using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; 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+0897715b5b9bc507393a232549dc5caa47f07e93")] [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().className = className; } private static void EnsureClassBadge(CardInfo cardInfo) { if (((Component)cardInfo).gameObject.GetComponent() == null) { ((Component)cardInfo).gameObject.AddComponent(); } } } internal static class ComponentExtensions { internal static T GetOrAddComponent(this GameObject gameObject) where T : Component { T component = gameObject.GetComponent(); if (component == null) { return gameObject.AddComponent(); } return component; } internal static T GetOrAddComponent(this Component component) where T : Component { return component.gameObject.GetOrAddComponent(); } } 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 buttons = new Dictionary(); 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 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(); 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 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 button in buttons) { TextMeshProUGUI componentInChildren = button.Value.GetComponentInChildren(); 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() ?? ((Component)text).gameObject.AddComponent(); 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(); 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(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? helldiverKeyboardModifier; private static ConfigEntry? helldiverKeyboardUp; private static ConfigEntry? helldiverKeyboardRight; private static ConfigEntry? helldiverKeyboardDown; private static ConfigEntry? helldiverKeyboardLeft; private static ConfigEntry? helldiverHudScale; private static ConfigEntry? helldiverControllerModifier; private static ConfigEntry? helldiverControllerUp; private static ConfigEntry? helldiverControllerRight; private static ConfigEntry? helldiverControllerDown; private static ConfigEntry? helldiverControllerLeft; private static bool initialized; internal static void Initialize(ConfigFile config) { if (!initialized) { helldiverKeyboardModifier = config.Bind("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("Helldiver HUD", "HUD Scale", 1f, "Scales the Helldiver HUD uniformly. 1.0 is the default size."); helldiverControllerModifier = config.Bind("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)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 list = new List(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 BindKeyboardDirection(ConfigFile config, HelldiverInputDirection direction, string defaultValue) { return config.Bind("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 BindControllerDirection(ConfigFile config, HelldiverInputDirection direction, InputControlType defaultValue) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) return config.Bind("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 list = new List(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(); if (helldiverSettingsMenuController == null) { helldiverSettingsMenuController = menu.AddComponent(); } 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(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? obj3 = helldiverControllerUp; return (InputControlType)((obj3 == null) ? 11 : ((int)obj3.Value)); } case HelldiverInputDirection.Right: { ConfigEntry? obj2 = helldiverControllerRight; return (InputControlType)((obj2 == null) ? 14 : ((int)obj2.Value)); } case HelldiverInputDirection.Down: { ConfigEntry? obj4 = helldiverControllerDown; return (InputControlType)((obj4 == null) ? 12 : ((int)obj4.Value)); } case HelldiverInputDirection.Left: { ConfigEntry? 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(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 Definitions = new Dictionary { [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, 0.8f, 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 }, 35f, 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 }, 40f, 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 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 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 => "^", HelldiverInputDirection.Right => ">", HelldiverInputDirection.Down => "v", HelldiverInputDirection.Left => "<", _ => "?", }; } return string.Join("-", array); } internal static bool IsPrefixOfAnyOwned(IReadOnlyList buffer, IEnumerable ownedTypes) { foreach (HelldiverStratagemType ownedType in ownedTypes) { IReadOnlyList 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 buffer, IEnumerable ownedTypes, out HelldiverStratagemType type) { foreach (HelldiverStratagemType ownedType in ownedTypes) { IReadOnlyList 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 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 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)OnGameStart); GameModeManager.AddHook("PointEnd", (Func)OnPointEnd); GameModeManager.AddHook("RoundEnd", (Func)OnRoundEnd); GameModeManager.AddHook("PickStart", (Func)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 list = PlayerManager.instance?.players; if (list != null) { foreach (Player item in list) { if (item != null) { HelldiverRuntime component = ((Component)item).gameObject.GetComponent(); 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)ResetTemporaryEffects); GameModeManager.AddHook("PointEnd", (Func)ResetTemporaryEffects); GameModeManager.AddHook("RoundEnd", (Func)ResetTemporaryEffects); GameModeManager.AddHook("PickStart", (Func)ResetTemporaryEffects); } private static IEnumerator ResetTemporaryEffects(IGameModeHandler handler) { HolySmiteEffect.ResetAllTransientState(); 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.2")] [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.2"; private static readonly HashSet HelldiverCardNames = new HashSet { "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)IsCardAllowedForMatchConditions); ToggleCardsCategoriesManager.instance.RegisterCategories("DOLY"); DolyTabInfoIntegration.Register(); HelldiverGameLifecycleHooks.Register(); HolySmiteGameLifecycleHooks.Register(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard((Action)delegate(CardInfo cardInfo) { GamblecoreRegistry.GamblecoreCardInfo = cardInfo; }); CustomCard.BuildCard((Action)delegate(CardInfo cardInfo) { GamblecoreRegistry.AwDangItCardInfo = cardInfo; RegisterHiddenCard(cardInfo); }); CustomCard.BuildCard((Action)delegate(CardInfo cardInfo) { GamblecoreRegistry.ICantStopWinningCardInfo = cardInfo; RegisterHiddenCard(cardInfo); }); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); CustomCard.BuildCard(); } 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 match) { List 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 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 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(); 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)((Component)this).GetComponentsInChildren(true)).FirstOrDefault((Func)((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(); ((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)edgePart.GetComponentsInChildren(true)).FirstOrDefault((Func)((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(); 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() != null && TryHandleSentryBlock(__instance, projectile, forward, hitPos, playParticle: false)) { return false; } HelldiverPrecisionProjectileController componentInParent = projectile.GetComponentInParent(); if (componentInParent != null) { Player componentInParent2 = ((Component)__instance).GetComponentInParent(); if (componentInParent2 != null) { componentInParent.HandleBlocked(componentInParent2, Vector2.op_Implicit(hitPos), Vector2.op_Implicit(forward)); } } DisintegrateOnBlockProjectileEffect componentInParent3 = projectile.GetComponentInParent(); if (componentInParent3 == null) { return true; } ProjectileHit component = projectile.GetComponent(); if (component != null) { component.RemoveOwnPlayerFromPlayersHit(); HealthHandler componentInParent4 = ((Component)__instance).GetComponentInParent(); 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() != null) { return; } HolySmiteProjectileTracker componentInParent = projectile.GetComponentInParent(); if (componentInParent != null) { Player componentInParent2 = ((Component)__instance).GetComponentInParent(); 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(); if (componentInParent == null) { return false; } Player componentInParent2 = ((Component)block).GetComponentInParent(); 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(); 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()?.playerActions; if (((Component)__instance).GetComponentInParent() != 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() ?? ((Component)__instance).GetComponentInParent(); if (healBlockDebuff != null) { return !healBlockDebuff.IsActive; } return true; } } [HarmonyPatch(typeof(HealthHandler), "Revive")] internal static class HolySmiteShrinkRevivePatches { private static void Postfix(HealthHandler __instance) { (((Component)__instance).GetComponent() ?? ((Component)__instance).GetComponentInParent())?.ResetShrink(); } } [HarmonyPatch(typeof(Player), "FullReset")] internal static class HolySmiteShrinkFullResetPatches { private static void Prefix(Player __instance) { if (__instance != null) { ((Component)__instance).GetComponent()?.ResetShrink(); } } } [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() ?? ((Component)__instance).GetComponentInParent(); if (val != null && !((Object)(object)val != (Object)(object)damagingPlayer)) { SelfDamageReductionEffect component = ((Component)val).GetComponent(); 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() ?? ((Component)__instance).GetComponentInParent(); Player val2 = ((Component)__instance).GetComponent() ?? ((Component)__instance).GetComponentInParent(); GiantSlayerEffect component = ((Component)damagingPlayer).gameObject.GetComponent(); 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(); CharacterData val = ((Component)__instance).GetComponent() ?? ((Component)__instance).GetComponentInParent(); 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() ?? ((Component)__instance).GetComponentInParent(); if (healBlockDebuff == null) { healBlockDebuff = ((Component)__state.TargetData).gameObject.GetOrAddComponent(); } 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() ?? ((Component)__instance).GetComponentInParent(); HolySmiteEffect holySmiteEffect = ((obj != null) ? ((Component)obj).gameObject.GetComponent() : 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() ?? ((Component)__instance).GetComponentInParent(); CharacterData val2 = ((Component)__instance).GetComponent() ?? ((Component)__instance).GetComponentInParent(); if (val != null && val2 != null) { HolySmiteMarkEffect component = ((Component)val).gameObject.GetComponent(); 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() ?? ((Component)__instance).GetComponentInParent(); 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() ?? ((Component)__instance).GetComponentInParent(); if (democracyProtectsEffect != null && democracyProtectsEffect.Stacks > 0 && democracyProtectsEffect.IsImmune) { lethal = false; return false; } if (!lethal) { return true; } CharacterData val = ((Component)__instance).GetComponent() ?? ((Component)__instance).GetComponentInParent(); 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(); } } } 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 player) => TryGetTackEffect(player, out TackShooterEffect _)), (Func)((Player player) => (!TryGetTackEffect(player, out TackShooterEffect effect11)) ? "-" : effect11.TackCount.ToString())); TabInfoManager.RegisterStat(obj, "Tack range", (Func)((Player player) => TryGetTackEffect(player, out TackShooterEffect _)), (Func)((Player player) => (!TryGetTackEffect(player, out TackShooterEffect effect9)) ? "-" : effect9.TackRange.ToString("F0"))); TabInfoManager.RegisterStat(obj, "Tack DMG", (Func)((Player player) => TryGetTackEffect(player, out TackShooterEffect _)), (Func)((Player player) => (!TryGetTackEffect(player, out TackShooterEffect effect7)) ? "-" : $"{Mathf.RoundToInt(0.5f * effect7.TackDamageMultiplier * 100f)}%")); TabInfoManager.RegisterStat(obj, "Hot Shots", (Func)((Player player) => TryGetTackEffect(player, out TackShooterEffect effect6) && effect6.UnblockableStacks > 0), (Func)((Player player) => (!TryGetTackEffect(player, out TackShooterEffect effect5) || effect5.UnblockableStacks <= 0) ? "-" : $"Yes x{effect5.UnblockableStacks}")); TabInfoManager.RegisterStat(obj, "Ring of Fire", (Func)((Player player) => TryGetTackEffect(player, out TackShooterEffect effect4) && effect4.RingOfFireStacks > 0), (Func)((Player player) => (!TryGetTackEffect(player, out TackShooterEffect effect3) || effect3.RingOfFireStacks <= 0) ? "-" : $"Yes x{effect3.RingOfFireStacks}")); TabInfoManager.RegisterStat(obj, "Ring HP DMG", (Func)((Player player) => TryGetTackEffect(player, out TackShooterEffect effect2) && effect2.ResolvedRingOfFirePercentDamage > 0f), (Func)((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 player) => TryGetHolySmiteEffect(player, out HolySmiteEffect _)), (Func)((Player player) => (!TryGetHolySmiteEffect(player, out HolySmiteEffect effect19)) ? "-" : $"{Mathf.RoundToInt(effect19.ResolvedDamageRatio * 100f)}% bullet + {effect19.ResolvedFlatDamage:F0}")); TabInfoManager.RegisterStat(obj, "Smite cooldown", (Func)((Player player) => TryGetHolySmiteEffect(player, out HolySmiteEffect _)), (Func)((Player player) => (!TryGetHolySmiteEffect(player, out HolySmiteEffect effect17)) ? "-" : $"{effect17.ResolvedCooldown:F2}s")); TabInfoManager.RegisterStat(obj, "Smite delay", (Func)((Player player) => TryGetHolySmiteEffect(player, out HolySmiteEffect _)), (Func)((Player player) => (!TryGetHolySmiteEffect(player, out HolySmiteEffect effect15)) ? "-" : $"{effect15.ResolvedDelay:F2}s")); TabInfoManager.RegisterStat(obj, "Smite size", (Func)((Player player) => TryGetHolySmiteEffect(player, out HolySmiteEffect _)), (Func)((Player player) => (!TryGetHolySmiteEffect(player, out HolySmiteEffect effect13)) ? "-" : $"{effect13.ResolvedSize:F2}")); TabInfoManager.RegisterStat(obj, "Bounce smite chance", (Func)((Player player) => TryGetHolySmiteEffect(player, out HolySmiteEffect effect12) && effect12.QuakingBounceChance > 0f), (Func)((Player player) => (!TryGetHolySmiteEffect(player, out HolySmiteEffect effect11) || !(effect11.QuakingBounceChance > 0f)) ? "-" : $"{Mathf.RoundToInt(effect11.QuakingBounceChance * 100f)}%")); TabInfoManager.RegisterStat(obj, "Additional smites", (Func)((Player player) => TryGetHolySmiteEffect(player, out HolySmiteEffect effect10) && effect10.ResolvedAdditionalSmites > 0), (Func)((Player player) => (!TryGetHolySmiteEffect(player, out HolySmiteEffect effect9)) ? "-" : effect9.ResolvedAdditionalSmites.ToString())); TabInfoManager.RegisterStat(obj, "Smite life steal", (Func)((Player player) => TryGetHolySmiteEffect(player, out HolySmiteEffect effect8) && effect8.LifeStealFraction > 0f), (Func)((Player player) => (!TryGetHolySmiteEffect(player, out HolySmiteEffect effect7)) ? "-" : $"{Mathf.RoundToInt(effect7.LifeStealFraction * 100f)}%")); TabInfoManager.RegisterStat(obj, "Stun", (Func)((Player player) => TryGetHolySmiteEffect(player, out HolySmiteEffect effect6) && effect6.StunDuration > 0f), (Func)((Player player) => (!TryGetHolySmiteEffect(player, out HolySmiteEffect effect5)) ? "-" : $"{effect5.StunDuration:F2}s")); TabInfoManager.RegisterStat(obj, "Burn", (Func)((Player player) => TryGetHolySmiteEffect(player, out HolySmiteEffect effect4) && effect4.BurnMaxHealthFractionPerSecond > 0f), (Func)((Player player) => (!TryGetHolySmiteEffect(player, out HolySmiteEffect effect3)) ? "-" : $"{Mathf.RoundToInt(effect3.BurnMaxHealthFractionPerSecond * 100f)}%/s for {effect3.BurnDurationSeconds:F1}s")); TabInfoManager.RegisterStat(obj, "Friendly heal", (Func)((Player player) => TryGetHolySmiteEffect(player, out HolySmiteEffect effect2) && effect2.ResolvedFriendlyHealRatio > 0f), (Func)((Player player) => (!TryGetHolySmiteEffect(player, out HolySmiteEffect effect)) ? "-" : $"{Mathf.RoundToInt(effect.ResolvedFriendlyHealRatio * 100f)}%")); } private static void RegisterHelldiverStats() { StatCategory val = TabInfoManager.RegisterCategory("DOLY Helldiver", 22); TabInfoManager.RegisterStat(val, "Stratagems", (Func)((Player player) => TryGetHelldiverEffect(player, out HelldiverEffect effect2) && effect2.OwnedStratagemCount > 0), (Func)delegate(Player player) { if (!TryGetHelldiverEffect(player, out HelldiverEffect effect) || effect.OwnedStratagemCount <= 0) { return "-"; } IEnumerable values = from HelldiverStratagemType type in Enum.GetValues(typeof(HelldiverStratagemType)) where type != 0 && effect.HasOwnedStratagem(type) select HelldiverClassRegistry.GetDefinition(type).DisplayName; return string.Join(", ", values); }); foreach (HelldiverStratagemType item in from HelldiverStratagemType stratagemType in Enum.GetValues(typeof(HelldiverStratagemType)) where stratagemType != 0 && HelldiverClassRegistry.GetDefinition(stratagemType).HasLimitedUses select stratagemType) { RegisterLimitedUseStat(val, item); } } private static void RegisterLimitedUseStat(StatCategory category, HelldiverStratagemType type) { HelldiverStratagemDefinition definition = HelldiverClassRegistry.GetDefinition(type); TabInfoManager.RegisterStat(category, definition.DisplayName, (Func)((Player player) => TryGetHelldiverEffect(player, out HelldiverEffect effect2) && effect2.HasOwnedStratagem(type)), (Func)((Player player) => (!TryGetHelldiverEffect(player, out HelldiverEffect effect)) ? "-" : $"{effect.GetRemainingUsesForDisplay(type)} left")); } private static bool TryGetTackEffect(Player player, out TackShooterEffect effect) { effect = ((Component)player).gameObject.GetComponent(); if (effect != null) { return !effect.IsEmpty; } return false; } private static bool TryGetHolySmiteEffect(Player player, out HolySmiteEffect effect) { effect = ((Component)player).gameObject.GetComponent(); if (effect != null) { return effect.EntryCount > 0; } return false; } private static bool TryGetHelldiverEffect(Player player, out HelldiverEffect effect) { effect = ((Component)player).gameObject.GetComponent(); if (effect != null) { return effect.OwnedStratagemCount > 0; } return false; } } } namespace RoundsDolyMods.Effects { internal sealed class AtomicChargeAudio : MonoBehaviour { private const string BlackHoleLoopClipName = "SFX_Block_Black_Hole_Zone_Loop_01"; private const string SupernovaChargeClipName = "SFX_Block_Supernova_Charge_01"; private const float BlackHoleVolume = 0.624f; private const float ChargeVolume = 0.8f; private const float ChargeLeadSeconds = 3f; private const float BlackHoleFadeInSeconds = 0.65f; private const float BlackHoleFadeOutSeconds = 0.45f; private const float VolumeBoostMultiplier = 1.15f; private static readonly Dictionary ClipCache = new Dictionary(StringComparer.Ordinal); private static readonly List LoadedClips = new List(); private static bool loadedClipPoolBuilt; private static bool resourceFallbackBuilt; private double startTime; private double fireTime; private double blackHoleFadeOutStartTime = double.PositiveInfinity; private AudioSource? blackHoleSource; private AudioSource? chargeSource; private bool chargeStarted; private bool releaseScheduled; internal static AtomicChargeAudio Spawn(double fireTime) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) AtomicChargeAudio atomicChargeAudio = new GameObject("DOLY_AtomicChargeAudio").AddComponent(); atomicChargeAudio.Initialize(fireTime); return atomicChargeAudio; } internal static void PlayExplosion() { AudioClip clip = GetClip("SFX_Block_Supernova_Explosion_01"); if (clip != null) { PlayAsUiLike2DAudio(clip, 0.95f); } } private void Initialize(double fireTime) { startTime = PhotonNetwork.Time; this.fireTime = fireTime; AudioClip clip = GetClip("SFX_Block_Black_Hole_Zone_Loop_01"); if (clip != null) { blackHoleSource = CreateSource("BlackHoleLoop", clip, 0.624f); blackHoleSource.loop = true; blackHoleSource.volume = 0f; blackHoleSource.Play(); } AudioClip clip2 = GetClip("SFX_Block_Supernova_Charge_01"); if (clip2 != null) { chargeSource = CreateSource("SupernovaCharge", clip2, 0.8f); if (PhotonNetwork.Time >= fireTime - 3.0) { StartCharge(); } } } private void Update() { UpdateBlackHoleLoop(); if (!chargeStarted && PhotonNetwork.Time >= fireTime - 3.0) { StartCharge(); } } internal void ScheduleReleaseFade(float expansionDuration, float lingerDuration) { releaseScheduled = true; blackHoleFadeOutStartTime = fireTime + (double)Mathf.Max(0f, expansionDuration) + (double)Mathf.Max(0f, lingerDuration); } internal void StopImmediate() { if (blackHoleSource != null) { blackHoleSource.Stop(); } if (chargeSource != null) { chargeSource.Stop(); } Object.Destroy((Object)(object)((Component)this).gameObject); } private void UpdateBlackHoleLoop() { if (blackHoleSource == null) { return; } double time = PhotonNetwork.Time; if (!releaseScheduled) { float num = Mathf.Clamp01((float)((time - startTime) / 0.6499999761581421)); blackHoleSource.volume = num * 0.624f * 1.15f; return; } if (time < blackHoleFadeOutStartTime) { blackHoleSource.volume = 0.7176f; return; } float num2 = Mathf.Clamp01((float)((time - blackHoleFadeOutStartTime) / 0.44999998807907104)); blackHoleSource.volume = (1f - num2) * 0.624f * 1.15f; if (num2 >= 1f) { StopImmediate(); } } private void StartCharge() { if (!chargeStarted && chargeSource != null) { chargeStarted = true; chargeSource.Play(); } } private AudioSource CreateSource(string objectName, AudioClip clip, float volume) { //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) GameObject val = new GameObject(objectName); val.transform.SetParent(((Component)this).transform, false); AudioSource obj = val.AddComponent(); obj.spatialBlend = 0f; obj.playOnAwake = false; obj.loop = false; obj.volume = volume * 1.15f; obj.priority = 64; obj.clip = clip; return obj; } private static AudioClip? GetClip(string clipName) { if (ClipCache.TryGetValue(clipName, out AudioClip value)) { return value; } EnsureLoadedClipPool(); AudioClip val = MatchClip(clipName); if (val == null) { EnsureResourceFallbackPool(); val = MatchClip(clipName); } ClipCache[clipName] = val; return val; } private static AudioClip? MatchClip(string clipName) { string clipName2 = clipName; return ((IEnumerable)LoadedClips).FirstOrDefault((Func)((AudioClip clip) => clip != null && (string.Equals(((Object)clip).name, clipName2, StringComparison.Ordinal) || string.Equals(((Object)clip).name, Path.GetFileNameWithoutExtension(clipName2), StringComparison.Ordinal)))); } private static void EnsureLoadedClipPool() { if (!loadedClipPoolBuilt) { loadedClipPoolBuilt = true; HashSet knownIds = new HashSet(); AddClips(Resources.FindObjectsOfTypeAll(), knownIds); } } private static void EnsureResourceFallbackPool() { if (!resourceFallbackBuilt) { resourceFallbackBuilt = true; HashSet knownIds = new HashSet(LoadedClips.Select((AudioClip clip) => ((Object)clip).GetInstanceID())); AddClips(Resources.LoadAll(string.Empty), knownIds); } } private static void AddClips(IEnumerable clips, HashSet knownIds) { foreach (AudioClip clip in clips) { if (clip != null) { int instanceID = ((Object)clip).GetInstanceID(); if (knownIds.Add(instanceID)) { LoadedClips.Add(clip); } } } } private static void PlayAsUiLike2DAudio(AudioClip clip, float volume) { //IL_0005: 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_0061: Expected O, but got Unknown GameObject val = new GameObject("DOLY_AtomicExplosionAudio"); AudioSource obj = val.AddComponent(); obj.spatialBlend = 0f; obj.playOnAwake = false; obj.loop = false; obj.volume = 1f; obj.clip = clip; obj.priority = 32; obj.PlayOneShot(clip, volume * 1.15f); Object.Destroy((Object)val, clip.length + 0.2f); } } internal sealed class AtomicBeamController : MonoBehaviour { private const float FallbackProjectileBaseDamage = 55f; private const float BeamStartWidth = 0.8f; private const float FalloffStartFraction = 0.5f; private const float MinimumDamageFraction = 0.01f; private const float FinalBeamWidthFractionOfScreen = 0.6f; private const float BeamLengthMultiplier = 3f; private const float FallbackVisibleHalfWidth = 16f; private const float FallbackBeamLength = 200f; private static readonly Dictionary PendingControllers = new Dictionary(); private int ownerPlayerId; private int ownerTeamId; private Vector2 beamCenter; private double fireTime; private float beamLength; private float finalHalfWidth; private float beamDamage; private float expansionDuration; private float lingerDuration; private bool activated; private AtomicBeamVisual? beamVisual; private readonly HashSet playersHit = new HashSet(); internal static void Preload(int ownerPlayerId, int ownerTeamId, Vector2 center, double fireTime, float beamLength, float finalHalfWidth, float beamDamage, float expansionDuration, float lingerDuration) { //IL_001b: 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) if (ownerPlayerId >= 0) { CancelPendingBeam(ownerPlayerId); AtomicBeamController atomicBeamController = new GameObject($"DOLY_AtomicBeam_{ownerPlayerId}").AddComponent(); atomicBeamController.Initialize(ownerPlayerId, ownerTeamId, center, fireTime, beamLength, finalHalfWidth, beamDamage, expansionDuration, lingerDuration); PendingControllers[ownerPlayerId] = atomicBeamController; } } internal static void ActivatePendingBeam(int ownerPlayerId) { if (ownerPlayerId >= 0 && PendingControllers.TryGetValue(ownerPlayerId, out AtomicBeamController value)) { PendingControllers.Remove(ownerPlayerId); value.Activate(); } } internal static void CancelPendingBeam(int ownerPlayerId) { if (ownerPlayerId >= 0 && PendingControllers.TryGetValue(ownerPlayerId, out AtomicBeamController value)) { PendingControllers.Remove(ownerPlayerId); Object.Destroy((Object)(object)((Component)value).gameObject); } } internal static float ComputeBeamDamage(CharacterData ownerData, float damageMultiplier, float flatDamageBonus) { Gun val = ownerData.weaponHandler?.gun; if (val == null) { return Mathf.Max(0f, flatDamageBonus) * Mathf.Max(0f, damageMultiplier); } return (ResolveProjectileBaseDamage(val) * Mathf.Max(0.1f, val.damage) * Mathf.Max(0.1f, val.bulletDamageMultiplier) + Mathf.Max(0f, flatDamageBonus)) * Mathf.Max(0f, damageMultiplier); } internal static float ComputeFinalHalfWidth() { float visibleHalfWidth = GetVisibleHalfWidth(); return Mathf.Max(0.4f, visibleHalfWidth * 0.6f); } internal static float ComputeBeamLength() { Camera val = MainCam.instance?.cam; if (val == null || !val.orthographic) { return 200f; } float num = val.orthographicSize * 2f; float num2 = num * val.aspect; return Mathf.Sqrt(num * num + num2 * num2) * 3f; } internal static float EvaluateExpansionProgress(float elapsed, float expansionDuration) { if (expansionDuration <= 0.0001f) { return 1f; } float num = Mathf.Clamp01(elapsed / expansionDuration); return 1f - Mathf.Pow(1f - num, 2.2f); } private static float GetVisibleHalfWidth() { Camera val = MainCam.instance?.cam; if (val == null || !val.orthographic) { return 16f; } return val.orthographicSize * val.aspect; } private static float ResolveProjectileBaseDamage(Gun gun) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) ProjectilesToSpawn[] projectiles = gun.projectiles; for (int i = 0; i < projectiles.Length; i++) { GameObject val = projectiles[i]?.objectToSpawn; ProjectileHit val2 = ((val != null) ? val.GetComponent() : null); if (val2 != null && val != null) { float num = Mathf.Max(0.01f, val.transform.localScale.x); return Mathf.Max(0.1f, val2.damage) * num; } } return 55f; } private void Initialize(int ownerPlayerId, int ownerTeamId, Vector2 center, double fireTime, float beamLength, float finalHalfWidth, float beamDamage, float expansionDuration, float lingerDuration) { //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) this.ownerPlayerId = ownerPlayerId; this.ownerTeamId = ownerTeamId; beamCenter = center; this.fireTime = fireTime; this.beamLength = Mathf.Max(beamLength, 200f); this.finalHalfWidth = Mathf.Max(finalHalfWidth, 0.4f); this.beamDamage = Mathf.Max(0f, beamDamage); this.expansionDuration = Mathf.Max(0f, expansionDuration); this.lingerDuration = Mathf.Max(0f, lingerDuration); } private void Activate() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (!activated) { activated = true; beamVisual = AtomicBeamVisual.Spawn(beamCenter, beamLength, 0.8f, finalHalfWidth * 2f, fireTime, expansionDuration, lingerDuration); } } private void Update() { if (!IsOwnerAlive()) { Object.Destroy((Object)(object)((Component)this).gameObject); } else if (activated) { float num = Mathf.Max(0f, (float)(PhotonNetwork.Time - fireTime)); float currentHalfWidth = GetCurrentHalfWidth(num); ApplyBeamDamage(currentHalfWidth); if (num >= expansionDuration + lingerDuration + 0.12f) { Object.Destroy((Object)(object)((Component)this).gameObject); } } } private void OnDestroy() { if (PendingControllers.TryGetValue(ownerPlayerId, out AtomicBeamController value) && (Object)(object)value == (Object)(object)this) { PendingControllers.Remove(ownerPlayerId); } if (beamVisual != null) { Object.Destroy((Object)(object)((Component)beamVisual).gameObject); beamVisual = null; } } private float GetCurrentHalfWidth(float elapsed) { float num = EvaluateExpansionProgress(elapsed, expansionDuration); return Mathf.Lerp(0.4f, finalHalfWidth, num); } private bool IsOwnerAlive() { Player val = ResolvePlayerById(ownerPlayerId); if (val?.data != null) { return !val.data.dead; } return false; } private void ApplyBeamDamage(float currentHalfWidth) { //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0123: 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_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) if (beamDamage <= 0f) { return; } List list = PlayerManager.instance?.players; if (list == null) { return; } Player val = ResolvePlayerById(ownerPlayerId); object obj; if (val == null) { obj = null; } else { CharacterData data = val.data; if (data == null) { obj = null; } else { WeaponHandler weaponHandler = data.weaponHandler; if (weaponHandler == null) { obj = null; } else { Gun gun = weaponHandler.gun; obj = ((gun != null) ? ((Component)gun).gameObject : null); } } } GameObject val2 = (GameObject)obj; float halfLength = beamLength * 0.5f; foreach (Player item in list) { if (item == null || item.data == null || item.data.dead || item.playerID == ownerPlayerId || (ownerTeamId >= 0 && item.teamID == ownerTeamId) || playersHit.Contains(item.playerID)) { continue; } Bounds bounds = (Bounds)((item.data.mainCol != null) ? item.data.mainCol.bounds : new Bounds(((Component)item).transform.position, Vector3.one)); if (!IntersectsBeam(bounds, beamCenter, halfLength, currentHalfWidth)) { continue; } float num = EvaluateDamageFraction(bounds, beamCenter.x, finalHalfWidth); if (!(num <= 0f)) { playersHit.Add(item.playerID); float num2 = beamDamage * num; float num3 = Mathf.Sign(((Bounds)(ref bounds)).center.x - beamCenter.x); if (Mathf.Approximately(num3, 0f)) { num3 = ((Random.value < 0.5f) ? (-1f) : 1f); } Vector2 val3 = new Vector2(num3, 0.35f); Vector2 val4 = ((Vector2)(ref val3)).normalized * num2; ((Damagable)item.data.healthHandler).TakeDamage(val4, beamCenter, val2, val, true, true); } } } private static float EvaluateDamageFraction(Bounds bounds, float centerX, float currentHalfWidth) { //IL_0007: 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) float num = Mathf.Max(0f, Mathf.Abs(((Bounds)(ref bounds)).center.x - centerX) - ((Bounds)(ref bounds)).extents.x); if (num > currentHalfWidth) { return 0f; } float num2 = currentHalfWidth * 0.5f; if (num <= num2) { return 1f; } float num3 = Mathf.Max(0.0001f, currentHalfWidth - num2); float num4 = Mathf.Clamp01((num - num2) / num3); return Mathf.Lerp(1f, 0.01f, num4); } private static bool IntersectsBeam(Bounds bounds, Vector2 center, float halfLength, float currentHalfWidth) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_000d: 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_0013: 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_002e: 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) Vector2 val = Vector2.op_Implicit(((Bounds)(ref bounds)).center) - center; if (Mathf.Abs(val.x) <= currentHalfWidth + ((Bounds)(ref bounds)).extents.x) { return Mathf.Abs(val.y) <= halfLength + ((Bounds)(ref bounds)).extents.y; } return false; } private static Player? ResolvePlayerById(int playerId) { return HolySmiteEffect.ResolvePlayerById(playerId); } } internal sealed class AtomicBeamVisual : MonoBehaviour { private const int SegmentCount = 36; internal const float FadeDurationSeconds = 0.12f; private const float GlowWidthMultiplier = 1.08f; private const float GlowPulseWidth = 0.03f; private const float CoreWidthMultiplier = 0.36f; private Vector2 center; private double fireTime; private float beamLength; private float startWidth; private float finalWidth; private float expansionDuration; private float lingerDuration; private LineRenderer? glowRenderer; private LineRenderer? mainRenderer; private LineRenderer? coreRenderer; private LineRenderer? shockRingRenderer; private LineRenderer? haloRingRenderer; private Material? glowMaterial; private Material? mainMaterial; private Material? coreMaterial; private Material? shockRingMaterial; private Material? haloRingMaterial; internal static AtomicBeamVisual Spawn(Vector2 center, float beamLength, float startWidth, float finalWidth, double fireTime, float expansionDuration, float lingerDuration) { //IL_0005: 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) AtomicBeamVisual atomicBeamVisual = new GameObject("DOLY_AtomicBeamVisual").AddComponent(); atomicBeamVisual.Initialize(center, beamLength, startWidth, finalWidth, fireTime, expansionDuration, lingerDuration); return atomicBeamVisual; } private void Initialize(Vector2 center, float beamLength, float startWidth, float finalWidth, double fireTime, float expansionDuration, float lingerDuration) { //IL_0001: 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) this.center = center; this.fireTime = fireTime; this.beamLength = Mathf.Max(beamLength, 50f); this.startWidth = Mathf.Max(startWidth, 0.2f); this.finalWidth = Mathf.Max(finalWidth, this.startWidth); this.expansionDuration = Mathf.Max(0f, expansionDuration); this.lingerDuration = Mathf.Max(0f, lingerDuration); glowRenderer = CreateBeamRenderer(ref glowMaterial, "GlowBeam", 3600); mainRenderer = CreateBeamRenderer(ref mainMaterial, "MainBeam", 3601); coreRenderer = CreateBeamRenderer(ref coreMaterial, "CoreBeam", 3602); shockRingRenderer = CreateRingRenderer(ref shockRingMaterial, "ShockRing", 3603); haloRingRenderer = CreateRingRenderer(ref haloRingMaterial, "HaloRing", 3604); } private void Update() { //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Max(0f, (float)(PhotonNetwork.Time - fireTime)); float num2 = ((expansionDuration <= 0.0001f) ? 1f : Mathf.Clamp01(num / expansionDuration)); float num3 = AtomicBeamController.EvaluateExpansionProgress(num, expansionDuration); float num4 = ((num <= expansionDuration + lingerDuration) ? 0f : Mathf.Clamp01((num - expansionDuration - lingerDuration) / 0.12f)); float num5 = Mathf.Sin(Time.unscaledTime * 10f + num2 * 12f) * 0.5f + 0.5f; float num6 = 1f - num4; float num7 = ((num4 <= 0f) ? 1f : Mathf.Clamp01(0.28f + 0.42f * Mathf.Abs(Mathf.Sin(Time.unscaledTime * 38f + num2 * 17f)) + 0.26f * Mathf.Abs(Mathf.Sin(Time.unscaledTime * 71f + num2 * 29f)) - num4 * 0.52f)); float num8 = num6 * num7; float num9 = ((num4 <= 0f) ? 1f : Mathf.Lerp(1f, 0.76f + 0.16f * num7, num4)); float num10 = Mathf.Lerp(startWidth, finalWidth, num3) * num9; UpdateBeam(glowRenderer, beamLength, num10 * (1.08f + 0.03f * num5), new Color(0.34f, 0.68f, 0.96f, 0.15f * num8)); UpdateBeam(mainRenderer, beamLength, num10, new Color(0.7f, 0.9f, 1f, 0.82f * num8)); UpdateBeam(coreRenderer, beamLength, Mathf.Max(0.16f, num10 * 0.36f), new Color(0.97f, 0.99f, 1f, 0.96f * num8)); UpdateShockRings(num10, num2, num8, num5); if (num4 >= 1f) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void OnDestroy() { DestroyMaterial(glowMaterial); DestroyMaterial(mainMaterial); DestroyMaterial(coreMaterial); DestroyMaterial(shockRingMaterial); DestroyMaterial(haloRingMaterial); } private LineRenderer CreateBeamRenderer(ref Material? material, string objectName, int sortingOrder) { //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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown GameObject val = new GameObject(objectName); val.transform.SetParent(((Component)this).transform, false); LineRenderer obj = val.AddComponent(); material = new Material(Shader.Find("Sprites/Default")); ((Renderer)obj).material = material; obj.positionCount = 2; obj.useWorldSpace = true; obj.numCapVertices = 12; obj.numCornerVertices = 12; ((Renderer)obj).sortingOrder = sortingOrder; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; obj.textureMode = (LineTextureMode)0; obj.alignment = (LineAlignment)0; return obj; } private LineRenderer CreateRingRenderer(ref Material? material, string objectName, int sortingOrder) { //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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown GameObject val = new GameObject(objectName); val.transform.SetParent(((Component)this).transform, false); LineRenderer obj = val.AddComponent(); material = new Material(Shader.Find("Sprites/Default")); ((Renderer)obj).material = material; obj.positionCount = 37; obj.loop = true; obj.useWorldSpace = true; obj.numCapVertices = 8; obj.numCornerVertices = 8; ((Renderer)obj).sortingOrder = sortingOrder; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; obj.textureMode = (LineTextureMode)0; obj.alignment = (LineAlignment)0; return obj; } private void UpdateShockRings(float currentWidth, float expansionProgress, float opacity, float pulse) { //IL_0036: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) float radius = Mathf.Lerp(currentWidth * 0.2f, currentWidth * 0.72f, expansionProgress); float radius2 = Mathf.Lerp(currentWidth * 0.08f, currentWidth * 0.46f, Mathf.Sqrt(expansionProgress)); UpdateRing(shockRingRenderer, center, radius, expansionProgress * 2.5f, (0.14f + 0.12f * pulse) * opacity, new Color(0.58f, 0.85f, 1f, 0.42f * opacity)); UpdateRing(haloRingRenderer, center, radius2, 0.6f + expansionProgress * 4.5f, (0.06f + 0.05f * pulse) * opacity, new Color(0.95f, 0.99f, 1f, 0.24f * opacity)); } private void UpdateBeam(LineRenderer? renderer, float length, float width, Color color) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0036: 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_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_005f: 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) if (renderer != null) { float num = length * 0.5f; renderer.SetPosition(0, Vector2.op_Implicit(center + Vector2.down * num)); renderer.SetPosition(1, Vector2.op_Implicit(center + Vector2.up * num)); renderer.startWidth = width; renderer.endWidth = width; renderer.startColor = color; renderer.endColor = color; } } private static void UpdateRing(LineRenderer? renderer, Vector2 center, float radius, float phase, float width, Color color) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_00a7: Unknown result type (might be due to invalid IL or missing references) if (renderer != null) { float num = Mathf.Max(0.04f, radius); for (int i = 0; i <= 36; i++) { float num2 = (float)i / 36f; float num3 = num2 * MathF.PI * 2f + phase; float num4 = 1f + 0.05f * Mathf.Sin(num2 * MathF.PI * 8f + Time.unscaledTime * 7f); renderer.SetPosition(i, Vector2.op_Implicit(center + new Vector2(Mathf.Cos(num3), Mathf.Sin(num3)) * (num * num4))); } renderer.startWidth = width; renderer.endWidth = width; renderer.startColor = color; renderer.endColor = color; } } private static void DestroyMaterial(Material? material) { if (material != null) { Object.Destroy((Object)(object)material); } } } internal sealed class AtomicChargeVisual : MonoBehaviour { private const int SegmentCount = 64; private const float TelegraphStartProgress = 0.82f; private const float BaseMajorRadius = 1f; private const float BaseMinorRadius = 0.24f; private const float RadiusGrowth = 0.2f; private const float BreathAmount = 0.14f; private CharacterData? ownerData; private double startTime; private double fireTime; private float sizeScale; private LineRenderer? primaryRing; private LineRenderer? secondaryRing; private LineRenderer? tertiaryRing; private Material? primaryMaterial; private Material? secondaryMaterial; private Material? tertiaryMaterial; internal static AtomicChargeVisual Spawn(CharacterData? ownerData, double startTime, double fireTime, float beamWidth) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) AtomicChargeVisual atomicChargeVisual = new GameObject("DOLY_AtomicChargeVisual").AddComponent(); atomicChargeVisual.Initialize(ownerData, startTime, fireTime, beamWidth); return atomicChargeVisual; } private void Initialize(CharacterData? ownerData, double startTime, double fireTime, float beamWidth) { this.ownerData = ownerData; this.startTime = startTime; this.fireTime = fireTime; sizeScale = Mathf.Lerp(1f, 1.36f, Mathf.Clamp01(beamWidth / 22f)); primaryRing = CreateRenderer(ref primaryMaterial, "PrimaryRing", 3400); secondaryRing = CreateRenderer(ref secondaryMaterial, "SecondaryRing", 3401); tertiaryRing = CreateRenderer(ref tertiaryMaterial, "TertiaryRing", 3402); } private void Update() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03bf: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Unknown result type (might be due to invalid IL or missing references) if (ownerData == null || !((Component)ownerData).gameObject.activeInHierarchy || ownerData.dead) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Vector2 center = ResolveBodyCenter(); float num = Mathf.Max(0.0001f, (float)(fireTime - startTime)); float num2 = Mathf.Clamp01((float)((PhotonNetwork.Time - startTime) / (double)num)); float num3 = Mathf.SmoothStep(0f, 1f, num2); float num4 = ((num2 < 0.82f) ? 0f : Mathf.Clamp01((num2 - 0.82f) / 0.18f)); float num5 = Mathf.Pow(num3, 1.8f); float num6 = Mathf.Sin(Time.unscaledTime * Mathf.Lerp(1.6f, 4.9f, num5) + num2 * 10f); float num7 = Mathf.Sin(Time.unscaledTime * Mathf.Lerp(2.2f, 8.8f, num5) + num2 * 18f); float num8 = Mathf.Sin(Time.unscaledTime * Mathf.Lerp(0f, 22f, num4) + num2 * 34f); float num9 = Time.unscaledTime * Mathf.Lerp(0.18f, 4.6f, num5) + num5 * 10f; float num10 = num4 * Time.unscaledTime * 8f; float num11 = num4 * num4; float num12 = 1f * sizeScale * (1f + 0.2f * num3 + 0.14f * num6); float num13 = Mathf.Lerp(1f, 0.74f + 0.08f * num8, num4); float num14 = 0.055f + 0.035f * num3 + 0.045f * num4; float num15 = Mathf.SmoothStep(0f, 1f, num4); float num16 = 0.12f * num4; UpdateGyroRing(primaryRing, center, num12 * num13, ComputeMinorRadius(num12, 0.24f, 0.28f, num9, 0.2f, num4), Mathf.Lerp(num9 * 0.9f, num9 * 2.4f, num11) + num10, num14, Color.Lerp(new Color(0.28f, 0.74f, 1f, 0.22f), new Color(0.92f, 0.97f, 1f, 0.48f + num16), num15), num7 * 0.8f, 0.065f + 0.025f * num4); UpdateGyroRing(secondaryRing, center, num12 * (0.9f + 0.05f * num7) * num13, ComputeMinorRadius(num12, 0.24f, 0.18f, num9, 1.9f, num4), Mathf.Lerp((0f - num9) * 1.25f + 1.2f, num9 * 2.4f + 0.5f, num11) - num10, num14 * 0.92f, Color.Lerp(new Color(0.6f, 0.42f, 1f, 0.18f), new Color(0.8f, 0.56f, 1f, 0.42f + num16), num15), num7 * -1.1f + 1.7f, 0.055f + 0.025f * num4); UpdateGyroRing(tertiaryRing, center, num12 * (0.82f + 0.07f * (0f - num6)) * num13, ComputeMinorRadius(num12, 0.24f, 0.24f, num9, 3.7f, num4), Mathf.Lerp(num9 * 1.45f + 2.4f, num9 * 2.4f + 1.1f, num11) + num10 * 0.7f, num14 * 0.84f, Color.Lerp(new Color(0.9f, 0.95f, 1f, 0.16f), new Color(0.98f, 0.99f, 1f, 0.5f + num16), num15), num7 + 3.1f, 0.045f + 0.03f * num4); } private void OnDestroy() { DestroyMaterial(primaryMaterial); DestroyMaterial(secondaryMaterial); DestroyMaterial(tertiaryMaterial); } private Vector2 ResolveBodyCenter() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (ownerData?.mainCol != null) { Bounds bounds = ownerData.mainCol.bounds; return Vector2.op_Implicit(((Bounds)(ref bounds)).center + new Vector3(0f, ((Bounds)(ref bounds)).extents.y * 0.08f, 0f)); } return Vector2.op_Implicit(((Component)this).transform.position); } private LineRenderer CreateRenderer(ref Material? material, string objectName, int sortingOrder) { //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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown GameObject val = new GameObject(objectName); val.transform.SetParent(((Component)this).transform, false); LineRenderer obj = val.AddComponent(); material = new Material(Shader.Find("Sprites/Default")); ((Renderer)obj).material = material; obj.useWorldSpace = true; obj.positionCount = 65; obj.loop = true; obj.numCapVertices = 10; obj.numCornerVertices = 10; ((Renderer)obj).sortingOrder = sortingOrder; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; obj.textureMode = (LineTextureMode)0; obj.alignment = (LineAlignment)0; return obj; } private static float ComputeMinorRadius(float baseMajorRadius, float baseMinorRadius, float extraStretch, float sharedSpin, float phaseOffset, float telegraphProgress) { float num = Mathf.Abs(Mathf.Sin(sharedSpin * 0.9f + phaseOffset)); return Mathf.Lerp(baseMajorRadius * (baseMinorRadius + extraStretch + 0.12f * num), baseMajorRadius * 0.72f, telegraphProgress * 0.55f); } private static void UpdateGyroRing(LineRenderer? renderer, Vector2 center, float majorRadius, float minorRadius, float rotation, float width, Color color, float flowPhase, float distortionAmount) { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) if (renderer != null) { float num = Mathf.Max(0.08f, majorRadius); float num2 = Mathf.Max(0.05f, minorRadius); float num3 = Mathf.Cos(rotation); float num4 = Mathf.Sin(rotation); Vector2 val = default(Vector2); Vector2 val2 = default(Vector2); for (int i = 0; i <= 64; i++) { float num5 = (float)i / 64f; float num6 = num5 * MathF.PI * 2f; float num7 = 1f + distortionAmount * Mathf.Sin(num5 * MathF.PI * 6f + flowPhase); ((Vector2)(ref val))..ctor(Mathf.Cos(num6) * num * num7, Mathf.Sin(num6) * num2 * (1f + distortionAmount * 0.65f * Mathf.Cos(num5 * MathF.PI * 4f + flowPhase))); ((Vector2)(ref val2))..ctor(val.x * num3 - val.y * num4, val.x * num4 + val.y * num3); renderer.SetPosition(i, Vector2.op_Implicit(center + val2)); } renderer.startWidth = width; renderer.endWidth = width; renderer.startColor = color; renderer.endColor = color; } } private static void DestroyMaterial(Material? material) { if (material != null) { Object.Destroy((Object)(object)material); } } } internal sealed class AtomicCooldownRing : MonoBehaviour { private const int SegmentCount = 72; private const float VisibilitySpeed = 8f; private const float RingPadding = 0.34f; private const float CooldownRingWidth = 0.1f; private const float ReadyRingWidth = 0.12f; private const float ReadyPulseWidth = 0.018f; private const float CooldownRingAlpha = 0.16f; private const float ReadyRingAlpha = 0.28f; private static readonly Color CooldownColor = new Color(0.22f, 0.09f, 0.38f, 1f); private static readonly Color ReadyColor = new Color(0.44f, 0.2f, 0.68f, 1f); private readonly Vector3[] ringPositions = (Vector3[])(object)new Vector3[73]; private CharacterData? ownerData; private LineRenderer? ringRenderer; private Material? ringMaterial; private bool targetReady; private float targetProgress; private float readyVisibility; private float displayedProgress; internal void Bind(CharacterData data) { ownerData = data; EnsureRenderer(); } internal void SetState(bool isReady, float cooldownProgress) { targetReady = isReady; targetProgress = Mathf.Clamp01(cooldownProgress); } private void LateUpdate() { //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) if (ownerData == null) { ownerData = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); } if (ownerData == null) { return; } EnsureRenderer(); if (ringRenderer == null) { return; } readyVisibility = Mathf.MoveTowards(readyVisibility, targetReady ? 1f : 0f, TimeHandler.deltaTime * 8f); displayedProgress = Mathf.MoveTowards(displayedProgress, targetProgress, TimeHandler.deltaTime * 8f); if (displayedProgress <= 0.001f && !targetReady) { ((Renderer)ringRenderer).enabled = false; return; } ((Renderer)ringRenderer).enabled = true; Bounds val = (Bounds)((ownerData.mainCol != null) ? ownerData.mainCol.bounds : new Bounds(((Component)this).transform.position, Vector3.one)); Vector3 center = ((Bounds)(ref val)).center; float num = ((Bounds)(ref val)).extents.x + 0.34f; float num2 = ((Bounds)(ref val)).extents.y + 0.34f; float num3 = 0.5f + 0.5f * Mathf.Sin(Time.time * 6.2f); int num4 = (targetReady ? 72 : Mathf.Clamp(Mathf.CeilToInt(displayedProgress * 72f), 0, 72)); if (num4 <= 0) { ((Renderer)ringRenderer).enabled = false; return; } for (int i = 0; i <= num4; i++) { float num5 = ((num4 == 0) ? 0f : ((float)i / (float)num4)); float num6 = (targetReady ? num5 : (displayedProgress * num5)); float num7 = MathF.PI / 2f - num6 * MathF.PI * 2f; ringPositions[i] = center + new Vector3(Mathf.Cos(num7) * num, Mathf.Sin(num7) * num2, 0f); } float a = (targetReady ? (0.28f + readyVisibility * num3 * 0.06f) : Mathf.Lerp(0.04f, 0.16f, displayedProgress)); float num8 = (targetReady ? (0.12f + readyVisibility * 0.018f * num3) : 0.1f); Color val2 = (targetReady ? ReadyColor : CooldownColor); val2.a = a; ringRenderer.positionCount = num4 + 1; ringRenderer.SetPositions(ringPositions); ringRenderer.startWidth = num8; ringRenderer.endWidth = num8; ringRenderer.startColor = val2; ringRenderer.endColor = val2; } private void OnDestroy() { if (ringMaterial != null) { Object.Destroy((Object)(object)ringMaterial); } } private void EnsureRenderer() { if (ringRenderer == null) { ringRenderer = CreateRenderer("AtomicCooldownRing", ref ringMaterial, 1250); } } private LineRenderer CreateRenderer(string childName, ref Material? material, int sortingOrder) { //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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_002e: 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_003e: 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_005e: Expected O, but got Unknown GameObject val = new GameObject(childName); val.transform.SetParent(((Component)this).transform, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; LineRenderer obj = val.AddComponent(); material = new Material(Shader.Find("Sprites/Default")); ((Renderer)obj).material = material; obj.useWorldSpace = true; obj.loop = false; obj.positionCount = 0; obj.numCapVertices = 8; obj.numCornerVertices = 8; obj.textureMode = (LineTextureMode)0; obj.alignment = (LineAlignment)0; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; ((Renderer)obj).sortingOrder = sortingOrder; ((Renderer)obj).enabled = false; return obj; } } internal sealed class AtomicEffect : MonoBehaviour { private const float ChargeDurationSeconds = 3f; private const float CooldownDurationSeconds = 40f; private const float ExpansionDurationSeconds = 3f; private const float LingerDurationSeconds = 0.65f; private const float PostCastCooldownResetSeconds = 0f; private CharacterData? ownerData; private Player? ownerPlayer; private Block? hookedBlock; private Rigidbody2D? body; private RigidbodyConstraints2D storedConstraints; private bool constraintsStored; private bool isChanneling; private double cooldownReadyTime; private double fireTime; private Vector2 anchorPosition; private float tempHealthBonus; private float originalMaxHealth; private float originalHealth; private bool bonusHealthApplied; private AtomicChargeVisual? chargeVisual; private AtomicCooldownRing? cooldownRing; private AtomicChargeAudio? chargeAudio; internal int EntryCount { get; set; } internal float DamageMultiplier { get; set; } = 1f; internal float FlatDamageBonus { get; set; } internal float ChannelHealthMultiplier { get; set; } = 1f; internal float ChannelRegenPerSecond { get; set; } internal float CooldownRemaining => Mathf.Max(0f, (float)(cooldownReadyTime - PhotonNetwork.Time)); internal float CooldownProgress => Mathf.Clamp01(1f - CooldownRemaining / 40f); internal bool IsAtomicReady { get { if (EntryCount > 0) { return CooldownRemaining <= 0.0001f; } return false; } } internal bool IsNeutral { get { if (EntryCount <= 0 && Mathf.Approximately(DamageMultiplier, 1f) && FlatDamageBonus <= 0f && Mathf.Approximately(ChannelHealthMultiplier, 1f)) { return ChannelRegenPerSecond <= 0f; } return false; } } private void OnEnable() { ResolveOwner(); TryHookBlock(); } private void Start() { ResolveOwner(); TryHookBlock(); UpdateCooldownRing(); } private void Update() { ResolveOwner(); TryHookBlock(); UpdateCooldownRing(); if (!isChanneling) { return; } if (ownerData == null || ownerPlayer == null) { CancelChannel(); return; } if (ownerData.dead) { CancelChannel(); return; } MaintainFrozenState(); RegenerateDuringChannel(); if (PhotonNetwork.Time >= fireTime) { FireAtomic(); } } private void OnDisable() { UnhookBlock(); if (isChanneling) { CancelChannel(); } } private void OnDestroy() { UnhookBlock(); CleanupChargeVisual(); if (cooldownRing != null) { Object.Destroy((Object)(object)cooldownRing); } StopChargeAudio(); RemoveBonusHealth(); ReleaseFrozenState(); } [PunRPC] private void RPCA_StartAtomicCharge(double syncedFireTime, double syncedCooldownReadyTime, float centerX, float centerY, float beamLength, float finalHalfWidth, float beamDamage) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (EntryCount > 0) { BeginChannel(syncedFireTime, syncedCooldownReadyTime, new Vector2(centerX, centerY), beamLength, finalHalfWidth, beamDamage); } } private void HandleBlock(BlockTriggerType triggerType) { //IL_0000: 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_0069: 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_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) if ((int)triggerType == 0 && !isChanneling && EntryCount > 0) { ResolveOwner(); if (ownerData != null && ownerPlayer != null && ownerData.view.IsMine && !ownerData.dead && !(PhotonNetwork.Time < cooldownReadyTime)) { Vector2 val = Vector2.op_Implicit(((Component)ownerPlayer).transform.position); float num = AtomicBeamController.ComputeBeamLength(); float num2 = AtomicBeamController.ComputeFinalHalfWidth(); float num3 = AtomicBeamController.ComputeBeamDamage(ownerData, DamageMultiplier, FlatDamageBonus); double num4 = PhotonNetwork.Time + 3.0; double num5 = PhotonNetwork.Time + 40.0; ownerData.view.RPC("RPCA_StartAtomicCharge", (RpcTarget)0, new object[7] { num4, num5, val.x, val.y, num, num2, num3 }); } } } private void BeginChannel(double syncedFireTime, double syncedCooldownReadyTime, Vector2 center, float beamLength, float finalHalfWidth, float beamDamage) { //IL_0020: 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_0089: Unknown result type (might be due to invalid IL or missing references) CancelChannel(); cooldownReadyTime = Math.Max(cooldownReadyTime, syncedCooldownReadyTime); fireTime = syncedFireTime; anchorPosition = center; isChanneling = true; ApplyBonusHealth(); EnterFrozenState(); chargeVisual = AtomicChargeVisual.Spawn(ownerData, syncedFireTime - 3.0, syncedFireTime, finalHalfWidth * 2f); StartChargeAudio(syncedFireTime); AtomicBeamController.Preload(ownerPlayer?.playerID ?? (-1), ownerPlayer?.teamID ?? (-1), center, syncedFireTime, beamLength, finalHalfWidth, beamDamage, 3f, 0.65f); } private void FireAtomic() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) if (isChanneling) { isChanneling = false; CleanupChargeVisual(); chargeAudio?.ScheduleReleaseFade(3f, 0.65f); ReleaseFrozenState(); RemoveBonusHealth(); ResolveOwner(); if (ownerData?.block != null) { ownerData.block.counter = 0f; } GamefeelManager.GameFeel(Vector2.up * 6f); AtomicChargeAudio.PlayExplosion(); AtomicBeamController.ActivatePendingBeam(ownerPlayer?.playerID ?? (-1)); } } private void CancelChannel() { if (isChanneling) { isChanneling = false; CleanupChargeVisual(); StopChargeAudio(); ReleaseFrozenState(); RemoveBonusHealth(); ResolveOwner(); if (ownerData?.block != null) { ownerData.block.counter = 0f; } AtomicBeamController.CancelPendingBeam(ownerPlayer?.playerID ?? (-1)); } } private void ResolveOwner() { if (ownerData == null) { ownerData = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); } if (ownerPlayer == null) { ownerPlayer = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); } if (body == null) { CharacterData? obj = ownerData; object obj2; if (obj == null) { obj2 = null; } else { PlayerVelocity playerVel = obj.playerVel; obj2 = ((playerVel != null) ? ((Component)playerVel).GetComponent() : null); } if (obj2 == null) { obj2 = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); } body = (Rigidbody2D?)obj2; } } private void TryHookBlock() { Block val = ownerData?.block; if (val != null && !((Object)(object)val == (Object)(object)hookedBlock)) { UnhookBlock(); hookedBlock = val; Block? obj = hookedBlock; obj.BlockAction = (Action)Delegate.Combine(obj.BlockAction, new Action(HandleBlock)); } } private void UnhookBlock() { if (hookedBlock != null) { Block? obj = hookedBlock; obj.BlockAction = (Action)Delegate.Remove(obj.BlockAction, new Action(HandleBlock)); hookedBlock = null; } } private void ApplyBonusHealth() { if (ownerData != null && !bonusHealthApplied) { originalMaxHealth = Mathf.Max(1f, ownerData.maxHealth); originalHealth = Mathf.Clamp(ownerData.health, 1f, originalMaxHealth); tempHealthBonus = originalMaxHealth * Mathf.Max(0f, ChannelHealthMultiplier - 1f); ownerData.maxHealth = originalMaxHealth + tempHealthBonus; ownerData.health = Mathf.Min(ownerData.maxHealth, ownerData.health + tempHealthBonus); bonusHealthApplied = tempHealthBonus > 0f; } } private void RemoveBonusHealth() { if (ownerData != null && bonusHealthApplied) { float num = Mathf.Max(1f, originalMaxHealth); float num2 = Mathf.Min(originalHealth, ownerData.health); ownerData.maxHealth = num; bonusHealthApplied = false; tempHealthBonus = 0f; originalMaxHealth = 0f; originalHealth = 0f; if (ownerData.dead) { ownerData.health = Mathf.Min(ownerData.health, num); } else if (num2 > 0f) { ownerData.health = Mathf.Min(num, num2); } else { ownerData.health = 1f; } } } private void EnterFrozenState() { //IL_002f: 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_001d: Unknown result type (might be due to invalid IL or missing references) if (body != null) { if (!constraintsStored) { storedConstraints = body.constraints; constraintsStored = true; } body.velocity = Vector2.zero; body.angularVelocity = 0f; body.constraints = (RigidbodyConstraints2D)7; } } private void MaintainFrozenState() { //IL_000e: 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) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (body != null) { body.velocity = Vector2.zero; body.angularVelocity = 0f; body.position = anchorPosition; } if (ownerData != null) { ((Component)ownerData).transform.position = Vector2.op_Implicit(anchorPosition); } } private void ReleaseFrozenState() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (body != null && constraintsStored) { body.constraints = storedConstraints; body.velocity = Vector2.zero; body.angularVelocity = 0f; } constraintsStored = false; } private void RegenerateDuringChannel() { if (ownerData != null && !(ChannelRegenPerSecond <= 0f) && !ownerData.dead) { ownerData.health = Mathf.Min(ownerData.maxHealth, ownerData.health + ChannelRegenPerSecond * TimeHandler.deltaTime); } } private void CleanupChargeVisual() { if (chargeVisual != null) { Object.Destroy((Object)(object)((Component)chargeVisual).gameObject); chargeVisual = null; } } private void StartChargeAudio(double syncedFireTime) { StopChargeAudio(); chargeAudio = AtomicChargeAudio.Spawn(syncedFireTime); } private void StopChargeAudio() { if (chargeAudio != null) { chargeAudio.StopImmediate(); chargeAudio = null; } } private void UpdateCooldownRing() { if (ownerData == null || EntryCount <= 0) { if (cooldownRing != null) { cooldownRing.SetState(isReady: false, 0f); } return; } if (cooldownRing == null) { cooldownRing = ((Component)this).gameObject.GetOrAddComponent(); } cooldownRing.Bind(ownerData); cooldownRing.SetState(IsAtomicReady, CooldownProgress); } } internal sealed class BeepboopEffect : MonoBehaviour { private const float ReapplyIntervalSeconds = 0.25f; private int stackCount; private Player? ownerPlayer; private CharacterData? ownerData; private float nextReapplyTime; private GameObject? skinHolder; private PlayerSkin? appliedSkin; internal bool IsNeutral => stackCount <= 0; internal void AddStack() { stackCount++; ApplyCurrentSkin(); } internal void RemoveStack() { stackCount = Math.Max(0, stackCount - 1); ApplyCurrentSkin(); } private void Start() { ResolveOwner(); ApplyCurrentSkin(); } private void Update() { ResolveOwner(); if (!(Time.unscaledTime < nextReapplyTime)) { nextReapplyTime = Time.unscaledTime + 0.25f; ApplyCurrentSkin(); } } private void ResolveOwner() { if (ownerPlayer == null) { ownerPlayer = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); } if (ownerData == null) { ownerData = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); } } private void ApplyCurrentSkin() { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) ResolveOwner(); if (ownerPlayer == null || ownerData == null) { return; } PlayerSkin playerSkinColors = PlayerSkinBank.GetPlayerSkinColors(ownerPlayer.playerID); if (playerSkinColors == null) { return; } EnsureSkin(); if (appliedSkin != null) { if (stackCount > 0) { appliedSkin.color = ToGray(playerSkinColors.color); appliedSkin.backgroundColor = ToGray(playerSkinColors.backgroundColor); appliedSkin.winText = ToGray(playerSkinColors.winText); appliedSkin.particleEffect = ToGray(playerSkinColors.particleEffect); } else { appliedSkin.color = playerSkinColors.color; appliedSkin.backgroundColor = playerSkinColors.backgroundColor; appliedSkin.winText = playerSkinColors.winText; appliedSkin.particleEffect = playerSkinColors.particleEffect; } SetTeamColor.TeamColorThis(((Component)ownerData).gameObject, appliedSkin); } } private void OnDestroy() { if (skinHolder != null) { Object.Destroy((Object)(object)skinHolder); } } private void EnsureSkin() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown if (skinHolder == null || appliedSkin == null) { skinHolder = new GameObject("DOLY_BEEPBOOP_SKIN"); ((Object)skinHolder).hideFlags = (HideFlags)61; appliedSkin = skinHolder.AddComponent(); } } private static Color ToGray(Color color) { //IL_0009: 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) float grayscale = ((Color)(ref color)).grayscale; return new Color(grayscale, grayscale, grayscale, color.a); } } internal sealed class BiodegradableBulletsEffect : ProjectileEffectBase { internal int SourceCount { get; set; } protected override void AttachToProjectile(GameObject projectile, ProjectileHit projectileHit) { if (SourceCount > 0) { projectile.GetOrAddComponent(); } } } internal sealed class BladeOfTheRuinedKingEffect : ProjectileEffectBase { internal int Stacks { get; set; } protected override void AttachToProjectile(GameObject projectile, ProjectileHit projectileHit) { GameObject projectile2 = projectile; if (Stacks <= 0) { return; } projectileHit.AddHitActionWithData((Action)delegate(HitInfo hit) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) HealthHandler hitHealth = ProjectileEffectBase.GetHitHealth(hit); CharacterData hitCharacterData = ProjectileEffectBase.GetHitCharacterData(hit); if (hitHealth != null && hitCharacterData != null) { float amount = hitCharacterData.health * 0.18f * (float)Stacks; ProjectileEffectBase.ApplyBonusDamage(hitHealth, amount, hit.point, projectile2, base.OwnerPlayer); } }); } } internal sealed class DemocracyProtectsEffect : MonoBehaviour { private const float ImmunityDurationSeconds = 0.1f; private float immunityUntil; internal int Stacks { get; set; } internal bool IsImmune => Time.time < immunityUntil; internal bool ShouldPreventLethalDamage() { if (IsImmune || Random.value >= 0.5f) { return false; } immunityUntil = Time.time + 0.1f; return true; } } internal sealed class DisintegrateOnBlockProjectileEffect : MonoBehaviour { private bool disintegrated; internal bool TryDisintegrate() { //IL_002d: 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) if (disintegrated) { return true; } disintegrated = true; ProjectileHit component = ((Component)this).GetComponent(); if (component != null) { component.bulletCanDealDeamage = false; } MoveTransform component2 = ((Component)this).GetComponent(); if (component2 != null) { component2.velocity = Vector3.zero; } RayCastTrail component3 = ((Component)this).GetComponent(); if (component3 != null) { component3.WasBlocked(); } Collider2D[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Behaviour)componentsInChildren[i]).enabled = false; } Renderer[] componentsInChildren2 = ((Component)this).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].enabled = false; } if (PhotonNetwork.OfflineMode) { Object.Destroy((Object)(object)((Component)this).gameObject); return true; } PhotonView component4 = ((Component)this).GetComponent(); if (component4 != null && component4.IsMine) { PhotonNetwork.Destroy(((Component)this).gameObject); } else { Object.Destroy((Object)(object)((Component)this).gameObject); } return true; } } internal sealed class DropMagEffect : MonoBehaviour { private CharacterData? ownerData; private GunAmmo? hookedGunAmmo; private CharacterStatModifiers? hookedStats; private GM_ArmsRace? hookedGameMode; private bool reloadHooked; internal int SourceCount { get; set; } internal int AmmoLostThisRound { get; private set; } private void Start() { ResolveOwner(); TryHookReload(); TryHookRoundReset(); } private void Update() { ResolveOwner(); TryHookReload(); TryHookRoundReset(); } private void OnDestroy() { UnhookReload(); UnhookRoundReset(); } internal bool TryApplyReloadPenalty(GunAmmo gunAmmo) { ResolveOwner(); if (SourceCount > 0 && ownerData != null && gunAmmo != null) { WeaponHandler weaponHandler = ownerData.weaponHandler; object obj; if (weaponHandler == null) { obj = null; } else { Gun gun = weaponHandler.gun; obj = ((gun != null) ? ((Component)gun).GetComponentInChildren() : null); } if (!((Object)(object)gunAmmo != (Object)obj)) { if (GameManager.instance == null || !GameManager.instance.battleOngoing || !ownerData.isPlaying || ownerData.dead) { return false; } int num = Mathf.Min(SourceCount, Math.Max(0, gunAmmo.maxAmmo - 1)); if (num <= 0) { return true; } hookedGunAmmo = gunAmmo; AmmoLostThisRound += num; gunAmmo.maxAmmo = Math.Max(1, gunAmmo.maxAmmo - num); gunAmmo.currentAmmo = Math.Min(gunAmmo.currentAmmo, gunAmmo.maxAmmo); gunAmmo.SetActiveBullets(false); gunAmmo.ReDrawTotalBullets(); return true; } } return false; } private void ResolveOwner() { if (ownerData == null) { ownerData = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); } if (hookedGunAmmo == null) { CharacterData? obj = ownerData; object obj2; if (obj == null) { obj2 = null; } else { WeaponHandler weaponHandler = obj.weaponHandler; if (weaponHandler == null) { obj2 = null; } else { Gun gun = weaponHandler.gun; obj2 = ((gun != null) ? ((Component)gun).GetComponentInChildren() : null); } } hookedGunAmmo = (GunAmmo?)obj2; } if (hookedStats == null) { hookedStats = ownerData?.stats; } } private void TryHookReload() { if (!reloadHooked && hookedStats != null) { CharacterStatModifiers? obj = hookedStats; obj.OnReloadDoneAction = (Action)Delegate.Combine(obj.OnReloadDoneAction, new Action(HandleReload)); reloadHooked = true; } } private void UnhookReload() { if (reloadHooked && hookedStats != null) { CharacterStatModifiers? obj = hookedStats; obj.OnReloadDoneAction = (Action)Delegate.Remove(obj.OnReloadDoneAction, new Action(HandleReload)); reloadHooked = false; } } private void HandleReload(int bulletsReloaded) { if (bulletsReloaded > 0 && hookedGunAmmo != null) { TryApplyReloadPenalty(hookedGunAmmo); } } private void TryHookRoundReset() { if (hookedGameMode == null && GM_ArmsRace.instance != null) { hookedGameMode = GM_ArmsRace.instance; GM_ArmsRace? obj = hookedGameMode; obj.pointOverAction = (Action)Delegate.Combine(obj.pointOverAction, new Action(HandlePointOver)); } } private void UnhookRoundReset() { if (hookedGameMode != null) { GM_ArmsRace? obj = hookedGameMode; obj.pointOverAction = (Action)Delegate.Remove(obj.pointOverAction, new Action(HandlePointOver)); hookedGameMode = null; } } private void HandlePointOver() { ResolveOwner(); if (AmmoLostThisRound <= 0 || hookedGunAmmo == null) { AmmoLostThisRound = 0; return; } GunAmmo? obj = hookedGunAmmo; obj.maxAmmo += AmmoLostThisRound; AmmoLostThisRound = 0; hookedGunAmmo.ReDrawTotalBullets(); } } internal sealed class GamblecoreTracker : MonoBehaviour { internal int GamblecoreCount { get; set; } internal int PendingReassignCount { get; set; } internal bool HasPendingReassign => PendingReassignCount > 0; internal int PendingAwDangItReassignCount { get; set; } internal bool HasPendingAwDangItReassign => PendingAwDangItReassignCount > 0; internal bool IsEmpty { get { if (GamblecoreCount <= 0 && !HasPendingReassign) { return !HasPendingAwDangItReassign; } return false; } } } internal sealed class GiantSlayerEffect : MonoBehaviour { internal int Stacks { get; set; } } internal sealed class GrievousWoundsEffect : MonoBehaviour { internal int Stacks { get; set; } } internal sealed class HealBlockDebuff : MonoBehaviour { private float expiresAt; internal bool IsActive => Time.time < expiresAt; internal void Apply(float durationSeconds) { expiresAt = Mathf.Max(expiresAt, Time.time + durationSeconds); } private void Update() { if (!IsActive && expiresAt > 0f) { Object.Destroy((Object)(object)this); } } } internal sealed class HelldiverBeacon : MonoBehaviour { private const float MarkerHeight = 3.15f; private const int CircleSegmentCount = 18; private const float VoidCancelMargin = 6f; private const int MaxSurfaceBounces = 3; private const float BounceSpeedRetention = 0.72f; private const float BounceSurfaceSeparation = 0.03f; private const float MinimumBounceSpeed = 5.5f; private static readonly Color BeaconCoreColor = new Color(0.4078f, 0.4078f, 0.4078f, 1f); private static readonly Color BeaconAccentColor = new Color(1f, 0.9059f, 0.0627f, 1f); private static readonly Color BeaconMarkerColor = new Color(0.2392f, 0.6902f, 0.8157f, 1f); private readonly Vector3[] circlePoints = (Vector3[])(object)new Vector3[19]; private HelldiverRuntime? ownerRuntime; private HelldiverEffect? ownerEffect; private HelldiverStratagemType type; private int ownerPlayerId; private int seed; private float callInDelaySeconds; private double executeTime; private double deployTime; private double spawnTime; private bool isAuthority; private bool settled; private bool executed; private bool deploymentRegistered; private bool deploymentBroadcast; private bool authoritativeDeploymentReceived; private int surfaceBounceCount; private float gravity; private Vector2 velocity; private Transform? stuckTarget; private Vector2 stuckOffset; private HelldiverActiveTargetBeam? targetBeam; private HelldiverStratagemTargetIcon? targetIcon; private LineRenderer? coreRenderer; private LineRenderer? accentRenderer; private LineRenderer? markerRenderer; private Material? coreMaterial; private Material? accentMaterial; private Material? markerMaterial; private float? cachedLowestMapY; internal void Configure(HelldiverEffect? effect, HelldiverStratagemType type, Vector2 startPosition, Vector2 startVelocity, float gravity, int ownerPlayerId, int seed, float callInDelaySeconds, bool isAuthority, double spawnTime, HelldiverRuntime? runtime) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_003a: Unknown result type (might be due to invalid IL or missing references) ownerRuntime = runtime; ownerEffect = effect; this.type = type; ((Component)this).transform.position = new Vector3(startPosition.x, startPosition.y, 0f); velocity = startVelocity; this.gravity = gravity; this.ownerPlayerId = ownerPlayerId; this.seed = seed; this.callInDelaySeconds = callInDelaySeconds; executeTime = double.PositiveInfinity; deployTime = double.PositiveInfinity; this.isAuthority = isAuthority; this.spawnTime = spawnTime; ownerEffect?.RegisterPendingBeacon(this); EnsureRenderers(); ownerRuntime?.RegisterTrackedBeacon(seed, this); UpdateVisual(); } private void Update() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) double num = (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time); if (executed) { return; } if (stuckTarget != null) { ((Component)this).transform.position = new Vector3(stuckTarget.position.x + stuckOffset.x, stuckTarget.position.y + stuckOffset.y, 0f); } else if (!settled) { SimulateMotion(); } if (!executed && IsInVoid()) { if (isAuthority && !authoritativeDeploymentReceived) { executed = true; ownerEffect?.BroadcastBeaconCancellation(seed); Object.Destroy((Object)(object)((Component)this).gameObject, 0.1f); } else if (authoritativeDeploymentReceived) { executed = true; Object.Destroy((Object)(object)((Component)this).gameObject, 0.1f); } else if (!isAuthority) { UpdateVisual(); } else { executed = true; Object.Destroy((Object)(object)((Component)this).gameObject, 0.1f); } return; } if (settled && isAuthority && !deploymentBroadcast) { deploymentBroadcast = true; ownerEffect?.BroadcastBeaconDeployment(type, seed, Vector2.op_Implicit(((Component)this).transform.position), ResolveStuckPlayerId(), stuckOffset, num, num + (double)callInDelaySeconds); } if (authoritativeDeploymentReceived && !deploymentRegistered) { deploymentRegistered = true; ownerEffect?.NotifyBeaconDeployed(this, type, deployTime); if (targetBeam == null) { targetBeam = HelldiverActiveTargetBeam.Spawn(((Component)this).transform, type, executeTime); } if (targetIcon == null) { targetIcon = HelldiverStratagemTargetIcon.Spawn(((Component)this).transform, type, executeTime); } } UpdateVisual(); if (authoritativeDeploymentReceived && isAuthority && num >= executeTime) { executed = true; ownerEffect?.BroadcastExecute(type, Vector2.op_Implicit(((Component)this).transform.position), ResolveRunDirection(), seed, executeTime); Object.Destroy((Object)(object)((Component)this).gameObject, 0.1f); } else if (authoritativeDeploymentReceived && !isAuthority && num >= executeTime + 0.20000000298023224) { executed = true; Object.Destroy((Object)(object)((Component)this).gameObject, 0.1f); } } private void OnDestroy() { if (targetBeam != null) { targetBeam.NotifySourceDestroyed(); } if (targetIcon != null) { targetIcon.NotifySourceDestroyed(); } if (coreMaterial != null) { Object.Destroy((Object)(object)coreMaterial); } if (accentMaterial != null) { Object.Destroy((Object)(object)accentMaterial); } if (markerMaterial != null) { Object.Destroy((Object)(object)markerMaterial); } ownerRuntime?.NotifyTrackedBeaconDestroyed(seed, this); ownerEffect?.NotifyBeaconDestroyed(this); } private void SimulateMotion() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_002c: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Min(TimeHandler.deltaTime, 0.02f); if (num <= 0f) { return; } Vector2 val = Vector2.op_Implicit(((Component)this).transform.position); velocity += Vector2.down * gravity * num; Vector2 val2 = velocity * num; float magnitude = ((Vector2)(ref val2)).magnitude; if (magnitude <= 0.0001f) { ((Component)this).transform.position = Vector2.op_Implicit(val); return; } RaycastHit2D[] array = CollectCollisionHits(val, ((Vector2)(ref val2)).normalized, magnitude); RaycastHit2D? val3 = null; float num2 = float.MaxValue; RaycastHit2D[] array2 = array; for (int i = 0; i < array2.Length; i++) { RaycastHit2D value = array2[i]; Collider2D collider = ((RaycastHit2D)(ref value)).collider; if (collider != null && !collider.isTrigger && !ShouldIgnoreCollider(collider) && IsCollidableTarget(collider)) { float distance = ((RaycastHit2D)(ref value)).distance; if (!(distance >= num2)) { num2 = distance; val3 = value; } } } if (!val3.HasValue) { ((Component)this).transform.position = Vector2.op_Implicit(val + val2); } else { HandleCollision(val3.Value); } } private bool ShouldIgnoreCollider(Collider2D collider) { Player componentInParent = ((Component)collider).GetComponentInParent(); if (componentInParent == null) { return false; } double num = (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time) - spawnTime; if (componentInParent.playerID == ownerPlayerId) { return num < 0.18000000715255737; } return false; } private static RaycastHit2D[] CollectCollisionHits(Vector2 currentPosition, Vector2 direction, float distance) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_002f: Unknown result type (might be due to invalid IL or missing references) int num = ((PlayerManager.instance != null) ? ((LayerMask)(ref PlayerManager.instance.canSeePlayerMask)).value : (-1)); RaycastHit2D[] array = Physics2D.CircleCastAll(currentPosition, 0.18f, direction, distance, num); RaycastHit2D[] array2 = Physics2D.CircleCastAll(currentPosition, 0.18f, direction, distance); if (array.Length == 0) { return array2; } if (array2.Length == 0) { return array; } RaycastHit2D[] array3 = (RaycastHit2D[])(object)new RaycastHit2D[array.Length + array2.Length]; Array.Copy(array, 0, array3, 0, array.Length); Array.Copy(array2, 0, array3, array.Length, array2.Length); return array3; } private static bool IsCollidableTarget(Collider2D collider) { if (((Component)collider).GetComponentInParent() != null) { return true; } if (PlayerManager.instance == null) { return true; } int value = ((LayerMask)(ref PlayerManager.instance.canSeePlayerMask)).value; return ((1 << ((Component)collider).gameObject.layer) & value) != 0; } private void HandleCollision(RaycastHit2D hit) { //IL_0053: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_003f: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_0075: Unknown result type (might be due to invalid IL or missing references) Collider2D collider = ((RaycastHit2D)(ref hit)).collider; if (collider == null) { return; } Player componentInParent = ((Component)collider).GetComponentInParent(); if (componentInParent != null) { stuckTarget = ((Component)componentInParent).transform; stuckOffset = ((RaycastHit2D)(ref hit)).point - Vector2.op_Implicit(((Component)componentInParent).transform.position); SettleAt(((RaycastHit2D)(ref hit)).point); return; } Vector2 normal = ResolveSurfaceNormal(hit); Vector2 val = ResolveImpactPosition(hit, normal); if (surfaceBounceCount < 3 && !CanStickToSurface(normal)) { BounceOffSurface(val, normal); } else { SettleAt(val); } } private Vector2 ResolveSurfaceNormal(RaycastHit2D hit) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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) Vector2 val = ((RaycastHit2D)(ref hit)).normal; if (((Vector2)(ref val)).sqrMagnitude > 0.0001f) { val = ((RaycastHit2D)(ref hit)).normal; return ((Vector2)(ref val)).normalized; } Vector2 val2 = Vector2.op_Implicit(((Component)this).transform.position) - ((RaycastHit2D)(ref hit)).point; if (((Vector2)(ref val2)).sqrMagnitude > 0.0001f) { return ((Vector2)(ref val2)).normalized; } if (((Vector2)(ref velocity)).sqrMagnitude > 0.0001f) { val = -velocity; return ((Vector2)(ref val)).normalized; } return Vector2.up; } private static Vector2 ResolveImpactPosition(RaycastHit2D hit, Vector2 normal) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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) Vector2 centroid = ((RaycastHit2D)(ref hit)).centroid; if (((Vector2)(ref centroid)).sqrMagnitude > 0.0001f) { return ((RaycastHit2D)(ref hit)).centroid; } return ((RaycastHit2D)(ref hit)).point + normal * 0.18f; } private static bool CanStickToSurface(Vector2 normal) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) return Vector2.Angle(normal, Vector2.up) <= 40f; } private void BounceOffSurface(Vector2 impactPosition, Vector2 normal) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_0081: Unknown result type (might be due to invalid IL or missing references) surfaceBounceCount++; ((Component)this).transform.position = Vector2.op_Implicit(impactPosition + normal * 0.03f); Vector2 val = Vector2.Reflect(velocity, normal) * 0.72f; if (((Vector2)(ref val)).sqrMagnitude <= 0.0001f) { val = normal * 5.5f; } else if (((Vector2)(ref val)).magnitude < 5.5f) { val = ((Vector2)(ref val)).normalized * 5.5f; } velocity = val; } internal void CancelAndDestroy() { if (!executed) { executed = true; Object.Destroy((Object)(object)((Component)this).gameObject, 0.1f); } } internal bool MatchesSeed(int beaconSeed) { return seed == beaconSeed; } internal void ApplyAuthoritativeDeployment(Vector2 settledPosition, int stuckPlayerId, Vector2 authoritativeStuckOffset, double deployTime, double executeTime) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_0060: 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_0097: Unknown result type (might be due to invalid IL or missing references) authoritativeDeploymentReceived = true; this.deployTime = deployTime; this.executeTime = executeTime; settled = true; velocity = Vector2.zero; if (stuckPlayerId >= 0) { Player? obj = HolySmiteEffect.ResolvePlayerById(stuckPlayerId); stuckTarget = ((obj != null) ? ((Component)obj).transform : null); stuckOffset = authoritativeStuckOffset; if (stuckTarget != null) { ((Component)this).transform.position = new Vector3(stuckTarget.position.x + stuckOffset.x, stuckTarget.position.y + stuckOffset.y, 0f); return; } } stuckTarget = null; stuckOffset = Vector2.zero; ((Component)this).transform.position = new Vector3(settledPosition.x, settledPosition.y, 0f); } private void SettleAt(Vector2 position) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_0019: Unknown result type (might be due to invalid IL or missing references) settled = true; velocity = Vector2.zero; ((Component)this).transform.position = Vector2.op_Implicit(position); } private int ResolveStuckPlayerId() { return ((stuckTarget == null) ? null : ((Component)stuckTarget).GetComponentInParent())?.playerID ?? (-1); } private Vector2 ResolveRunDirection() { //IL_000d: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_005f: 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) if (!UsesDirectionalRun(type)) { return Vector2.zero; } Player val = HolySmiteEffect.ResolvePlayerById(ownerPlayerId); if (val != null) { float num = ((Component)this).transform.position.x - ((Component)val).transform.position.x; if (Mathf.Abs(num) > 0.0001f) { if (!(num > 0f)) { return Vector2.left; } return Vector2.right; } } if (new Random(seed).Next(0, 2) != 0) { return Vector2.right; } return Vector2.left; } private static bool UsesDirectionalRun(HelldiverStratagemType type) { if ((uint)(type - 8) <= 2u) { return true; } return false; } private bool IsInVoid() { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) MapManager instance = MapManager.instance; object obj; if (instance == null) { obj = null; } else { MapWrapper currentMap = instance.currentMap; obj = ((currentMap != null) ? currentMap.Map : null); } if (obj == null) { return false; } float? num = cachedLowestMapY; if (!num.HasValue) { Collider2D[] componentsInChildren = ((Component)MapManager.instance.currentMap.Map).GetComponentsInChildren(); if (componentsInChildren.Length == 0) { return false; } bool flag = false; float num2 = 0f; Collider2D[] array = componentsInChildren; foreach (Collider2D val in array) { if (val != null && !val.isTrigger) { Bounds bounds = val.bounds; float y = ((Bounds)(ref bounds)).min.y; if (!flag || y < num2) { num2 = y; flag = true; } } } if (!flag) { return false; } cachedLowestMapY = num2; } return ((Component)this).transform.position.y < cachedLowestMapY.Value - 6f; } private void EnsureRenderers() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Expected O, but got Unknown //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Expected O, but got Unknown if (coreRenderer == null) { GameObject val = new GameObject("BeaconCore"); val.transform.SetParent(((Component)this).transform, false); coreRenderer = val.AddComponent(); coreMaterial = new Material(Shader.Find("Sprites/Default")); ((Renderer)coreRenderer).material = coreMaterial; coreRenderer.useWorldSpace = true; coreRenderer.loop = false; coreRenderer.positionCount = 19; coreRenderer.numCapVertices = 6; coreRenderer.numCornerVertices = 6; coreRenderer.alignment = (LineAlignment)0; ((Renderer)coreRenderer).sortingOrder = 1400; } if (accentRenderer == null) { GameObject val2 = new GameObject("BeaconAccent"); val2.transform.SetParent(((Component)this).transform, false); accentRenderer = val2.AddComponent(); accentMaterial = new Material(Shader.Find("Sprites/Default")); ((Renderer)accentRenderer).material = accentMaterial; accentRenderer.useWorldSpace = true; accentRenderer.loop = false; accentRenderer.positionCount = 19; accentRenderer.numCapVertices = 6; accentRenderer.numCornerVertices = 6; accentRenderer.alignment = (LineAlignment)0; ((Renderer)accentRenderer).sortingOrder = 1401; } if (markerRenderer == null) { GameObject val3 = new GameObject("BeaconMarker"); val3.transform.SetParent(((Component)this).transform, false); markerRenderer = val3.AddComponent(); markerMaterial = new Material(Shader.Find("Sprites/Default")); ((Renderer)markerRenderer).material = markerMaterial; markerRenderer.useWorldSpace = true; markerRenderer.loop = false; markerRenderer.positionCount = 2; markerRenderer.numCapVertices = 6; markerRenderer.numCornerVertices = 6; markerRenderer.alignment = (LineAlignment)0; ((Renderer)markerRenderer).sortingOrder = 1399; } } private void UpdateVisual() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) if (coreRenderer != null && accentRenderer != null && markerRenderer != null) { Vector3 position = ((Component)this).transform.position; float num = 0.5f + 0.5f * Mathf.Sin(Time.time * 8f); float num2 = 0.18f * (settled ? 1f : 1.04f); for (int i = 0; i <= 18; i++) { float num3 = (float)i / 18f * MathF.PI * 2f; circlePoints[i] = position + new Vector3(Mathf.Cos(num3) * num2, Mathf.Sin(num3) * num2, 0f); } Color beaconCoreColor = BeaconCoreColor; beaconCoreColor.a = (settled ? 0.98f : 0.92f); coreRenderer.widthMultiplier = (settled ? 0.15f : 0.13f); coreRenderer.startColor = beaconCoreColor; coreRenderer.endColor = beaconCoreColor; coreRenderer.SetPositions(circlePoints); Color beaconAccentColor = BeaconAccentColor; beaconAccentColor.a = 0.82f + 0.08f * num; accentRenderer.widthMultiplier = (settled ? 0.026f : 0.022f); accentRenderer.startColor = beaconAccentColor; accentRenderer.endColor = beaconAccentColor; accentRenderer.SetPositions(circlePoints); Color beaconMarkerColor = BeaconMarkerColor; beaconMarkerColor.a = 0.24f + 0.08f * num; ((Renderer)markerRenderer).enabled = true; markerRenderer.startWidth = 0.16f; markerRenderer.endWidth = 0.05f; markerRenderer.startColor = beaconMarkerColor; markerRenderer.endColor = new Color(beaconMarkerColor.r, beaconMarkerColor.g, beaconMarkerColor.b, 0f); markerRenderer.SetPosition(0, position); markerRenderer.SetPosition(1, position + Vector3.up * 3.15f); } } } internal sealed class HelldiverActiveTargetBeam : MonoBehaviour { private const float FadeInDurationSeconds = 0.18f; private const float FadeDurationSeconds = 1f; private static readonly Color BeamColor = new Color(0.96f, 0.24f, 0.2f, 0.154f); private Transform? trackedTarget; private Vector2 frozenPoint; private double executeTime; private double destroyTime; private double spawnTime; private bool frozen; private LineRenderer? beamRenderer; private Material? beamMaterial; internal static HelldiverActiveTargetBeam Spawn(Transform target, HelldiverStratagemType type, double executeTime) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) HelldiverActiveTargetBeam helldiverActiveTargetBeam = new GameObject($"DOLY_{type}_ActiveTargetBeam").AddComponent(); helldiverActiveTargetBeam.Configure(target, type, executeTime); return helldiverActiveTargetBeam; } private void Configure(Transform target, HelldiverStratagemType type, double executeTime) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown trackedTarget = target; frozenPoint = Vector2.op_Implicit(target.position); spawnTime = (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time); this.executeTime = executeTime; destroyTime = executeTime + (double)HelldiverStrikeController.GetActiveIndicatorDurationSeconds(type) + 1.0; beamRenderer = ((Component)this).gameObject.AddComponent(); beamMaterial = new Material(Shader.Find("Sprites/Default")); ((Renderer)beamRenderer).material = beamMaterial; beamRenderer.useWorldSpace = true; beamRenderer.loop = false; beamRenderer.positionCount = 2; beamRenderer.numCapVertices = 8; beamRenderer.numCornerVertices = 8; beamRenderer.alignment = (LineAlignment)0; ((Renderer)beamRenderer).sortingOrder = 1405; beamRenderer.startWidth = 0.405f; beamRenderer.endWidth = 0.405f; } internal void NotifySourceDestroyed() { FreezeAtCurrentPoint(); } private void Update() { //IL_0074: 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_007b: 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_0082: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) double num = (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time); if (num >= destroyTime) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } if (!frozen && (trackedTarget == null || num >= executeTime)) { FreezeAtCurrentPoint(); } UpdateVisual(frozenPoint = (frozen ? frozenPoint : ((trackedTarget != null) ? Vector2.op_Implicit(trackedTarget.position) : frozenPoint)), num); } private void FreezeAtCurrentPoint() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (!frozen) { if (trackedTarget != null) { frozenPoint = Vector2.op_Implicit(trackedTarget.position); } trackedTarget = null; frozen = true; } } private void UpdateVisual(Vector2 point, double currentTime) { //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) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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 (beamRenderer != null) { float num = ((currentTime <= destroyTime - 1.0) ? 1f : Mathf.Clamp01((float)((destroyTime - currentTime) / 1.0))); num *= Mathf.Clamp01((float)((currentTime - spawnTime) / 0.18000000715255737)); Color beamColor = BeamColor; beamColor.a *= num; beamRenderer.startColor = beamColor; beamRenderer.endColor = beamColor; beamRenderer.SetPosition(0, Vector2.op_Implicit(ResolveTopPoint(point))); beamRenderer.SetPosition(1, Vector2.op_Implicit(point)); } } private static Vector2 ResolveTopPoint(Vector2 point) { //IL_0011: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) Camera main = Camera.main; if (main == null || !main.orthographic) { return point + Vector2.up * 8f; } return new Vector2(point.x, ((Component)main).transform.position.y + main.orthographicSize + 0.35f); } private void OnDestroy() { if (beamMaterial != null) { Object.Destroy((Object)(object)beamMaterial); } } } internal static class HelldiverBombGunPool { private static SimulatedGun? sharedGun; private static Gun? defaultGunTemplate; private static float? defaultProjectileBaseDamage; internal static void Warm() { GetOrCreateSharedGun(); } internal static void Invalidate() { if ((Object)(object)sharedGun != (Object)null) { Object.Destroy((Object)(object)((Component)sharedGun).gameObject); } sharedGun = null; defaultGunTemplate = null; defaultProjectileBaseDamage = null; } internal static bool Configure(Player owner, float projectileSpeed, Vector2 flightDirection, float unlockDepthY, float directDamage, float directPercentDamage, float explosionRadius, float explosionDamage, float explosionPercentDamage, int maxBounces, float bounceSpeedRetention, float fuseSeconds) { //IL_0016: 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) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) Player owner2 = owner; if (owner2.data == null) { return false; } SimulatedGun orCreateSharedGun = GetOrCreateSharedGun(); Gun val = GetDefaultGunTemplate(); if (orCreateSharedGun == null || val == null) { return false; } orCreateSharedGun.CopyGunStatsExceptActions(val); ((Gun)orCreateSharedGun).projectiles = CloneProjectiles(val.projectiles); ((Gun)orCreateSharedGun).player = owner2; ((Gun)orCreateSharedGun).damage = directDamage / GetDefaultProjectileBaseDamage(); ((Gun)orCreateSharedGun).percentageDamage = directPercentDamage; ((Gun)orCreateSharedGun).knockback = 0f; ((Gun)orCreateSharedGun).slow = 0f; ((Gun)orCreateSharedGun).spread = 0f; ((Gun)orCreateSharedGun).evenSpread = 0f; ((Gun)orCreateSharedGun).numberOfProjectiles = 1; ((Gun)orCreateSharedGun).bursts = 1; ((Gun)orCreateSharedGun).timeBetweenBullets = 0f; ((Gun)orCreateSharedGun).drag = 0f; ((Gun)orCreateSharedGun).dragMinSpeed = 0f; ((Gun)orCreateSharedGun).gravity = 0f; ((Gun)orCreateSharedGun).projectielSimulatonSpeed = 1f; ((Gun)orCreateSharedGun).projectileSpeed = 1f; ((Gun)orCreateSharedGun).shake = 0f; ((Gun)orCreateSharedGun).shakeM = 0f; ((Gun)orCreateSharedGun).forceSpecificShake = true; ((Gun)orCreateSharedGun).ignoreWalls = true; ((Gun)orCreateSharedGun).destroyBulletAfter = fuseSeconds + 2f; ((Gun)orCreateSharedGun).projectileColor = Color.black; ((Gun)orCreateSharedGun).reflects = 0; GameObject val2 = ResolveBombProjectilePrefab(val); if (val2 != null) { ProjectilesToSpawn[] projectiles = ((Gun)orCreateSharedGun).projectiles; if (projectiles != null && projectiles.Length > 0) { ((Gun)orCreateSharedGun).projectiles[0].objectToSpawn = val2; } } ((Gun)orCreateSharedGun).objectsToSpawn = BuildBombAttachments(); ((Gun)orCreateSharedGun).ShootPojectileAction = delegate { }; ((Gun)orCreateSharedGun).ShootPojectileAction = (Action)Delegate.Combine(((Gun)orCreateSharedGun).ShootPojectileAction, (Action)delegate(GameObject bullet) { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) ProjectileHit component = bullet.GetComponent(); if (component != null) { component.fullSelfDamage = true; component.holdPlayerFor = fuseSeconds; component.destroyOnBlock = false; component.force = 0f; component.shake = 0f; component.movementSlow = 0f; } RayCastTrail component2 = bullet.GetComponent(); if (component2 != null) { component2.teamID = -1; component2.timeAtSpawn = 0f; component2.extraSize = Mathf.Min(component2.extraSize, 0f); } HelldiverBombProjectileController helldiverBombProjectileController = bullet.GetComponent(); if (helldiverBombProjectileController == null) { helldiverBombProjectileController = bullet.AddComponent(); } HelldiverBombBounceEffect helldiverBombBounceEffect = bullet.GetComponent(); if (helldiverBombBounceEffect == null) { helldiverBombBounceEffect = bullet.AddComponent(); } helldiverBombProjectileController.Configure(projectileSpeed, flightDirection, unlockDepthY, explosionRadius, explosionDamage, explosionPercentDamage, 0f, fuseSeconds, owner2.playerID); helldiverBombBounceEffect.Configure(maxBounces, bounceSpeedRetention); }); return true; } internal static bool Fire(Player owner, Vector2 spawnPoint) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (owner.data == null) { return false; } SimulatedGun orCreateSharedGun = GetOrCreateSharedGun(); if (orCreateSharedGun == null) { return false; } return orCreateSharedGun.SimulatedAttack(owner.playerID, Vector2.op_Implicit(spawnPoint), Vector3.down, 0f, 1f, (Transform)null, false); } private static ObjectsToSpawn[] BuildBombAttachments() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0046: Expected O, but got Unknown //IL_004a: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown GameObject loadedPrefab = HelldiverVanillaPrefabResolver.GetLoadedPrefab("A_Bomb_Bombs_Away"); GameObject loadedPrefab2 = HelldiverVanillaPrefabResolver.GetLoadedPrefab("S_ExtraGravity_BombsAway"); if (loadedPrefab == null && loadedPrefab2 == null) { return (ObjectsToSpawn[])(object)new ObjectsToSpawn[0]; } List list = new List(2); if (loadedPrefab != null) { list.Add(new ObjectsToSpawn { AddToProjectile = loadedPrefab, removeScriptsFromProjectileObject = true }); } if (loadedPrefab2 != null) { list.Add(new ObjectsToSpawn { AddToProjectile = loadedPrefab2, removeScriptsFromProjectileObject = false }); } return list.ToArray(); } private static GameObject? ResolveBombProjectilePrefab(Gun templateGun) { GameObject loadedPrefab = HelldiverVanillaPrefabResolver.GetLoadedPrefab("Bullet_NoTrail"); if (loadedPrefab != null) { return loadedPrefab; } ProjectilesToSpawn[] projectiles = templateGun.projectiles; if (projectiles == null || projectiles.Length <= 0) { return null; } return templateGun.projectiles[0].objectToSpawn; } private static ProjectilesToSpawn[] CloneProjectiles(ProjectilesToSpawn[] projectiles) { //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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown ProjectilesToSpawn[] array = (ProjectilesToSpawn[])(object)new ProjectilesToSpawn[projectiles.Length]; for (int i = 0; i < projectiles.Length; i++) { ProjectilesToSpawn val = projectiles[i]; array[i] = new ProjectilesToSpawn { objectToSpawn = val.objectToSpawn, numberOfSpawns = val.numberOfSpawns }; } return array; } private static SimulatedGun? GetOrCreateSharedGun() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown if ((Object)(object)sharedGun != (Object)null) { return sharedGun; } GameObject val = new GameObject("DOLY_HelldiverBombGun"); Object.DontDestroyOnLoad((Object)val); sharedGun = val.AddComponent(); return sharedGun; } private static Gun? GetDefaultGunTemplate() { if ((Object)(object)defaultGunTemplate != (Object)null) { return defaultGunTemplate; } GameObject val = Resources.Load("Player"); if (val == null) { return null; } Holdable val2 = val.GetComponent()?.holdable; defaultGunTemplate = ((val2 != null) ? ((Component)val2).GetComponent() : null); return defaultGunTemplate; } private static float GetDefaultProjectileBaseDamage() { if (defaultProjectileBaseDamage.HasValue) { return defaultProjectileBaseDamage.Value; } ProjectilesToSpawn[] array = GetDefaultGunTemplate()?.projectiles; GameObject obj = ((array != null && array.Length > 0) ? array[0].objectToSpawn : null); float valueOrDefault = ((obj == null) ? null : obj.GetComponent()?.damage).GetValueOrDefault(1f); defaultProjectileBaseDamage = Mathf.Max(0.0001f, valueOrDefault); return defaultProjectileBaseDamage.Value; } } internal sealed class HelldiverBombProjectileController : MonoBehaviour { private const float SurfaceExplosionOffset = 0.08f; private LayerMask defaultRayMask; private float initialSpeed; private Vector2 initialDirection = Vector2.down; private float unlockDepthY; private float explosionRadius; private float explosionDamage; private float explosionPercentDamage; private float edgeDamageMultiplier; private float fuseSeconds; private int ownerPlayerId; private bool configured; private bool defaultRayMaskCaptured; private bool launched; private bool wallsUnlocked; private bool exploded; private float elapsed; private MoveTransform? moveTransform; private ProjectileHit? projectileHit; private RayCastTrail? rayCastTrail; private SpawnedAttack? spawnedAttack; private PhotonView? photonView; private bool impactHooked; internal void Configure(float initialSpeed, Vector2 initialDirection, float unlockDepthY, float explosionRadius, float explosionDamage, float explosionPercentDamage, float edgeDamageMultiplier, float fuseSeconds, int ownerPlayerId) { //IL_001f: 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_0024: 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) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) this.initialSpeed = initialSpeed; this.initialDirection = ((((Vector2)(ref initialDirection)).sqrMagnitude > 0.0001f) ? ((Vector2)(ref initialDirection)).normalized : Vector2.down); this.unlockDepthY = unlockDepthY; this.explosionRadius = explosionRadius; this.explosionDamage = explosionDamage; this.explosionPercentDamage = explosionPercentDamage; this.edgeDamageMultiplier = edgeDamageMultiplier; this.fuseSeconds = Mathf.Max(0.01f, fuseSeconds); this.ownerPlayerId = ownerPlayerId; configured = true; launched = false; wallsUnlocked = false; exploded = false; elapsed = 0f; if (moveTransform != null) { ((Behaviour)moveTransform).enabled = true; moveTransform.velocity = Vector3.zero; } if (projectileHit != null) { ((Behaviour)projectileHit).enabled = true; projectileHit.bulletCanDealDeamage = true; } if (rayCastTrail != null && defaultRayMaskCaptured) { rayCastTrail.mask = defaultRayMask; } if (photonView != null) { ((Behaviour)photonView).enabled = true; } TryResolveComponents(); } private void Update() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!configured) { return; } TryResolveComponents(); if (!wallsUnlocked && ((Component)this).transform.position.y <= unlockDepthY) { wallsUnlocked = true; if (rayCastTrail != null) { rayCastTrail.mask = ((PlayerManager.instance != null) ? PlayerManager.instance.canSeePlayerMask : LayerMask.op_Implicit(-1)); } } if (!launched && moveTransform != null) { launched = true; moveTransform.velocity = Vector2.op_Implicit(initialDirection * initialSpeed); ((Component)this).transform.rotation = Quaternion.LookRotation(Vector3.forward, moveTransform.velocity); } if (!exploded) { elapsed += TimeHandler.deltaTime; if (!(elapsed < fuseSeconds)) { exploded = true; Vector2 explosionPoint = Vector2.op_Implicit(((Component)this).transform.position); SpawnDetonationPayload(explosionPoint, Vector2.up); } } } private void TryResolveComponents() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) if (moveTransform == null) { moveTransform = ((Component)this).GetComponent(); } if (projectileHit == null) { projectileHit = ((Component)this).GetComponent(); } if (rayCastTrail == null) { rayCastTrail = ((Component)this).GetComponent(); } if (spawnedAttack == null) { spawnedAttack = ((Component)this).GetComponent(); } if (photonView == null) { photonView = ((Component)this).GetComponent(); } if (!defaultRayMaskCaptured && rayCastTrail != null) { defaultRayMask = rayCastTrail.mask; defaultRayMaskCaptured = true; } if (!impactHooked && projectileHit != null) { projectileHit.AddHitActionWithData((Action)HandleImpact); impactHooked = true; } } private void HandleImpact(HitInfo hitInfo) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_0054: 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_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_0041: Unknown result type (might be due to invalid IL or missing references) if (!exploded) { Vector2 val = ((((Vector2)(ref hitInfo.normal)).sqrMagnitude > 0.0001f) ? ((Vector2)(ref hitInfo.normal)).normalized : Vector2.up); if (val.y < 0f) { val = -val; } SpawnDetonationPayload(hitInfo.point + val * 0.08f, val); } } internal void TriggerSurfaceDetonation(HitInfo hitInfo) { HandleImpact(hitInfo); } private void SpawnDetonationPayload(Vector2 explosionPoint, Vector2 surfaceNormal) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) if (!exploded) { exploded = true; HelldiverDelayedExplosionPayload helldiverDelayedExplosionPayload = new GameObject("DOLY_HelldiverClusterBombDetonation").AddComponent(); float radius = explosionRadius; float flatDamage = explosionDamage; float percentageDamage = explosionPercentDamage; float num = edgeDamageMultiplier; int num2 = ownerPlayerId; SpawnedAttack? obj = spawnedAttack; bool? obj3; if (obj == null) { PhotonView? obj2 = photonView; obj3 = ((obj2 != null) ? new bool?(obj2.IsMine) : null); } else { obj3 = obj.IsMine(); } bool? flag = obj3; helldiverDelayedExplosionPayload.Configure(explosionPoint, radius, flatDamage, percentageDamage, num, 0.01f, num2, -1, ignoreWalls: false, flag.GetValueOrDefault(), HelldiverExplosionPresentationSize.Small, HelldiverExplosionPresentationSize.Small, 1f, Color.white, 0.42f, 0.14f, Vector2.SignedAngle(Vector2.up, surfaceNormal)); if (projectileHit != null) { projectileHit.bulletCanDealDeamage = false; ((Behaviour)projectileHit).enabled = false; } if (moveTransform != null) { moveTransform.velocity = Vector3.zero; ((Behaviour)moveTransform).enabled = false; } if (photonView != null && photonView.IsMine) { PhotonNetwork.Destroy(((Component)this).gameObject); } else { Object.Destroy((Object)(object)((Component)this).gameObject, 0.05f); } } } } internal sealed class HelldiverBombBounceEffect : RayHitEffect { private const float MinimumBounceSpeed = 3.5f; private const float MaxGroundBounceUpwardSpeed = 8f; private const float GroundHorizontalRetention = 0.2f; private MoveTransform? moveTransform; private int remainingBounces; private float speedRetention; internal void Configure(int maxBounces, float speedRetention) { remainingBounces = Mathf.Max(0, maxBounces); this.speedRetention = Mathf.Clamp(speedRetention, 0.05f, 1f); base.priority = 1000; if (moveTransform == null) { moveTransform = ((Component)this).GetComponent(); } } public override HasToReturn DoHitEffect(HitInfo hit) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012e: 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_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) if (moveTransform == null) { moveTransform = ((Component)this).GetComponent(); } if (moveTransform == null || remainingBounces <= 0) { ((Component)this).GetComponent()?.TriggerSurfaceDetonation(hit); return (HasToReturn)0; } Vector3 velocity = moveTransform.velocity; Vector2 val = default(Vector2); if (hit.normal.y >= 0.65f) { ((Vector2)(ref val))..ctor(velocity.x * 0.2f, Mathf.Min(Mathf.Abs(velocity.y) * speedRetention, 8f)); } else { val = Vector2.Reflect(Vector2.op_Implicit(velocity), hit.normal) * speedRetention; } if (((Vector2)(ref val)).sqrMagnitude < 12.25f) { val = (Vector2)((hit.normal.y >= 0.65f) ? new Vector2(0f, 3.5f) : ((((Vector2)(ref hit.normal)).sqrMagnitude > 0.0001f) ? (((Vector2)(ref hit.normal)).normalized * 3.5f) : (Vector2.up * 3.5f))); } moveTransform.velocity = Vector2.op_Implicit(val); ((Component)this).transform.position = Vector2.op_Implicit(hit.point + ((Vector2)(ref val)).normalized * 0.08f); remainingBounces--; if (remainingBounces <= 0) { ((Component)this).GetComponent()?.TriggerSurfaceDetonation(hit); } return (HasToReturn)0; } } internal sealed class HelldiverDeferredExplosion : MonoBehaviour { internal void Configure(float radius, float damage, Player? owner, bool ignoreWalls) { ((Component)this).gameObject.AddComponent().spawner = owner; Explosion obj = ((Component)this).gameObject.AddComponent(); obj.auto = false; obj.damage = damage; obj.range = radius; obj.force = 0f; obj.slow = 0f; obj.silence = 0f; obj.stun = 0f; obj.flyingFor = 0f; obj.ignoreTeam = false; obj.ignoreWalls = ignoreWalls; obj.staticRangeMultiplier = false; obj.scaleSlow = false; obj.scaleSilence = false; obj.scaleDmg = false; obj.scaleRadius = false; obj.scaleStun = false; obj.scaleForce = false; obj.auto = true; Object.Destroy((Object)(object)((Component)this).gameObject, 0.15f); } } internal sealed class HelldiverDelayedExplosionPayload : MonoBehaviour { private Vector2 explosionPoint; private float radius; private float flatDamage; private float percentageDamage; private float edgeDamageMultiplier; private float delaySeconds; private int ownerPlayerId; private int ignoredPlayerId = -1; private bool ignoreWalls; private bool applyDamageAuthority; private float elapsed; private bool detonated; private HelldiverExplosionPresentationSize visualSize; private HelldiverExplosionPresentationSize soundSize; private float soundVolumeMultiplier; internal void Configure(Vector2 explosionPoint, float radius, float flatDamage, float percentageDamage, float edgeDamageMultiplier, float delaySeconds, int ownerPlayerId, int ignoredPlayerId, bool ignoreWalls, bool applyDamageAuthority, HelldiverExplosionPresentationSize visualSize, HelldiverExplosionPresentationSize soundSize, float soundVolumeMultiplier, Color shellColor, float shellLength, float shellWidth, float shellAngleDegrees) { //IL_0001: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) this.explosionPoint = explosionPoint; this.radius = radius; this.flatDamage = flatDamage; this.percentageDamage = percentageDamage; this.edgeDamageMultiplier = edgeDamageMultiplier; this.delaySeconds = delaySeconds; this.ownerPlayerId = ownerPlayerId; this.ignoredPlayerId = ignoredPlayerId; this.ignoreWalls = ignoreWalls; this.applyDamageAuthority = applyDamageAuthority; this.visualSize = visualSize; this.soundSize = soundSize; this.soundVolumeMultiplier = soundVolumeMultiplier; ((Component)this).transform.position = Vector2.op_Implicit(explosionPoint); if (shellLength > 0f && shellWidth > 0f) { ((Component)this).gameObject.AddComponent().Configure(explosionPoint, shellColor, shellLength, shellWidth, shellAngleDegrees, delaySeconds); } } private void Update() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) elapsed += TimeHandler.deltaTime; if (!detonated && elapsed >= delaySeconds) { detonated = true; PlayDetonationPresentation(); if (applyDamageAuthority) { HelldiverStrikeController.ApplyRadialDamage(explosionPoint, radius, flatDamage, percentageDamage, edgeDamageMultiplier, ownerPlayerId, ignoreWalls, ignoredPlayerId); } } if (detonated && elapsed >= delaySeconds + 0.2f) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void PlayDetonationPresentation() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) HelldiverExplosionPresentation.Play(visualSize, explosionPoint, radius, soundSize, soundVolumeMultiplier); } } internal sealed class HelldiverEagleBombPayload : MonoBehaviour { private static readonly Color BombBodyColor = new Color(0.56f, 0.58f, 0.6f, 1f); private static readonly Color BombGlowColor = new Color(0.96f, 0.66f, 0.34f, 1f); private const float BombVisualLengthScaleMultiplier = 3f; private const float BombVisualWidthScaleMultiplier = 4f; private const float ExplosionVisualScaleMultiplier = 2f; private Vector2 explosionPoint; private float radius; private float flatDamage; private float percentageDamage; private float edgeDamageMultiplier; private float delaySeconds; private int ownerPlayerId; private int ignoredPlayerId = -1; private bool ignoreWalls; private bool applyDamageAuthority; private float elapsed; private bool detonated; private HelldiverExplosionPresentationSize visualSize; private HelldiverExplosionPresentationSize soundSize; private float soundVolumeMultiplier; internal void Configure(Vector2 explosionPoint, Vector2 surfaceNormal, float radius, float flatDamage, float percentageDamage, float edgeDamageMultiplier, float delaySeconds, int ownerPlayerId, int ignoredPlayerId, bool ignoreWalls, bool applyDamageAuthority, HelldiverExplosionPresentationSize visualSize, HelldiverExplosionPresentationSize soundSize, float soundVolumeMultiplier, float shellLength, float shellWidth) { //IL_0001: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_00a4: Unknown result type (might be due to invalid IL or missing references) this.explosionPoint = explosionPoint; this.radius = radius; this.flatDamage = flatDamage; this.percentageDamage = percentageDamage; this.edgeDamageMultiplier = edgeDamageMultiplier; this.delaySeconds = delaySeconds; this.ownerPlayerId = ownerPlayerId; this.ignoredPlayerId = ignoredPlayerId; this.ignoreWalls = ignoreWalls; this.applyDamageAuthority = applyDamageAuthority; this.visualSize = visualSize; this.soundSize = soundSize; this.soundVolumeMultiplier = soundVolumeMultiplier; ((Component)this).transform.position = Vector2.op_Implicit(explosionPoint); ((Component)this).gameObject.AddComponent().Configure(explosionPoint, (((Vector2)(ref surfaceNormal)).sqrMagnitude > 0.0001f) ? ((Vector2)(ref surfaceNormal)).normalized : Vector2.up, BombBodyColor, BombGlowColor, shellLength * 3f, shellWidth * 4f, delaySeconds); } private void Update() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) elapsed += TimeHandler.deltaTime; if (!detonated && elapsed >= delaySeconds) { detonated = true; PlayDetonationPresentation(); if (applyDamageAuthority) { HelldiverStrikeController.ApplyRadialDamage(explosionPoint, radius, flatDamage, percentageDamage, edgeDamageMultiplier, ownerPlayerId, ignoreWalls, ignoredPlayerId); } } if (detonated && elapsed >= delaySeconds + 0.2f) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void PlayDetonationPresentation() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) HelldiverExplosionPresentation.Play(visualSize, explosionPoint, radius * 2f, HelldiverExplosionPresentationSize.Medium, soundVolumeMultiplier); } } internal sealed class HelldiverEmbeddedBombVisual : MonoBehaviour { private Vector2 point; private Vector2 surfaceNormal; private float length; private float width; private float lifetime; private float elapsed; private Color bodyColor; private Color glowColor; private LineRenderer? bodyRenderer; private Material? bodyMaterial; private LineRenderer? glowRenderer; private Material? glowMaterial; internal void Configure(Vector2 point, Vector2 surfaceNormal, Color bodyColor, Color glowColor, float length, float width, float lifetime) { //IL_0001: 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_0008: 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) //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_0016: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) this.point = point; this.surfaceNormal = surfaceNormal; this.bodyColor = bodyColor; this.glowColor = glowColor; this.length = Mathf.Max(0.01f, length); this.width = Mathf.Max(0.01f, width); this.lifetime = Mathf.Max(0.01f, lifetime); ((Component)this).transform.position = Vector2.op_Implicit(point); bodyRenderer = CreateRenderer("Body", ref bodyMaterial, 1414); glowRenderer = CreateRenderer("Glow", ref glowMaterial, 1413); RenderBomb(1f); } private void Update() { elapsed += TimeHandler.deltaTime; float alpha = Mathf.Clamp01(1f - elapsed / lifetime); RenderBomb(alpha); } private void OnDestroy() { if (bodyMaterial != null) { Object.Destroy((Object)(object)bodyMaterial); } if (glowMaterial != null) { Object.Destroy((Object)(object)glowMaterial); } } private void RenderBomb(float alpha) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_002c: 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_003c: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: 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_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_010c: 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_014c: Unknown result type (might be due to invalid IL or missing references) //IL_015d: 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) float num = length * 0.5f; Vector2 val = point - surfaceNormal * num; Vector2 val2 = point + surfaceNormal * num; if (bodyRenderer != null) { Color val3 = bodyColor; val3.a = 0.98f * alpha; bodyRenderer.startColor = val3; bodyRenderer.endColor = val3; bodyRenderer.startWidth = width; bodyRenderer.endWidth = width * 0.82f; bodyRenderer.SetPosition(0, Vector2.op_Implicit(val)); bodyRenderer.SetPosition(1, Vector2.op_Implicit(val2)); } if (glowRenderer != null) { Color val4 = glowColor; val4.a = 0.28f * alpha; glowRenderer.startColor = val4; glowRenderer.endColor = new Color(val4.r, val4.g, val4.b, 0f); glowRenderer.startWidth = width * 1.7f; glowRenderer.endWidth = width * 0.9f; glowRenderer.SetPosition(0, Vector2.op_Implicit(val)); glowRenderer.SetPosition(1, Vector2.op_Implicit(val2)); } } private LineRenderer CreateRenderer(string childName, ref Material? material, int sortingOrder) { //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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown GameObject val = new GameObject(childName); val.transform.SetParent(((Component)this).transform, false); material = new Material(Shader.Find("Sprites/Default")); LineRenderer obj = val.AddComponent(); ((Renderer)obj).material = material; obj.positionCount = 2; obj.useWorldSpace = true; obj.numCapVertices = 12; obj.numCornerVertices = 12; obj.textureMode = (LineTextureMode)0; obj.alignment = (LineAlignment)0; ((Renderer)obj).sortingOrder = sortingOrder; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; return obj; } } internal sealed class HelldiverEffect : MonoBehaviour { private sealed class ThrowProfile { internal float InitialSpeed { get; } internal float Gravity { get; } internal ThrowProfile(float initialSpeed, float gravity) { InitialSpeed = initialSpeed; Gravity = gravity; } } private const float OrbitalCallInReductionPerUpgrade = 0.4f; private const float SentryTargetingSpeedBonusPerUpgrade = 0.5f; private const float SentryAmmoBonusPerUpgrade = 0.5f; private const float SentryHealthBonusPerUpgrade = 1.5f; private readonly Dictionary ownedCounts = new Dictionary(); private readonly Dictionary cooldownReadyTimes = new Dictionary(); private readonly Dictionary remainingUses = new Dictionary(); private readonly List currentInput = new List(); private readonly List ownedTypesCache = new List(); private readonly List hudEntries = new List(); private CharacterData? ownerData; private Player? ownerPlayer; private GeneralInput? input; private GM_ArmsRace? hookedGameMode; private HelldiverHud? hud; private HelldiverReadyGlow? readyGlow; private HelldiverBeacon? pendingBeacon; private double eagleRearmReadyTime = double.NegativeInfinity; private bool eagleRearmPending; private bool ownedTypesDirty = true; private float inputExpireTime; internal int EntryCount { get; set; } internal int ExpandedWeaponsBayCount { get; set; } internal int TargetingSoftwareUpgradeCount { get; set; } internal int SentryTargetingSpeedUpgradeCount { get; set; } internal int SentryAmmoUpgradeCount { get; set; } internal int SentryHealthUpgradeCount { get; set; } internal HelldiverStratagemType ArmedType { get; private set; } internal bool IsNeutral { get { if (EntryCount <= 0 && ownedCounts.Count <= 0 && ExpandedWeaponsBayCount <= 0 && TargetingSoftwareUpgradeCount <= 0 && SentryTargetingSpeedUpgradeCount <= 0 && SentryAmmoUpgradeCount <= 0) { return SentryHealthUpgradeCount <= 0; } return false; } } internal bool IsEmpty => IsNeutral; internal int OwnedStratagemCount => ownedCounts.Count; internal bool HasOwnedStratagem(HelldiverStratagemType type) { if (ownedCounts.TryGetValue(type, out var value)) { return value > 0; } return false; } internal int GetRemainingUsesForDisplay(HelldiverStratagemType type) { return GetRemainingUses(type); } internal bool HasAnyOwnedOrbitalStratagem() { foreach (HelldiverStratagemType ownedType in GetOwnedTypes()) { if (HelldiverClassRegistry.IsOrbitalStratagem(ownedType)) { return true; } } return false; } internal bool HasAnyOwnedLimitedUseEagleStratagem() { foreach (HelldiverStratagemType ownedType in GetOwnedTypes()) { if (HelldiverClassRegistry.IsLimitedUseEagleStratagem(ownedType)) { return true; } } return false; } internal bool HasAnyOwnedSentryStratagem() { foreach (HelldiverStratagemType ownedType in GetOwnedTypes()) { if (HelldiverClassRegistry.IsSentryStratagem(ownedType)) { return true; } } return false; } internal float GetSentryTargetingSpeedMultiplier() { return 1f + (float)Mathf.Max(0, SentryTargetingSpeedUpgradeCount) * 0.5f; } internal float GetSentryAmmoMultiplier() { return 1f + (float)Mathf.Max(0, SentryAmmoUpgradeCount) * 0.5f; } internal float GetSentryHealthMultiplier() { return 1f + (float)Mathf.Max(0, SentryHealthUpgradeCount) * 1.5f; } private void OnEnable() { ResolveOwner(); TryHookRoundReset(); } private void Start() { ResolveOwner(); TryHookRoundReset(); UpdateLocalVisuals(); } private void Update() { ResolveOwner(); TryHookRoundReset(); UpdateTimedState(); UpdateInput(); UpdateLocalVisuals(); } private void OnDisable() { UnhookRoundReset(); } private void OnDestroy() { UnhookRoundReset(); if (readyGlow != null) { Object.Destroy((Object)(object)readyGlow); } if (hud != null) { Object.Destroy((Object)(object)hud); } } internal void AddStratagem(HelldiverStratagemType type) { if (type != 0) { ownedCounts[type] = 1; ownedTypesDirty = true; if (!cooldownReadyTimes.ContainsKey(type)) { cooldownReadyTimes[type] = 0.0; } HelldiverClassRegistry.GetDefinition(type); int usesPerRound = GetUsesPerRound(type); if (usesPerRound > 0) { remainingUses[type] = usesPerRound; } } } internal void RemoveStratagem(HelldiverStratagemType type) { if (ownedCounts.ContainsKey(type)) { ownedCounts.Remove(type); ownedTypesDirty = true; cooldownReadyTimes.Remove(type); remainingUses.Remove(type); if (ArmedType == type) { ArmedType = HelldiverStratagemType.None; } } } internal void SynchronizeCardState(bool hasEntryCard, bool hasExpandedWeaponsBay, bool hasTargetingSoftwareUpgrade, int sentryTargetingSpeedUpgradeCount, int sentryAmmoUpgradeCount, int sentryHealthUpgradeCount, ISet ownedStratagems) { List list = new List(GetOwnedTypes()); int num = (hasExpandedWeaponsBay ? 1 : 0) - ExpandedWeaponsBayCount; EntryCount = (hasEntryCard ? 1 : 0); ExpandedWeaponsBayCount = (hasExpandedWeaponsBay ? 1 : 0); TargetingSoftwareUpgradeCount = (hasTargetingSoftwareUpgrade ? 1 : 0); SentryTargetingSpeedUpgradeCount = Mathf.Max(0, sentryTargetingSpeedUpgradeCount); SentryAmmoUpgradeCount = Mathf.Max(0, sentryAmmoUpgradeCount); SentryHealthUpgradeCount = Mathf.Max(0, sentryHealthUpgradeCount); for (int i = 0; i < list.Count; i++) { HelldiverStratagemType helldiverStratagemType = list[i]; if (!ownedStratagems.Contains(helldiverStratagemType)) { RemoveStratagem(helldiverStratagemType); } } foreach (HelldiverStratagemType ownedStratagem in ownedStratagems) { if (!list.Contains(ownedStratagem)) { AddStratagem(ownedStratagem); } } if (num != 0) { for (int j = 0; j < list.Count; j++) { HelldiverStratagemType helldiverStratagemType2 = list[j]; if (ownedStratagems.Contains(helldiverStratagemType2) && HelldiverClassRegistry.IsLimitedUseEagleStratagem(helldiverStratagemType2)) { remainingUses[helldiverStratagemType2] = Mathf.Clamp(GetRemainingUses(helldiverStratagemType2) + num, 0, GetUsesPerRound(helldiverStratagemType2)); } } } foreach (HelldiverStratagemType ownedType in GetOwnedTypes()) { if (GetUsesPerRound(ownedType) > 0) { remainingUses[ownedType] = Mathf.Clamp(GetRemainingUses(ownedType), 0, GetUsesPerRound(ownedType)); } } } internal bool TryHijackBlock() { ResolveOwner(); if (ArmedType == HelldiverStratagemType.None || ownerData == null || ownerPlayer == null || ownerData.view == null || !ownerData.view.IsMine || ownerData.dead) { return false; } if (!CanUse(ArmedType)) { ArmedType = HelldiverStratagemType.None; return false; } ThrowArmedStratagem(); return true; } private void ResolveOwner() { if (ownerData == null) { ownerData = ((Component)this).GetComponentInParent(); } if (ownerPlayer == null) { ownerPlayer = ((Component)this).GetComponentInParent(); } if (input == null) { input = ((Component)this).GetComponentInParent(); } } private void UpdateInput() { ResolveOwner(); if (ownerData == null || ownerData.view == null || !ownerData.view.IsMine || ownerData.dead || ownerData.playerActions == null) { return; } if (currentInput.Count > 0 && Time.unscaledTime >= inputExpireTime) { currentInput.Clear(); } if (!TryReadDirection(out var direction)) { return; } IReadOnlyList ownedTypes = GetOwnedTypes(); currentInput.Add(direction); inputExpireTime = Time.unscaledTime + 1.35f; if (HelldiverClassRegistry.TryResolveExactMatch(currentInput, ownedTypes, out var type)) { if (CanUse(type)) { if (type == HelldiverStratagemType.EagleRearm) { ActivateInstantStratagem(type); } else { ArmedType = type; } } currentInput.Clear(); } else if (!HelldiverClassRegistry.IsPrefixOfAnyOwned(currentInput, ownedTypes)) { currentInput.Clear(); } } private IReadOnlyList GetOwnedTypes() { if (!ownedTypesDirty) { return ownedTypesCache; } ownedTypesCache.Clear(); foreach (HelldiverStratagemType allStratagem in HelldiverClassRegistry.AllStratagems) { if (ownedCounts.TryGetValue(allStratagem, out var value) && value > 0) { ownedTypesCache.Add(allStratagem); } } ownedTypesDirty = false; return ownedTypesCache; } private bool TryReadDirection(out HelldiverInputDirection direction) { return DolyModSettings.TryReadHelldiverDirection(ownerData?.playerActions, out direction); } private void ThrowArmedStratagem() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) if (ownerData != null && ownerPlayer != null && ownerData.view != null) { HelldiverStratagemType armedType = ArmedType; HelldiverClassRegistry.GetDefinition(armedType); if (!CanUse(armedType)) { ArmedType = HelldiverStratagemType.None; return; } Vector2 throwDirection = GetThrowDirection(); ThrowProfile throwProfile = ResolveStockThrowProfile(); Vector2 position = ResolveSpawnPosition(throwDirection); Vector2 velocity = throwDirection * throwProfile.InitialSpeed; int seed = Random.Range(1, int.MaxValue); HelldiverRuntime.GetOrAdd(ownerPlayer).BroadcastSpawnHelldiverBeacon(armedType, position, velocity, throwProfile.Gravity, GetCallInDelaySeconds(armedType), seed, ownerPlayer.playerID); ArmedType = HelldiverStratagemType.None; currentInput.Clear(); } } private Vector2 GetThrowDirection() { //IL_0011: 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_0016: Unknown result type (might be due to invalid IL or missing references) //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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ownerData?.aimDirection ?? Vector3.zero; Vector2 val2; if (((Vector3)(ref val)).sqrMagnitude > 0.0001f) { val2 = Vector2.op_Implicit(val); return ((Vector2)(ref val2)).normalized; } val = input?.lastAimDirection ?? Vector3.zero; if (((Vector3)(ref val)).sqrMagnitude > 0.0001f) { val2 = Vector2.op_Implicit(val); return ((Vector2)(ref val2)).normalized; } Player? obj = ownerPlayer; if (!(((obj != null) ? ((Component)obj).transform.localScale.x : 1f) < 0f)) { return Vector2.right; } return Vector2.left; } private Vector2 ResolveSpawnPosition(Vector2 throwDirection) { //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) //IL_000e: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: 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) Vector2 val = ((ownerData != null) ? Vector2.op_Implicit(ownerData.hand.position) : Vector2.op_Implicit(((Component)this).transform.position)); Vector2 val2 = Vector2.up * 0.08f; Vector2 normalized = default(Vector2); ((Vector2)(ref normalized))..ctor(throwDirection.x, Mathf.Max(throwDirection.y, -0.2f)); if (((Vector2)(ref normalized)).sqrMagnitude > 0.0001f) { normalized = ((Vector2)(ref normalized)).normalized; } Vector2 val3 = val + normalized * 0.45f + val2; CharacterData? obj = ownerData; Bounds? obj2; if (obj == null) { obj2 = null; } else { Collider2D mainCol = obj.mainCol; obj2 = ((mainCol != null) ? new Bounds?(mainCol.bounds) : null); } Bounds? val4 = obj2; if (val4.HasValue) { Bounds value = val4.Value; float num = ((Bounds)(ref value)).min.y + 0.18f + 0.04f; if (val3.y < num) { val3.y = num; } } return val3; } private ThrowProfile ResolveStockThrowProfile() { ThrowProfile throwProfile = new ThrowProfile(22f, 30f); ProjectilesToSpawn[] array = ownerData?.weaponHandler?.gun?.projectiles; GameObject val = ((array != null && array.Length > 0) ? array[0].objectToSpawn : null); if (val == null) { return throwProfile; } MoveTransform component = val.GetComponent(); if (component == null) { return throwProfile; } float num = ((Vector3)(ref component.localForce)).magnitude; if (num <= 0.0001f) { num = throwProfile.InitialSpeed; } float gravity = component.gravity; if (gravity <= 0.0001f) { gravity = throwProfile.Gravity; } return new ThrowProfile(num, gravity); } private bool CanUse(HelldiverStratagemType type) { if (!ownedCounts.TryGetValue(type, out var value) || value <= 0) { return false; } if (GetUsesPerRound(type) > 0 && GetRemainingUses(type) <= 0) { return false; } return GetCooldownRemaining(type) <= 0.0001f; } private float GetCooldownRemaining(HelldiverStratagemType type) { if (!cooldownReadyTimes.TryGetValue(type, out var value)) { return 0f; } double num = (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time); return Mathf.Max(0f, (float)(value - num)); } private int GetRemainingUses(HelldiverStratagemType type) { if (!remainingUses.TryGetValue(type, out var value)) { return GetUsesPerRound(type); } return value; } private int GetUsesPerRound(HelldiverStratagemType type) { int num = HelldiverClassRegistry.GetDefinition(type).UsesPerRound; if (num <= 0) { return 0; } if (HelldiverClassRegistry.IsLimitedUseEagleStratagem(type)) { num += ExpandedWeaponsBayCount; } return Mathf.Max(0, num); } private float GetCallInDelaySeconds(HelldiverStratagemType type) { float num = HelldiverClassRegistry.GetDefinition(type).CallInTimeSeconds; if (num <= 0f || !HelldiverClassRegistry.IsOrbitalStratagem(type)) { return num; } for (int i = 0; i < TargetingSoftwareUpgradeCount; i++) { num *= 0.4f; } return Mathf.Max(0f, num); } internal void RefreshExpandedWeaponsBay(int delta) { if (delta == 0) { return; } foreach (HelldiverStratagemType ownedType in GetOwnedTypes()) { if (HelldiverClassRegistry.IsLimitedUseEagleStratagem(ownedType)) { int value = Mathf.Clamp(GetRemainingUses(ownedType) + delta, 0, GetUsesPerRound(ownedType)); remainingUses[ownedType] = value; } } } private void UpdateTimedState() { if (!eagleRearmPending || (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time) < eagleRearmReadyTime) { return; } eagleRearmPending = false; foreach (HelldiverStratagemType ownedType in GetOwnedTypes()) { if (HelldiverClassRegistry.IsLimitedUseEagleStratagem(ownedType)) { remainingUses[ownedType] = GetUsesPerRound(ownedType); } } } private void ActivateEagleRearm() { double val = (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time) + (double)HelldiverClassRegistry.GetDefinition(HelldiverStratagemType.EagleRearm).CooldownSeconds; eagleRearmReadyTime = Math.Max(eagleRearmReadyTime, val); eagleRearmPending = true; foreach (HelldiverStratagemType ownedType in GetOwnedTypes()) { if (HelldiverClassRegistry.IsLimitedUseEagleStratagem(ownedType)) { cooldownReadyTimes[ownedType] = Math.Max(GetCooldownReadyTime(ownedType), val); } } } private void ActivateInstantStratagem(HelldiverStratagemType type) { if (ownedCounts.TryGetValue(type, out var value) && value > 0) { HelldiverStratagemDefinition definition = HelldiverClassRegistry.GetDefinition(type); cooldownReadyTimes[type] = (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time) + (double)definition.CooldownSeconds; if (GetUsesPerRound(type) > 0) { remainingUses[type] = Mathf.Max(0, GetRemainingUses(type) - 1); } if (type == HelldiverStratagemType.EagleRearm) { ActivateEagleRearm(); } ArmedType = HelldiverStratagemType.None; } } private double GetCooldownReadyTime(HelldiverStratagemType type) { if (!cooldownReadyTimes.TryGetValue(type, out var value)) { return 0.0; } return value; } private void TryHookRoundReset() { if (hookedGameMode == null && GM_ArmsRace.instance != null) { hookedGameMode = GM_ArmsRace.instance; GM_ArmsRace? obj = hookedGameMode; obj.pointOverAction = (Action)Delegate.Combine(obj.pointOverAction, new Action(HandlePointOver)); } } private void UnhookRoundReset() { if (hookedGameMode != null) { GM_ArmsRace? obj = hookedGameMode; obj.pointOverAction = (Action)Delegate.Remove(obj.pointOverAction, new Action(HandlePointOver)); hookedGameMode = null; } } internal void HandlePointOver() { currentInput.Clear(); ArmedType = HelldiverStratagemType.None; if (pendingBeacon != null) { pendingBeacon.CancelAndDestroy(); pendingBeacon = null; } HelldiverWorldCleanup.CleanupPointObjects(); eagleRearmPending = false; eagleRearmReadyTime = double.NegativeInfinity; } internal void RefillLimitedUses() { foreach (HelldiverStratagemType ownedType in GetOwnedTypes()) { if (GetUsesPerRound(ownedType) > 0) { remainingUses[ownedType] = GetUsesPerRound(ownedType); } } } internal void HandleRoundOver() { foreach (HelldiverStratagemType ownedType in GetOwnedTypes()) { cooldownReadyTimes[ownedType] = 0.0; } RefillLimitedUses(); currentInput.Clear(); ArmedType = HelldiverStratagemType.None; if (pendingBeacon != null) { pendingBeacon.CancelAndDestroy(); pendingBeacon = null; } eagleRearmPending = false; eagleRearmReadyTime = double.NegativeInfinity; } private void UpdateLocalVisuals() { //IL_0094: 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) ResolveOwner(); if (ownerData?.view != null && ownerData.view.IsMine) { if (readyGlow == null) { readyGlow = ((Component)this).gameObject.GetOrAddComponent(); } readyGlow.Bind(ownerData); readyGlow.SetState(ArmedType != HelldiverStratagemType.None, (Color)((ArmedType == HelldiverStratagemType.None) ? new Color(0.48f, 0.86f, 1f, 1f) : HelldiverClassRegistry.GetDefinition(ArmedType).Color)); if (hud == null) { hud = ((Component)this).gameObject.GetOrAddComponent(); } IReadOnlyList ownedTypes = GetOwnedTypes(); hudEntries.Clear(); for (int i = 0; i < ownedTypes.Count; i++) { HelldiverStratagemType helldiverStratagemType = ownedTypes[i]; HelldiverStratagemDefinition definition = HelldiverClassRegistry.GetDefinition(helldiverStratagemType); float cooldownRemaining = GetCooldownRemaining(helldiverStratagemType); hudEntries.Add(new HelldiverHudEntryState(helldiverStratagemType, definition.DisplayName, definition.Code, helldiverStratagemType == ArmedType, cooldownRemaining > 0.0001f, RoundCooldownForDisplay(cooldownRemaining), GetRemainingUses(helldiverStratagemType), GetUsesPerRound(helldiverStratagemType))); } hud.SetState(ownedTypes.Count > 0, hudEntries, currentInput); } } private static float RoundCooldownForDisplay(float cooldownRemaining) { if (cooldownRemaining <= 0.0001f) { return 0f; } return Mathf.Round(cooldownRemaining * 10f) / 10f; } internal void BroadcastExecute(HelldiverStratagemType type, Vector2 point, Vector2 runDirection, int seed, double executeTime) { //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) if (ownerData?.view != null) { if (type == HelldiverStratagemType.EagleRearm) { ActivateEagleRearm(); } else if (ownerPlayer != null) { HelldiverRuntime.GetOrAdd(ownerPlayer).BroadcastExecute(type, point, runDirection, seed, executeTime); } } } internal void BroadcastBeaconDeployment(HelldiverStratagemType type, int beaconSeed, Vector2 settledPosition, int stuckPlayerId, Vector2 stuckOffset, double deployTime, double executeTime) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) ResolveOwner(); if (ownerPlayer != null) { HelldiverRuntime.GetOrAdd(ownerPlayer).BroadcastDeployHelldiverBeacon(type, beaconSeed, settledPosition, stuckPlayerId, stuckOffset, deployTime, executeTime); } } internal void BroadcastBeaconCancellation(int beaconSeed) { ResolveOwner(); if (ownerPlayer != null) { HelldiverRuntime.GetOrAdd(ownerPlayer).BroadcastCancelHelldiverBeacon(beaconSeed); } } internal void BroadcastGasCloudPayload(Vector2 center, float radius, float duration, float tickInterval, float flatDamage, float percentageDamage, float slowAmount, int damageOwnerPlayerId, Color flashColor) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) ResolveOwner(); if (ownerPlayer != null) { HelldiverRuntime.GetOrAdd(ownerPlayer).BroadcastGasCloudPayload(center, radius, duration, tickInterval, flatDamage, percentageDamage, slowAmount, damageOwnerPlayerId, flashColor); } } internal void BroadcastEmsFieldPayload(Vector2 center, float radius, float duration, float initialStunDuration, float slowAmount, Color flashColor) { //IL_001a: 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) ResolveOwner(); if (ownerPlayer != null) { HelldiverRuntime.GetOrAdd(ownerPlayer).BroadcastEmsFieldPayload(center, radius, duration, initialStunDuration, slowAmount, flashColor); } } internal void RegisterPendingBeacon(HelldiverBeacon beacon) { if (!((Object)(object)pendingBeacon == (Object)(object)beacon)) { HelldiverBeacon helldiverBeacon = pendingBeacon; pendingBeacon = beacon; if (helldiverBeacon != null && (Object)(object)helldiverBeacon != (Object)(object)beacon) { helldiverBeacon.CancelAndDestroy(); } } } internal void NotifyBeaconDeployed(HelldiverBeacon beacon, HelldiverStratagemType type, double deployTime) { if ((Object)(object)pendingBeacon == (Object)(object)beacon) { pendingBeacon = null; } if (ownedCounts.TryGetValue(type, out var value) && value > 0) { HelldiverStratagemDefinition definition = HelldiverClassRegistry.GetDefinition(type); cooldownReadyTimes[type] = deployTime + (double)definition.CooldownSeconds; if (GetUsesPerRound(type) > 0) { remainingUses[type] = Mathf.Max(0, GetRemainingUses(type) - 1); } } } internal bool TryApplyAuthoritativeBeaconDeployment(int beaconSeed, Vector2 settledPosition, int stuckPlayerId, Vector2 stuckOffset, double deployTime, double executeTime) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (pendingBeacon == null || !pendingBeacon.MatchesSeed(beaconSeed)) { return false; } pendingBeacon.ApplyAuthoritativeDeployment(settledPosition, stuckPlayerId, stuckOffset, deployTime, executeTime); return true; } internal bool TryCancelPendingBeacon(int beaconSeed) { if (pendingBeacon == null || !pendingBeacon.MatchesSeed(beaconSeed)) { return false; } pendingBeacon.CancelAndDestroy(); pendingBeacon = null; return true; } internal void NotifyBeaconDestroyed(HelldiverBeacon beacon) { if ((Object)(object)pendingBeacon == (Object)(object)beacon) { pendingBeacon = null; } } } internal sealed class HelldiverEmsField : MonoBehaviour { private const float GrowthDurationSeconds = 0.5f; private static readonly Color OutlineColor = new Color(0.52f, 0.89f, 1f, 0.9f); private static readonly Color FillColor = new Color(0.36f, 0.72f, 1f, 0.12f); private readonly HashSet stunnedPlayers = new HashSet(); private float targetRadius; private float duration; private float initialStunDuration; private float slowAmount; private float elapsed; private double startTime; private bool useSyncedClock; private Transform? visualRoot; internal void Configure(Vector2 center, float radius, float duration, float initialStunDuration, float slowAmount, double startTime) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_0090: 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) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) targetRadius = Mathf.Max(0.25f, radius); this.duration = Mathf.Max(0.1f, duration); this.initialStunDuration = Mathf.Max(0f, initialStunDuration); this.slowAmount = Mathf.Clamp01(slowAmount); this.startTime = startTime; useSyncedClock = true; elapsed = ResolveElapsedSeconds(); ((Component)this).transform.position = Vector2.op_Implicit(center); GameObject val = new GameObject("VisualRoot"); val.transform.SetParent(((Component)this).transform, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one * 0.08f; visualRoot = val.transform; HelldiverCircularFieldPresentation.Spawn(visualRoot, radius, duration, OutlineColor, FillColor, elapsed); } private void Update() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) elapsed = (useSyncedClock ? ResolveElapsedSeconds() : (elapsed + TimeHandler.deltaTime)); float num = EvaluateGrowth(); float currentRadius = Mathf.Max(0.01f, targetRadius * num); if (visualRoot != null) { visualRoot.localScale = Vector3.one * Mathf.Lerp(0.08f, 1f, num); } AffectPlayers(currentRadius); if (elapsed >= duration) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void AffectPlayers(float currentRadius) { List list = PlayerManager.instance?.players; if (list == null) { return; } foreach (Player item in list) { if (!ShouldApplyGameplayToPlayer(item) || !IsPlayerInsideField(item, currentRadius)) { continue; } if (initialStunDuration > 0f && stunnedPlayers.Add(item.playerID)) { CharacterData data = item.data; if (data != null) { StunHandler stunHandler = data.stunHandler; if (stunHandler != null) { stunHandler.AddStun(initialStunDuration); } } } CharacterData data2 = item.data; if (data2 != null) { CharacterStatModifiers stats = data2.stats; if (stats != null) { stats.AddSlowAddative(slowAmount, slowAmount, false); } } } } private bool IsPlayerInsideField(Player? player, float currentRadius) { //IL_0056: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0069: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) if (player == null || player.data == null || player.data.dead || player.data.healthHandler == null) { return false; } Bounds val = (Bounds)((player.data.mainCol != null) ? player.data.mainCol.bounds : new Bounds(((Component)player).transform.position, Vector3.one)); return Vector2.Distance(Vector2.op_Implicit(((Bounds)(ref val)).ClosestPoint(((Component)this).transform.position)), Vector2.op_Implicit(((Component)this).transform.position)) <= currentRadius; } private float EvaluateGrowth() { float num = Mathf.Clamp01(elapsed / 0.5f); return 1f - Mathf.Pow(1f - num, 2.15f); } private float ResolveElapsedSeconds() { double num = (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time); return Mathf.Max(0f, (float)(num - startTime)); } private static bool ShouldApplyGameplayToPlayer(Player? player) { if (player?.data == null || player.data.dead || player.data.healthHandler == null) { return false; } if (!PhotonNetwork.OfflineMode && player.data.view != null) { return player.data.view.IsMine; } return true; } } internal static class HelldiverCircularFieldPresentation { internal static void Spawn(Transform parent, float radius, float duration, Color outlineColor, Color fillColor, float initialElapsedSeconds = 0f) { //IL_0005: 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("DOLY_FieldCircleVisual"); val.transform.SetParent(parent, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.AddComponent().Configure(radius, duration, outlineColor, fillColor, initialElapsedSeconds); } } internal sealed class HelldiverFieldCircleVisual : MonoBehaviour { private const int SegmentCount = 48; private static Mesh? sharedDiscMesh; private readonly Vector3[] outerPoints = (Vector3[])(object)new Vector3[48]; private float radius; private float duration; private float elapsed; private Color outlineColor; private Color fillColor; private LineRenderer? outlineRenderer; private Material? outlineMaterial; private MeshRenderer? fillRenderer; private Material? fillMaterial; internal void Configure(float radius, float duration, Color outlineColor, Color fillColor, float initialElapsedSeconds) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_002c: Unknown result type (might be due to invalid IL or missing references) this.radius = Mathf.Max(0.25f, radius); this.duration = Mathf.Max(0.1f, duration); this.outlineColor = outlineColor; this.fillColor = fillColor; elapsed = Mathf.Clamp(initialElapsedSeconds, 0f, this.duration); outlineRenderer = CreateRenderer("Outline", ref outlineMaterial, 1404); fillRenderer = CreateFillRenderer(ref fillMaterial, 1403); Render(Mathf.Clamp01(elapsed / this.duration)); } private void Update() { elapsed += TimeHandler.deltaTime; Render(Mathf.Clamp01(elapsed / duration)); if (elapsed >= duration) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void OnDestroy() { if (outlineMaterial != null) { Object.Destroy((Object)(object)outlineMaterial); } if (fillMaterial != null) { Object.Destroy((Object)(object)fillMaterial); } } private void Render(float lifetimeProgress) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) if (outlineRenderer != null && fillRenderer != null && fillMaterial != null) { float num = 0.5f + 0.5f * Mathf.Sin(Time.time * 5f); float num2 = Mathf.Lerp(1f, 0.48f, lifetimeProgress); float num3 = radius * (0.92f + 0.05f * num); Vector3 val = default(Vector3); for (int i = 0; i < 48; i++) { float num4 = (float)i / 48f * MathF.PI * 2f; ((Vector3)(ref val))..ctor(Mathf.Cos(num4), Mathf.Sin(num4), 0f); outerPoints[i] = val * num3; } Color val2 = outlineColor; val2.a *= num2; outlineRenderer.widthMultiplier = Mathf.Clamp(radius * 0.075f, 0.08f, 0.32f); outlineRenderer.startColor = val2; outlineRenderer.endColor = val2; outlineRenderer.SetPositions(outerPoints); Color color = fillColor; color.a *= num2; fillMaterial.color = color; float num5 = radius * (0.89f + 0.04f * num); ((Component)fillRenderer).transform.localScale = new Vector3(num5, num5, 1f); } } private LineRenderer CreateRenderer(string childName, ref Material? material, int sortingOrder) { //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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown GameObject val = new GameObject(childName); val.transform.SetParent(((Component)this).transform, false); material = new Material(Shader.Find("Sprites/Default")); LineRenderer obj = val.AddComponent(); ((Renderer)obj).material = material; obj.useWorldSpace = false; obj.loop = true; obj.positionCount = 48; obj.numCapVertices = 8; obj.numCornerVertices = 8; obj.alignment = (LineAlignment)0; obj.textureMode = (LineTextureMode)0; ((Renderer)obj).sortingOrder = sortingOrder; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; return obj; } private MeshRenderer CreateFillRenderer(ref Material? material, int sortingOrder) { //IL_0005: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Fill"); val.transform.SetParent(((Component)this).transform, false); material = new Material(Shader.Find("Sprites/Default")); val.AddComponent().sharedMesh = GetOrCreateDiscMesh(); MeshRenderer obj = val.AddComponent(); ((Renderer)obj).material = material; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; ((Renderer)obj).sortingOrder = sortingOrder; return obj; } private static Mesh GetOrCreateDiscMesh() { if (sharedDiscMesh == null) { sharedDiscMesh = CreateDiscMesh(); } return sharedDiscMesh; } private static Mesh CreateDiscMesh() { //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_0011: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) Mesh val = new Mesh { name = "DOLY_FieldDisc" }; Vector3[] array = (Vector3[])(object)new Vector3[49]; int[] array2 = new int[144]; array[0] = Vector3.zero; for (int i = 0; i < 48; i++) { float num = (float)i / 48f * MathF.PI * 2f; array[i + 1] = new Vector3(Mathf.Cos(num), Mathf.Sin(num), 0f); int num2 = i * 3; array2[num2] = 0; array2[num2 + 1] = i + 1; array2[num2 + 2] = ((i == 47) ? 1 : (i + 2)); } val.vertices = array; val.triangles = array2; val.RecalculateBounds(); val.RecalculateNormals(); return val; } } internal enum HelldiverExplosionPresentationSize { Small, Medium, Large } internal static class HelldiverExplosionPresentation { private const float GlobalExplosionVolumeMultiplier = 0.5f; private const float VolumeBoostMultiplier = 1.25f; private const StringComparison NameComparison = StringComparison.OrdinalIgnoreCase; private static readonly string[] SmallAudioPrefixes = new string[5] { "SFX_Block_Bombs_Away_Bomb_Explosion_", "SFX_Bullet_Effect_Grow_Explosion_", "SFX_Impact_Environment_Basic_", "SFX_Block_Supernova_Explosion_01", "SFX_Impact_Damage_To_Explosion_Huge_" }; private static readonly string[] MediumAudioPrefixes = new string[5] { "SFX_Bullet_Effect_Grow_Explosion_", "SFX_Impact_Environment_Basic_", "SFX_Block_Supernova_Explosion_01", "SFX_Impact_Damage_To_Explosion_Huge_", "SFX_Block_Bombs_Away_Bomb_Explosion_" }; private static readonly string[] LargeAudioPrefixes = new string[5] { "SFX_Impact_Damage_To_Explosion_Huge_", "SFX_Block_Supernova_Explosion_01", "SFX_Impact_Environment_Basic_", "SFX_Bullet_Effect_Grow_Explosion_", "SFX_Block_Bombs_Away_Bomb_Explosion_" }; private static readonly Dictionary ClipCache = new Dictionary(StringComparer.Ordinal); private static readonly Dictionary PrefabCache = new Dictionary(StringComparer.Ordinal); private static readonly HashSet MissingPrefixes = new HashSet(StringComparer.Ordinal); private static readonly HashSet MissingPrefabs = new HashSet(StringComparer.Ordinal); private static readonly List LoadedClips = new List(); private static readonly List LoadedGameObjects = new List(); private static bool loadedClipPoolBuilt; private static bool loadedGameObjectPoolBuilt; private static bool resourceFallbackBuilt; internal static void Play(HelldiverExplosionPresentationSize visualSize, Vector2 point, float radius, HelldiverExplosionPresentationSize? soundSize = null, float soundVolumeMultiplier = 1f) { //IL_0009: 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) //IL_0018: Unknown result type (might be due to invalid IL or missing references) HelldiverExplosionPresentationSize valueOrDefault = soundSize.GetValueOrDefault(visualSize); TryPlayPrimaryVisual(visualSize, point, radius); TryPlaySmokeOverlay(visualSize, point, radius); TryPlayAudio(valueOrDefault, point, soundVolumeMultiplier); } private static void TryPlayPrimaryVisual(HelldiverExplosionPresentationSize visualSize, Vector2 point, float radius) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) var (prefabName, nominalRadius, scaleBoost, scalingSize) = GetPrimaryVisual(visualSize); TryPlayVisualLayer(prefabName, point, radius, nominalRadius, scaleBoost, scalingSize); } private static void TryPlaySmokeOverlay(HelldiverExplosionPresentationSize visualSize, Vector2 point, float radius) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (visualSize == HelldiverExplosionPresentationSize.Large) { TryPlayVisualLayer("A_Explosion_Timed_Detonation", point, radius * 1.15f, 7f, 1.5f, HelldiverExplosionPresentationSize.Medium); } } private static void TryPlayVisualLayer(string prefabName, Vector2 point, float radius, float nominalRadius, float scaleBoost, HelldiverExplosionPresentationSize scalingSize) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) try { TrySpawnPrefab(prefabName, point, radius, nominalRadius, scaleBoost, scalingSize); } catch (Exception arg) { Debug.LogWarning($"[DOLY] Helldiver explosion VFX failed for '{prefabName}': {arg}"); } } private static void TryPlayAudio(HelldiverExplosionPresentationSize soundSize, Vector2 point, float soundVolumeMultiplier) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) try { PlayRandomClip(GetAudioPrefixes(soundSize), point, GetAudioVolume(soundSize) * Mathf.Max(0f, soundVolumeMultiplier) * 0.5f); } catch (Exception arg) { Debug.LogWarning($"[DOLY] Helldiver explosion audio failed for {soundSize}: {arg}"); } } private static bool TrySpawnPrefab(string prefabName, Vector2 point, float radius, float nominalRadius, float scaleBoost, HelldiverExplosionPresentationSize size) { //IL_0030: 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_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) GameObject prefab = GetPrefab(prefabName); if (prefab == null) { if (MissingPrefabs.Add(prefabName)) { Debug.LogWarning("[DOLY] Helldiver explosion VFX could not resolve prefab '" + prefabName + "'."); } return false; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(point.x, point.y, 0f); GameObject obj = Object.Instantiate(prefab, val, Quaternion.identity); ((Object)obj).name = "DOLY_" + ((Object)prefab).name; float scaleMultiplier = ((nominalRadius <= 0.0001f) ? 1f : Mathf.Clamp(radius / nominalRadius * scaleBoost, GetMinRootScale(size), 3.4f)); ApplyParticlePresentationScale(obj, scaleMultiplier, size); return true; } private static (string PrefabName, float NominalRadius, float ScaleBoost, HelldiverExplosionPresentationSize ScalingSize) GetPrimaryVisual(HelldiverExplosionPresentationSize size) { return size switch { HelldiverExplosionPresentationSize.Small => ("A_Explosion_Bombs_Away", 3.5f, 1.225f, HelldiverExplosionPresentationSize.Small), HelldiverExplosionPresentationSize.Medium => ("A_Explosion_Timed_Detonation", 7f, 1.4f, HelldiverExplosionPresentationSize.Medium), HelldiverExplosionPresentationSize.Large => ("A_Explosion", 18f, 1.575f, HelldiverExplosionPresentationSize.Large), _ => ("A_Explosion", 18f, 1.575f, HelldiverExplosionPresentationSize.Large), }; } private static float GetAudioVolume(HelldiverExplosionPresentationSize size) { return size switch { HelldiverExplosionPresentationSize.Small => 0.82f, HelldiverExplosionPresentationSize.Medium => 0.92f, HelldiverExplosionPresentationSize.Large => 1.05f, _ => 1.05f, }; } private static string[] GetAudioPrefixes(HelldiverExplosionPresentationSize size) { return size switch { HelldiverExplosionPresentationSize.Small => SmallAudioPrefixes, HelldiverExplosionPresentationSize.Medium => MediumAudioPrefixes, HelldiverExplosionPresentationSize.Large => LargeAudioPrefixes, _ => LargeAudioPrefixes, }; } private static float GetMinRootScale(HelldiverExplosionPresentationSize size) { return size switch { HelldiverExplosionPresentationSize.Small => 0.42f, HelldiverExplosionPresentationSize.Medium => 0.7f, HelldiverExplosionPresentationSize.Large => 1.15f, _ => 1f, }; } private static void ApplyParticlePresentationScale(GameObject instance, float scaleMultiplier, HelldiverExplosionPresentationSize size) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_005d: Unknown result type (might be due to invalid IL or missing references) Transform transform = instance.transform; transform.localScale *= scaleMultiplier; Transform[] componentsInChildren = instance.GetComponentsInChildren(true); foreach (Transform val in componentsInChildren) { if (!((Object)(object)val == (Object)(object)instance.transform)) { float childScaleBoost = GetChildScaleBoost(((Object)val).name, size); if (Mathf.Abs(childScaleBoost - 1f) > 0.001f) { val.localScale *= childScaleBoost; } } } ParticleSystem[] componentsInChildren2 = instance.GetComponentsInChildren(true); foreach (ParticleSystem obj in componentsInChildren2) { float particleBoost = GetParticleBoost(((Object)((Component)obj).gameObject).name, size); AmplifyParticleSystem(obj, scaleMultiplier, particleBoost); obj.Play(true); } } private static float GetChildScaleBoost(string childName, HelldiverExplosionPresentationSize size) { if (ContainsAny(childName, "stay", "smoke")) { return size switch { HelldiverExplosionPresentationSize.Small => 1.225f, HelldiverExplosionPresentationSize.Medium => 1.475f, HelldiverExplosionPresentationSize.Large => 1.7f, _ => 1.4f, }; } if (ContainsAny(childName, "burst", "close", "pieces", "spark")) { return size switch { HelldiverExplosionPresentationSize.Small => 1.1f, HelldiverExplosionPresentationSize.Medium => 1.225f, HelldiverExplosionPresentationSize.Large => 1.375f, _ => 1.175f, }; } return 1f; } private static float GetParticleBoost(string particleName, HelldiverExplosionPresentationSize size) { if (ContainsAny(particleName, "stay", "smoke")) { return size switch { HelldiverExplosionPresentationSize.Small => 1.275f, HelldiverExplosionPresentationSize.Medium => 1.575f, HelldiverExplosionPresentationSize.Large => 1.875f, _ => 1.45f, }; } if (ContainsAny(particleName, "burst", "close")) { return size switch { HelldiverExplosionPresentationSize.Small => 1.15f, HelldiverExplosionPresentationSize.Medium => 1.35f, HelldiverExplosionPresentationSize.Large => 1.525f, _ => 1.25f, }; } if (ContainsAny(particleName, "pieces", "spark")) { return size switch { HelldiverExplosionPresentationSize.Small => 1.075f, HelldiverExplosionPresentationSize.Medium => 1.2f, HelldiverExplosionPresentationSize.Large => 1.35f, _ => 1.125f, }; } return 1.1f; } private static void AmplifyParticleSystem(ParticleSystem particleSystem, float baseScaleMultiplier, float particleBoost) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Max(1f, baseScaleMultiplier * particleBoost); MainModule main = particleSystem.main; ((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)0; ((MainModule)(ref main)).startSizeMultiplier = ((MainModule)(ref main)).startSizeMultiplier * num; ((MainModule)(ref main)).startSpeedMultiplier = ((MainModule)(ref main)).startSpeedMultiplier * Mathf.Lerp(1f, num, 0.25f); ShapeModule shape = particleSystem.shape; ((ShapeModule)(ref shape)).scale = ((ShapeModule)(ref shape)).scale * num; ((ShapeModule)(ref shape)).radius = ((ShapeModule)(ref shape)).radius * num; VelocityOverLifetimeModule velocityOverLifetime = particleSystem.velocityOverLifetime; if (((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled) { ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).xMultiplier = ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).xMultiplier * num; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).yMultiplier = ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).yMultiplier * num; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).zMultiplier = ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).zMultiplier * num; } ForceOverLifetimeModule forceOverLifetime = particleSystem.forceOverLifetime; if (((ForceOverLifetimeModule)(ref forceOverLifetime)).enabled) { ((ForceOverLifetimeModule)(ref forceOverLifetime)).xMultiplier = ((ForceOverLifetimeModule)(ref forceOverLifetime)).xMultiplier * num; ((ForceOverLifetimeModule)(ref forceOverLifetime)).yMultiplier = ((ForceOverLifetimeModule)(ref forceOverLifetime)).yMultiplier * num; ((ForceOverLifetimeModule)(ref forceOverLifetime)).zMultiplier = ((ForceOverLifetimeModule)(ref forceOverLifetime)).zMultiplier * num; } NoiseModule noise = particleSystem.noise; if (((NoiseModule)(ref noise)).enabled) { ((NoiseModule)(ref noise)).strengthMultiplier = ((NoiseModule)(ref noise)).strengthMultiplier * Mathf.Lerp(1f, num, 0.4f); ((NoiseModule)(ref noise)).scrollSpeedMultiplier = ((NoiseModule)(ref noise)).scrollSpeedMultiplier * Mathf.Lerp(1f, num, 0.15f); } } private static bool ContainsAny(string name, params string[] fragments) { foreach (string value in fragments) { if (name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } private static GameObject? GetPrefab(string prefabName) { if (PrefabCache.TryGetValue(prefabName, out GameObject value)) { return value; } GameObject val = HelldiverVanillaPrefabResolver.GetLoadedPrefab(prefabName); if (val == null) { EnsureLoadedGameObjectPool(); val = MatchPrefab(prefabName); } if (val == null) { EnsureResourceFallbackPool(); val = MatchPrefab(prefabName); } PrefabCache[prefabName] = val; return val; } private static GameObject? MatchPrefab(string prefabName) { //IL_003c: 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) string prefabName2 = prefabName; GameObject[] array = LoadedGameObjects.Where((GameObject gameObject) => gameObject != null && string.Equals(((Object)gameObject).name, prefabName2, StringComparison.Ordinal)).ToArray(); if (array.Length == 0) { return null; } GameObject[] array2 = array; foreach (GameObject val in array2) { Scene scene = val.scene; if (!((Scene)(ref scene)).IsValid()) { return val; } } return array[0]; } private static void PlayRandomClip(string[] prefixes, Vector2 point, float volume) { //IL_006a: 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) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown AudioClip[] array = Array.Empty(); for (int i = 0; i < prefixes.Length; i++) { array = GetClips(prefixes[i]); if (array.Length != 0) { break; } } if (array.Length == 0) { string text = string.Join(" | ", prefixes); if (MissingPrefixes.Add(text)) { Debug.LogWarning("[DOLY] Helldiver explosion audio could not resolve any AudioClips for '" + text + "'."); } return; } AudioClip val = array[Random.Range(0, array.Length)]; GameObject val2 = new GameObject("DOLY_HelldiverExplosionAudio"); val2.transform.position = new Vector3(point.x, point.y, 0f); AudioSource obj = val2.AddComponent(); obj.spatialBlend = 0f; obj.playOnAwake = false; obj.loop = false; obj.volume = 1f; obj.priority = 32; obj.clip = val; obj.PlayOneShot(val, volume * 1.25f); Object.Destroy((Object)val2, val.length + 0.2f); } private static AudioClip[] GetClips(string prefix) { if (ClipCache.TryGetValue(prefix, out AudioClip[] value)) { return value; } EnsureLoadedClipPool(); value = MatchClips(prefix); if (value.Length == 0) { EnsureResourceFallbackPool(); value = MatchClips(prefix); } ClipCache[prefix] = value; return value; } private static AudioClip[] MatchClips(string prefix) { string prefix2 = prefix; return LoadedClips.Where((AudioClip clip) => clip != null && ((Object)clip).name.StartsWith(prefix2, StringComparison.Ordinal)).OrderBy((AudioClip clip) => ((Object)clip).name, StringComparer.Ordinal).ToArray(); } private static void EnsureLoadedClipPool() { if (!loadedClipPoolBuilt) { loadedClipPoolBuilt = true; HashSet knownIds = new HashSet(); AddClips(Resources.FindObjectsOfTypeAll(), knownIds); } } private static void EnsureLoadedGameObjectPool() { if (!loadedGameObjectPoolBuilt) { loadedGameObjectPoolBuilt = true; HashSet knownIds = new HashSet(); AddGameObjects(Resources.FindObjectsOfTypeAll(), knownIds); } } private static void EnsureResourceFallbackPool() { if (!resourceFallbackBuilt) { resourceFallbackBuilt = true; AddClips(Resources.LoadAll(string.Empty), new HashSet(LoadedClips.Select((AudioClip clip) => ((Object)clip).GetInstanceID()))); AddGameObjects(Resources.LoadAll(string.Empty), new HashSet(LoadedGameObjects.Select((GameObject gameObject) => ((Object)gameObject).GetInstanceID()))); } } private static void AddClips(IEnumerable clips, HashSet knownIds) { foreach (AudioClip clip in clips) { if (clip != null && knownIds.Add(((Object)clip).GetInstanceID())) { LoadedClips.Add(clip); } } } private static void AddGameObjects(IEnumerable gameObjects, HashSet knownIds) { foreach (GameObject gameObject in gameObjects) { if (gameObject != null && knownIds.Add(((Object)gameObject).GetInstanceID())) { LoadedGameObjects.Add(gameObject); } } } } internal sealed class HelldiverGasCloud : MonoBehaviour { private const float GrowthDurationSeconds = 1.1f; private float targetRadius; private float duration; private float tickInterval; private float flatDamage; private float percentageDamage; private float slowAmount; private int ownerPlayerId; private float elapsed; private double startTime; private bool useSyncedClock; private readonly Dictionary nextTickTimesByPlayer = new Dictionary(); private readonly HashSet playersInside = new HashSet(); private readonly List playersToRemove = new List(); private Transform? visualRoot; internal void Configure(Vector2 center, float radius, float duration, float tickInterval, float flatDamage, float percentageDamage, float slowAmount, int ownerPlayerId, double startTime) { //IL_0057: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) targetRadius = radius; this.duration = duration; this.tickInterval = tickInterval; this.flatDamage = flatDamage; this.percentageDamage = percentageDamage; this.slowAmount = slowAmount; this.ownerPlayerId = ownerPlayerId; this.startTime = startTime; useSyncedClock = true; elapsed = ResolveElapsedSeconds(); ((Component)this).transform.position = Vector2.op_Implicit(center); GameObject val = new GameObject("VisualRoot"); val.transform.SetParent(((Component)this).transform, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one * 0.08f; visualRoot = val.transform; HelldiverToxicCloudPresentation.Spawn(visualRoot, radius, duration, elapsed); } private void Update() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) elapsed = (useSyncedClock ? ResolveElapsedSeconds() : (elapsed + TimeHandler.deltaTime)); float num = EvaluateGrowth(); float currentRadius = Mathf.Max(0.01f, targetRadius * num); if (visualRoot != null) { visualRoot.localScale = Vector3.one * Mathf.Lerp(0.08f, 1f, num); } UpdateAffectedPlayers(currentRadius); if (elapsed >= duration) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void UpdateAffectedPlayers(float currentRadius) { playersInside.Clear(); List list = PlayerManager.instance?.players; if (list == null) { return; } foreach (Player item in list) { if (ShouldApplyGameplayToPlayer(item) && IsPlayerInsideCloud(item, currentRadius)) { playersInside.Add(item.playerID); if (nextTickTimesByPlayer.TryGetValue(item.playerID, out var value) && elapsed < value) { ApplySlow(item); continue; } ApplyTick(item); nextTickTimesByPlayer[item.playerID] = elapsed + tickInterval; } } playersToRemove.Clear(); foreach (int key in nextTickTimesByPlayer.Keys) { if (!playersInside.Contains(key)) { playersToRemove.Add(key); } } foreach (int item2 in playersToRemove) { nextTickTimesByPlayer.Remove(item2); } } private void ApplyTick(Player player) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) Player val = ResolvePlayerById(ownerPlayerId); object obj; if (val == null) { obj = null; } else { CharacterData data = val.data; if (data == null) { obj = null; } else { WeaponHandler weaponHandler = data.weaponHandler; if (weaponHandler == null) { obj = null; } else { Gun gun = weaponHandler.gun; obj = ((gun != null) ? ((Component)gun).gameObject : null); } } } GameObject val2 = (GameObject)obj; float num = flatDamage + percentageDamage * player.data.maxHealth; if (num > 0f) { Vector2 val3 = Vector2.op_Implicit(((Component)player).transform.position) - Vector2.op_Implicit(((Component)this).transform.position); if (((Vector2)(ref val3)).sqrMagnitude <= 0.0001f) { val3 = Vector2.up; } DamageOverTime val4 = ((Component)player).GetComponent() ?? ((Component)player).GetComponentInChildren(); if (val4 != null) { val4.TakeDamageOverTime(((Vector2)(ref val3)).normalized * num, Vector2.op_Implicit(((Component)this).transform.position), tickInterval, tickInterval, new Color(0.56f, 0.93f, 0.46f, 1f), (SoundEvent)null, val2, val, true); } else { ((Damagable)player.data.healthHandler).TakeDamage(((Vector2)(ref val3)).normalized * num, Vector2.op_Implicit(((Component)this).transform.position), val2, val, true, false); } } ApplySlow(player); } private void ApplySlow(Player player) { CharacterData data = player.data; if (data != null) { CharacterStatModifiers stats = data.stats; if (stats != null) { stats.AddSlowAddative(slowAmount, slowAmount, false); } } } private bool IsPlayerInsideCloud(Player? player, float currentRadius) { //IL_0056: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0069: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) if (player == null || player.data == null || player.data.dead || player.data.healthHandler == null) { return false; } Bounds val = (Bounds)((player.data.mainCol != null) ? player.data.mainCol.bounds : new Bounds(((Component)player).transform.position, Vector3.one)); return Vector2.Distance(Vector2.op_Implicit(((Bounds)(ref val)).ClosestPoint(((Component)this).transform.position)), Vector2.op_Implicit(((Component)this).transform.position)) <= currentRadius; } private float EvaluateGrowth() { float num = Mathf.Clamp01(elapsed / 1.1f); return 1f - Mathf.Pow(1f - num, 2.35f); } private float ResolveElapsedSeconds() { double num = (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time); return Mathf.Max(0f, (float)(num - startTime)); } private static bool ShouldApplyGameplayToPlayer(Player? player) { if (player?.data == null || player.data.dead || player.data.healthHandler == null) { return false; } if (!PhotonNetwork.OfflineMode && player.data.view != null) { return player.data.view.IsMine; } return true; } private static Player? ResolvePlayerById(int playerId) { List list = PlayerManager.instance?.players; if (list == null) { return null; } foreach (Player item in list) { if (item != null && item.playerID == playerId) { return item; } } return null; } } internal static class HelldiverGatlingGunPool { private const float VisualScaleMultiplier = 0.65f; private static SimulatedGun? sharedGun; private static Gun? defaultGunTemplate; private static float? defaultProjectileBaseDamage; internal static void Warm() { GetOrCreateSharedGun(); } internal static void Invalidate() { if ((Object)(object)sharedGun != (Object)null) { Object.Destroy((Object)(object)((Component)sharedGun).gameObject); } sharedGun = null; defaultGunTemplate = null; defaultProjectileBaseDamage = null; } internal static bool Configure(Player owner, float speed, float damage, float percentageDamage, float unlockDepthY, Color color, Vector2? flightDirection = null) { //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) if (owner.data == null) { return false; } SimulatedGun orCreateSharedGun = GetOrCreateSharedGun(); Gun val = GetDefaultGunTemplate(); if (orCreateSharedGun == null || val == null) { return false; } orCreateSharedGun.CopyGunStatsExceptActions(val); ((Gun)orCreateSharedGun).player = owner; ((Gun)orCreateSharedGun).damage = damage / GetDefaultProjectileBaseDamage(); ((Gun)orCreateSharedGun).percentageDamage = percentageDamage; ((Gun)orCreateSharedGun).knockback = 0f; ((Gun)orCreateSharedGun).slow = 0f; ((Gun)orCreateSharedGun).spread = 0f; ((Gun)orCreateSharedGun).evenSpread = 0f; ((Gun)orCreateSharedGun).numberOfProjectiles = 1; ((Gun)orCreateSharedGun).bursts = 1; ((Gun)orCreateSharedGun).timeBetweenBullets = 0f; ((Gun)orCreateSharedGun).drag = 0f; ((Gun)orCreateSharedGun).dragMinSpeed = 0f; ((Gun)orCreateSharedGun).gravity = 0f; ((Gun)orCreateSharedGun).projectileSpeed = 1f; ((Gun)orCreateSharedGun).projectielSimulatonSpeed = 1f; ((Gun)orCreateSharedGun).shake = 0f; ((Gun)orCreateSharedGun).shakeM = 0f; ((Gun)orCreateSharedGun).forceSpecificShake = true; ((Gun)orCreateSharedGun).ignoreWalls = true; ((Gun)orCreateSharedGun).destroyBulletAfter = 4f; ((Gun)orCreateSharedGun).projectileColor = color; ((Gun)orCreateSharedGun).ShootPojectileAction = delegate { }; ((Gun)orCreateSharedGun).ShootPojectileAction = (Action)Delegate.Combine(((Gun)orCreateSharedGun).ShootPojectileAction, (Action)delegate(GameObject bullet) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) HelldiverGatlingProjectileController helldiverGatlingProjectileController = bullet.GetComponent(); if (helldiverGatlingProjectileController == null) { helldiverGatlingProjectileController = bullet.AddComponent(); } ProjectileHit component = bullet.GetComponent(); if (component != null) { component.fullSelfDamage = true; component.holdPlayerFor = 0f; component.destroyOnBlock = true; component.force = 0f; component.shake = 0f; component.movementSlow = 0f; } RayCastTrail component2 = bullet.GetComponent(); if (component2 != null) { component2.teamID = -1; component2.timeAtSpawn = 0f; component2.extraSize = Mathf.Min(component2.extraSize, 0f); } Transform transform = bullet.transform; transform.localScale *= 0.65f; helldiverGatlingProjectileController.Configure(speed, unlockDepthY, (Vector2)(((??)flightDirection) ?? Vector2.down)); }); return true; } internal static bool Fire(Player owner, Vector2 spawnPoint) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (owner.data == null) { return false; } SimulatedGun orCreateSharedGun = GetOrCreateSharedGun(); if (orCreateSharedGun == null) { return false; } return orCreateSharedGun.SimulatedAttack(owner.playerID, Vector2.op_Implicit(spawnPoint), Vector3.down, 0f, 1f, (Transform)null, false); } private static SimulatedGun? GetOrCreateSharedGun() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown if ((Object)(object)sharedGun != (Object)null) { return sharedGun; } GameObject val = new GameObject("DOLY_HelldiverGatlingGun"); Object.DontDestroyOnLoad((Object)val); sharedGun = val.AddComponent(); return sharedGun; } private static Gun? GetDefaultGunTemplate() { if ((Object)(object)defaultGunTemplate != (Object)null) { return defaultGunTemplate; } GameObject val = Resources.Load("Player"); if (val == null) { return null; } Holdable val2 = val.GetComponent()?.holdable; defaultGunTemplate = ((val2 != null) ? ((Component)val2).GetComponent() : null); return defaultGunTemplate; } private static float GetDefaultProjectileBaseDamage() { if (defaultProjectileBaseDamage.HasValue) { return defaultProjectileBaseDamage.Value; } ProjectilesToSpawn[] array = GetDefaultGunTemplate()?.projectiles; GameObject obj = ((array != null && array.Length > 0) ? array[0].objectToSpawn : null); float valueOrDefault = ((obj == null) ? null : obj.GetComponent()?.damage).GetValueOrDefault(1f); defaultProjectileBaseDamage = Mathf.Max(0.0001f, valueOrDefault); return defaultProjectileBaseDamage.Value; } } internal sealed class HelldiverGatlingProjectileController : MonoBehaviour { private LayerMask defaultRayMask; private float speed; private float unlockDepthY; private Vector2 flightDirection = Vector2.down; private bool configured; private bool defaultRayMaskCaptured; private bool wallsUnlocked; private MoveTransform? moveTransform; private RayCastTrail? rayCastTrail; private Rigidbody2D? rigidbody2D; internal void Configure(float speed, float unlockDepthY, Vector2 flightDirection) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) this.speed = speed; this.unlockDepthY = unlockDepthY; this.flightDirection = ((((Vector2)(ref flightDirection)).sqrMagnitude > 0.0001f) ? ((Vector2)(ref flightDirection)).normalized : Vector2.down); configured = false; wallsUnlocked = false; if (moveTransform != null) { ((Behaviour)moveTransform).enabled = true; moveTransform.velocity = Vector3.zero; } if (rayCastTrail != null && defaultRayMaskCaptured) { rayCastTrail.mask = defaultRayMask; } if (rigidbody2D != null) { rigidbody2D.velocity = Vector2.zero; rigidbody2D.angularVelocity = 0f; } TryApplyConfiguration(); } private void Awake() { TryApplyConfiguration(); } private void Start() { TryApplyConfiguration(); } private void Update() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) TryApplyConfiguration(); if (!configured) { return; } if (!wallsUnlocked && ((Component)this).transform.position.y <= unlockDepthY) { wallsUnlocked = true; if (rayCastTrail != null) { rayCastTrail.mask = ((PlayerManager.instance != null) ? PlayerManager.instance.canSeePlayerMask : LayerMask.op_Implicit(-1)); } } if (moveTransform != null) { moveTransform.velocity = Vector2.op_Implicit(flightDirection * speed); ((Component)this).transform.rotation = Quaternion.LookRotation(Vector2.op_Implicit(flightDirection), Vector3.forward); } } private void TryApplyConfiguration() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) if (configured) { return; } if (moveTransform == null) { moveTransform = ((Component)this).GetComponent(); } if (rayCastTrail == null) { rayCastTrail = ((Component)this).GetComponent(); } if (rigidbody2D == null) { rigidbody2D = ((Component)this).GetComponent(); } if (!defaultRayMaskCaptured && rayCastTrail != null) { defaultRayMask = rayCastTrail.mask; defaultRayMaskCaptured = true; } if (moveTransform != null && rayCastTrail != null) { configured = true; moveTransform.gravity = 0f; moveTransform.drag = 0f; moveTransform.dragMinSpeed = 0f; moveTransform.simulateGravity = 0; moveTransform.localForce = Vector3.zero; moveTransform.worldForce = Vector3.zero; moveTransform.velocity = Vector2.op_Implicit(flightDirection * speed); if (rigidbody2D != null) { rigidbody2D.gravityScale = 0f; rigidbody2D.drag = 0f; rigidbody2D.velocity = flightDirection * speed; } ((Component)this).transform.rotation = Quaternion.LookRotation(Vector2.op_Implicit(flightDirection), Vector3.forward); rayCastTrail.MoveRay(); } } } internal sealed class HelldiverHud : MonoBehaviour { private sealed class RowWidgets { internal RectTransform Root { get; } internal HorizontalLayoutGroup RowLayout { get; } internal LayoutElement RowElement { get; } internal Image IconGraphicImage { get; } internal GameObject ContentRoot { get; } internal GameObject TopLine { get; } internal LayoutElement TopLineElement { get; } internal GameObject BottomLine { get; } internal LayoutElement BottomLineElement { get; } internal TextMeshProUGUI NameText { get; } internal Image CountBadge { get; } internal TextMeshProUGUI CountText { get; } internal HorizontalLayoutGroup CodeRoot { get; } internal List CodeArrows { get; } = new List(); internal TextMeshProUGUI CooldownText { get; } internal RowWidgets(RectTransform root, HorizontalLayoutGroup rowLayout, LayoutElement rowElement, Image iconGraphicImage, GameObject contentRoot, GameObject topLine, LayoutElement topLineElement, GameObject bottomLine, LayoutElement bottomLineElement, TextMeshProUGUI nameText, Image countBadge, TextMeshProUGUI countText, HorizontalLayoutGroup codeRoot, TextMeshProUGUI cooldownText) { Root = root; RowLayout = rowLayout; RowElement = rowElement; IconGraphicImage = iconGraphicImage; ContentRoot = contentRoot; TopLine = topLine; TopLineElement = topLineElement; BottomLine = bottomLine; BottomLineElement = bottomLineElement; NameText = nameText; CountBadge = countBadge; CountText = countText; CodeRoot = codeRoot; CooldownText = cooldownText; } } private const string CanvasObjectName = "DOLY_HelldiverHudCanvas"; private const float PanelWidth = 410f; private const float RowSpacing = 8f; private const float RowHeight = 48f; private const float IconSize = 40f; private const float ArrowSize = 18f; private const float BottomArrowSize = 16f; private const float InputPlaceholderOpacity = 0.48f; private const float HudLeftMargin = 18f; private const float HudGapBelowScoreboard = 10f; private const float FallbackScoreboardTopPadding = 18f; private const float FallbackScoreboardRowHeight = 34f; private static readonly Color PanelColor = new Color(0f, 0f, 0f, 0.64f); private static readonly Color TextColor = new Color(0.93f, 0.91f, 0.84f, 1f); private static readonly Color CountColor = new Color(0.67f, 0.68f, 0.69f, 1f); private static readonly Color CooldownColor = new Color(0.86f, 0.83f, 0.76f, 1f); private static readonly Color DisabledColor = new Color(0.58f, 0.58f, 0.55f, 1f); private static readonly Color CountBadgeColor = new Color(0.92f, 0.92f, 0.88f, 0.92f); private static readonly Color CountTextOnBadgeColor = new Color(0.08f, 0.08f, 0.08f, 1f); private static readonly Color OrbitalAndEagleColor = HexToColor("E67366"); private static readonly Color GenericColor = HexToColor("C9B269"); private static readonly Color DisabledIconColor = new Color(0.45f, 0.45f, 0.43f, 0.82f); private static Sprite? solidSprite; private static Sprite? arrowSprite; private static Sprite? circleSprite; private readonly List rows = new List(); private readonly List inputArrows = new List(); private readonly List lastEntries = new List(); private readonly List lastInput = new List(); private Canvas? canvas; private RectTransform? panelRect; private Image? panelImage; private VerticalLayoutGroup? panelLayout; private RectTransform? inputRowRect; private TextMeshProUGUI? inputLabel; private HorizontalLayoutGroup? inputArrowLayout; private TextMeshProUGUI? inputPlaceholder; private bool hasLastState; private bool lastVisible; private float cachedAnchorOffset = -18f; private float lastAppliedHudScale = -1f; private int lastAnchorPlayerCount = -1; private int lastAnchorScreenHeight = -1; internal void SetState(bool visible, IReadOnlyList entries, IReadOnlyList currentInput) { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) EnsureUi(); if (canvas == null || panelRect == null || panelLayout == null) { return; } ApplyHudScale(); string summary; bool flag = DolyModSettings.TryGetHelldiverInputSummary(out summary); if (inputRowRect != null) { ((Component)inputRowRect).gameObject.SetActive(true); } if (inputLabel != null) { ((Component)inputLabel).gameObject.SetActive(flag); if (flag && ((TMP_Text)inputLabel).text != summary) { ((TMP_Text)inputLabel).text = summary; } LayoutElement component = ((Component)inputLabel).GetComponent(); if (component != null) { float minWidth = (component.preferredWidth = (flag ? 200f : 0f)); component.minWidth = minWidth; } } if (visible) { RefreshAnchorPosition(); } else if (panelRect != null) { panelRect.anchoredPosition = new Vector2(18f, cachedAnchorOffset); } if (!HasStateChanged(visible, entries, currentInput)) { return; } SnapshotState(visible, entries, currentInput); ((Behaviour)canvas).enabled = visible; if (!visible) { return; } EnsureRowCount(entries.Count); for (int i = 0; i < rows.Count; i++) { bool flag2 = i < entries.Count; ((Component)rows[i].Root).gameObject.SetActive(flag2); if (flag2) { ApplyRowState(rows[i], entries[i]); } } ApplyInputState(currentInput); LayoutRebuilder.ForceRebuildLayoutImmediate(panelRect); } private void OnDestroy() { if ((Object)(object)canvas != (Object)null && (Object)(object)((Component)canvas).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)canvas).gameObject); } } private void EnsureUi() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Expected O, but got Unknown //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Expected O, but got Unknown if (canvas == null || panelRect == null || panelLayout == null) { EnsureSprites(); GameObject val = new GameObject("DOLY_HelldiverHudCanvas", new Type[3] { typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster) }); canvas = val.GetComponent(); canvas.renderMode = (RenderMode)0; canvas.sortingOrder = 5000; CanvasScaler component = val.GetComponent(); component.uiScaleMode = (ScaleMode)1; component.referenceResolution = new Vector2(1920f, 1080f); component.screenMatchMode = (ScreenMatchMode)0; component.matchWidthOrHeight = 0.5f; GameObject val2 = new GameObject("Panel", new Type[4] { typeof(RectTransform), typeof(Image), typeof(VerticalLayoutGroup), typeof(ContentSizeFitter) }); val2.transform.SetParent(val.transform, false); panelRect = val2.GetComponent(); panelRect.anchorMin = new Vector2(0f, 1f); panelRect.anchorMax = new Vector2(0f, 1f); panelRect.pivot = new Vector2(0f, 1f); panelRect.anchoredPosition = new Vector2(18f, cachedAnchorOffset); panelRect.sizeDelta = new Vector2(410f, 0f); panelImage = val2.GetComponent(); panelImage.sprite = solidSprite; ((Graphic)panelImage).color = PanelColor; ((Graphic)panelImage).raycastTarget = false; panelLayout = val2.GetComponent(); ((LayoutGroup)panelLayout).padding = new RectOffset(12, 12, 12, 10); ((HorizontalOrVerticalLayoutGroup)panelLayout).spacing = 8f; ((HorizontalOrVerticalLayoutGroup)panelLayout).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)panelLayout).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)panelLayout).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)panelLayout).childForceExpandHeight = false; ContentSizeFitter component2 = val2.GetComponent(); component2.horizontalFit = (FitMode)2; component2.verticalFit = (FitMode)2; CreateInputRow(((Component)panelLayout).transform); } } private void CreateInputRow(Transform parent) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Expected O, but got Unknown //IL_0217: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("CurrentInputRow", new Type[3] { typeof(RectTransform), typeof(HorizontalLayoutGroup), typeof(LayoutElement) }); val.transform.SetParent(parent, false); inputRowRect = val.GetComponent(); ((Component)inputRowRect).gameObject.SetActive(false); HorizontalLayoutGroup component = val.GetComponent(); ((HorizontalOrVerticalLayoutGroup)component).spacing = 10f; ((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = false; LayoutElement component2 = val.GetComponent(); component2.preferredHeight = 24f; component2.minHeight = 24f; string summary; bool flag = DolyModSettings.TryGetHelldiverInputSummary(out summary); inputLabel = CreateText("Label", val.transform, summary, 15f, GenericColor, (FontStyles)0); ((TMP_Text)inputLabel).alignment = (TextAlignmentOptions)4097; ((Component)inputLabel).gameObject.SetActive(flag); LayoutElement obj = ((Component)inputLabel).gameObject.AddComponent(); obj.preferredWidth = (flag ? 200f : 0f); obj.minWidth = (flag ? 200f : 0f); GameObject val2 = new GameObject("ArrowHolder", new Type[3] { typeof(RectTransform), typeof(HorizontalLayoutGroup), typeof(LayoutElement) }); val2.transform.SetParent(val.transform, false); inputArrowLayout = val2.GetComponent(); ((HorizontalOrVerticalLayoutGroup)inputArrowLayout).spacing = 4f; ((HorizontalOrVerticalLayoutGroup)inputArrowLayout).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)inputArrowLayout).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)inputArrowLayout).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)inputArrowLayout).childForceExpandHeight = false; LayoutElement component3 = val2.GetComponent(); component3.flexibleWidth = 1f; component3.minWidth = 140f; inputPlaceholder = CreateText("Placeholder", val2.transform, "NONE", 16f, new Color(TextColor.r, TextColor.g, TextColor.b, 0.48f), (FontStyles)0); ((TMP_Text)inputPlaceholder).alignment = (TextAlignmentOptions)4097; } private void EnsureRowCount(int count) { if (panelLayout != null && inputLabel != null) { while (rows.Count < count) { rows.Add(CreateRow(((Component)panelLayout).transform, rows.Count)); } Transform parent = ((TMP_Text)inputLabel).transform.parent; if (parent != null && (Object)(object)parent.parent == (Object)(object)((Component)panelLayout).transform) { parent.SetSiblingIndex(((Component)panelLayout).transform.childCount - 1); } } } private bool HasStateChanged(bool visible, IReadOnlyList entries, IReadOnlyList currentInput) { if (!hasLastState || lastVisible != visible) { return true; } if (!visible) { return false; } if (lastEntries.Count != entries.Count || lastInput.Count != currentInput.Count) { return true; } for (int i = 0; i < entries.Count; i++) { if (!lastEntries[i].Equals(entries[i])) { return true; } } for (int j = 0; j < currentInput.Count; j++) { if (lastInput[j] != currentInput[j]) { return true; } } return false; } private void SnapshotState(bool visible, IReadOnlyList entries, IReadOnlyList currentInput) { hasLastState = true; lastVisible = visible; lastEntries.Clear(); for (int i = 0; i < entries.Count; i++) { lastEntries.Add(entries[i]); } lastInput.Clear(); for (int j = 0; j < currentInput.Count; j++) { lastInput.Add(currentInput[j]); } } private RowWidgets CreateRow(Transform parent, int index) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Expected O, but got Unknown //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_0325: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Expected O, but got Unknown //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_0404: Expected O, but got Unknown //IL_0470: Unknown result type (might be due to invalid IL or missing references) //IL_04ec: Unknown result type (might be due to invalid IL or missing references) //IL_04f3: Expected O, but got Unknown //IL_057b: Unknown result type (might be due to invalid IL or missing references) //IL_0580: Unknown result type (might be due to invalid IL or missing references) //IL_0593: Unknown result type (might be due to invalid IL or missing references) //IL_05f7: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject($"StratagemRow_{index}", new Type[3] { typeof(RectTransform), typeof(HorizontalLayoutGroup), typeof(LayoutElement) }); val.transform.SetParent(parent, false); HorizontalLayoutGroup component = val.GetComponent(); ((HorizontalOrVerticalLayoutGroup)component).spacing = 10f; ((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = false; LayoutElement component2 = val.GetComponent(); component2.preferredHeight = 48f; component2.minHeight = 48f; GameObject val2 = new GameObject("Icon", new Type[2] { typeof(RectTransform), typeof(LayoutElement) }); val2.transform.SetParent(val.transform, false); LayoutElement component3 = val2.GetComponent(); component3.preferredWidth = 40f; component3.preferredHeight = 40f; component3.minWidth = 40f; component3.minHeight = 40f; val2.GetComponent().sizeDelta = new Vector2(40f, 40f); GameObject val3 = new GameObject("IconGraphic", new Type[2] { typeof(RectTransform), typeof(Image) }); val3.transform.SetParent(val2.transform, false); RectTransform component4 = val3.GetComponent(); component4.anchorMin = Vector2.zero; component4.anchorMax = Vector2.one; component4.offsetMin = Vector2.zero; component4.offsetMax = Vector2.zero; Image component5 = val3.GetComponent(); ((Graphic)component5).raycastTarget = false; component5.preserveAspect = true; ((Graphic)component5).color = Color.white; GameObject val4 = new GameObject("CountBadge", new Type[3] { typeof(RectTransform), typeof(Image), typeof(Outline) }); val4.transform.SetParent(val2.transform, false); RectTransform component6 = val4.GetComponent(); component6.anchorMin = new Vector2(1f, 0f); component6.anchorMax = new Vector2(1f, 0f); component6.pivot = new Vector2(1f, 0f); component6.sizeDelta = new Vector2(16f, 16f); component6.anchoredPosition = new Vector2(4f, -4f); Image component7 = val4.GetComponent(); component7.sprite = solidSprite; ((Graphic)component7).color = CountBadgeColor; ((Graphic)component7).raycastTarget = false; Outline component8 = val4.GetComponent(); ((Shadow)component8).effectColor = new Color(1f, 1f, 1f, 0.22f); ((Shadow)component8).effectDistance = new Vector2(1f, -1f); ((Shadow)component8).useGraphicAlpha = true; TextMeshProUGUI val5 = CreateText("CountText", val4.transform, string.Empty, 12f, CountTextOnBadgeColor, (FontStyles)1); ((TMP_Text)val5).alignment = (TextAlignmentOptions)514; RectTransform rectTransform = ((TMP_Text)val5).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = Vector2.zero; rectTransform.offsetMax = Vector2.zero; val4.SetActive(false); GameObject val6 = new GameObject("Content", new Type[3] { typeof(RectTransform), typeof(VerticalLayoutGroup), typeof(LayoutElement) }); val6.transform.SetParent(val.transform, false); VerticalLayoutGroup component9 = val6.GetComponent(); ((HorizontalOrVerticalLayoutGroup)component9).spacing = 2f; ((HorizontalOrVerticalLayoutGroup)component9).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component9).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component9).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)component9).childForceExpandHeight = false; val6.GetComponent().flexibleWidth = 1f; GameObject val7 = new GameObject("TopLine", new Type[3] { typeof(RectTransform), typeof(HorizontalLayoutGroup), typeof(LayoutElement) }); val7.transform.SetParent(val6.transform, false); HorizontalLayoutGroup component10 = val7.GetComponent(); ((HorizontalOrVerticalLayoutGroup)component10).spacing = 8f; ((HorizontalOrVerticalLayoutGroup)component10).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component10).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component10).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)component10).childForceExpandHeight = false; LayoutElement component11 = val7.GetComponent(); component11.preferredHeight = 22f; TextMeshProUGUI val8 = CreateText("Name", val7.transform, string.Empty, 17f, TextColor, (FontStyles)0); ((TMP_Text)val8).alignment = (TextAlignmentOptions)4097; ((TMP_Text)val8).enableWordWrapping = false; ((TMP_Text)val8).overflowMode = (TextOverflowModes)1; LayoutElement obj = ((Component)val8).gameObject.AddComponent(); obj.flexibleWidth = 1f; obj.minWidth = 120f; GameObject val9 = new GameObject("BottomLine", new Type[3] { typeof(RectTransform), typeof(HorizontalLayoutGroup), typeof(LayoutElement) }); val9.transform.SetParent(val6.transform, false); HorizontalLayoutGroup component12 = val9.GetComponent(); ((HorizontalOrVerticalLayoutGroup)component12).spacing = 6f; ((HorizontalOrVerticalLayoutGroup)component12).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component12).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component12).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)component12).childForceExpandHeight = false; LayoutElement component13 = val9.GetComponent(); component13.preferredHeight = 18f; GameObject val10 = new GameObject("Code", new Type[3] { typeof(RectTransform), typeof(HorizontalLayoutGroup), typeof(LayoutElement) }); val10.transform.SetParent(val9.transform, false); HorizontalLayoutGroup component14 = val10.GetComponent(); ((HorizontalOrVerticalLayoutGroup)component14).spacing = 4f; ((HorizontalOrVerticalLayoutGroup)component14).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component14).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component14).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)component14).childForceExpandHeight = false; LayoutElement component15 = val10.GetComponent(); component15.flexibleWidth = 1f; component15.minWidth = 120f; TextMeshProUGUI val11 = CreateText("Cooldown", val9.transform, string.Empty, 16f, CooldownColor, (FontStyles)0); ((TMP_Text)val11).alignment = (TextAlignmentOptions)4097; ((TMP_Text)val11).enableWordWrapping = false; LayoutElement obj2 = ((Component)val11).gameObject.AddComponent(); obj2.flexibleWidth = 1f; obj2.minWidth = 120f; return new RowWidgets(val.GetComponent(), component, component2, component5, val6, val7, component11, val9, component13, val8, component7, val5, component14, val11); } private void ApplyRowState(RowWidgets row, HelldiverHudEntryState state) { //IL_0007: 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_001b: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) Color accentColor = GetAccentColor(state.Type); bool isSpent = state.IsSpent; Color color = (isSpent ? DisabledColor : accentColor); Sprite sprite = HelldiverStratagemIconLibrary.GetSprite(state.Type); row.IconGraphicImage.sprite = sprite; ((Component)row.IconGraphicImage).gameObject.SetActive(sprite != null); ((Graphic)row.IconGraphicImage).color = (isSpent ? DisabledIconColor : Color.white); ((TMP_Text)row.NameText).text = state.DisplayName; ((Graphic)row.NameText).color = color; bool flag = state.MaxUses > 0; ((Component)row.CountBadge).gameObject.SetActive(flag); if (flag) { ((TMP_Text)row.CountText).text = state.RemainingUses.ToString(); ((Graphic)row.CountBadge).color = (Color)(state.IsSpent ? new Color(0.72f, 0.72f, 0.7f, 0.75f) : CountBadgeColor); ((Graphic)row.CountText).color = (Color)(state.IsSpent ? new Color(0.18f, 0.18f, 0.18f, 0.8f) : CountTextOnBadgeColor); } bool isCooldownActive = state.IsCooldownActive; bool flag2 = !isCooldownActive && !state.IsSpent; ((HorizontalOrVerticalLayoutGroup)row.RowLayout).spacing = 10f; row.RowElement.preferredHeight = 48f; row.RowElement.minHeight = 48f; row.ContentRoot.gameObject.SetActive(true); row.TopLine.gameObject.SetActive(true); row.TopLineElement.preferredHeight = 22f; row.BottomLine.gameObject.SetActive(true); row.BottomLineElement.preferredHeight = 18f; ((Component)row.CooldownText).gameObject.SetActive(isCooldownActive || state.IsSpent); ((Component)row.CodeRoot).gameObject.SetActive(flag2); if (state.IsSpent) { ((TMP_Text)row.CooldownText).text = "DEPLETED"; ((Graphic)row.CooldownText).color = DisabledColor; } else if (isCooldownActive) { ((TMP_Text)row.CooldownText).text = $"{state.CooldownDisplayRemaining:0.0}s"; ((Graphic)row.CooldownText).color = CooldownColor; } if (flag2) { SetArrowSequence(row.CodeRoot, row.CodeArrows, state.Code, 18f, TextColor); } } private void ApplyInputState(IReadOnlyList currentInput) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (inputArrowLayout == null || inputPlaceholder == null) { return; } bool flag = currentInput.Count > 0; ((Component)inputPlaceholder).gameObject.SetActive(!flag); if (flag) { SetArrowSequence(inputArrowLayout, inputArrows, currentInput, 16f, TextColor); return; } for (int i = 0; i < inputArrows.Count; i++) { ((Component)inputArrows[i]).gameObject.SetActive(false); } } private void RefreshAnchorPosition() { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) if (canvas == null || panelRect == null) { return; } RectTransform component = ((Component)canvas).GetComponent(); if (component != null && Screen.height > 0) { int num = Mathf.Max((PlayerManager.instance?.players?.Count).GetValueOrDefault(), 2); if (num == lastAnchorPlayerCount && Screen.height == lastAnchorScreenHeight) { panelRect.anchoredPosition = new Vector2(18f, cachedAnchorOffset); return; } lastAnchorPlayerCount = num; lastAnchorScreenHeight = Screen.height; float num2 = EstimateScoreboardBottomScreenY(num); Rect rect = component.rect; float num3 = ((Rect)(ref rect)).height / (float)Screen.height; float num4 = ((float)Screen.height - num2 + 10f) * num3; cachedAnchorOffset = 0f - Mathf.Max(18f, num4); panelRect.anchoredPosition = new Vector2(18f, cachedAnchorOffset); } } private static float EstimateScoreboardBottomScreenY(int playerCount) { float num = 18f + (float)playerCount * 34f; return (float)Screen.height - num; } private void SetArrowSequence(HorizontalLayoutGroup layout, List pool, IReadOnlyList directions, float arrowSize, Color color) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) while (pool.Count < directions.Count) { pool.Add(CreateArrowImage(((Component)layout).transform, arrowSize)); } for (int i = 0; i < pool.Count; i++) { bool flag = i < directions.Count; ((Component)pool[i]).gameObject.SetActive(flag); if (flag) { ConfigureArrowImage(pool[i], directions[i], arrowSize, color); } } } private void ApplyHudScale() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (panelRect == null) { return; } float helldiverHudScale = DolyModSettings.GetHelldiverHudScale(); if (!Mathf.Approximately(lastAppliedHudScale, helldiverHudScale)) { lastAppliedHudScale = helldiverHudScale; ((Transform)panelRect).localScale = new Vector3(helldiverHudScale, helldiverHudScale, 1f); if (((Component)panelRect).gameObject.activeInHierarchy) { LayoutRebuilder.ForceRebuildLayoutImmediate(panelRect); } } } private static Image CreateArrowImage(Transform parent, float arrowSize) { //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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Arrow", new Type[3] { typeof(RectTransform), typeof(Image), typeof(LayoutElement) }); val.transform.SetParent(parent, false); Image component = val.GetComponent(); component.sprite = arrowSprite; ((Graphic)component).raycastTarget = false; component.preserveAspect = true; ((Graphic)component).rectTransform.sizeDelta = new Vector2(arrowSize, arrowSize); LayoutElement component2 = val.GetComponent(); component2.preferredWidth = arrowSize; component2.preferredHeight = arrowSize; component2.minWidth = arrowSize; component2.minHeight = arrowSize; return component; } private static void ConfigureArrowImage(Image image, HelldiverInputDirection direction, float arrowSize, Color color) { //IL_0001: 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_002f: Unknown result type (might be due to invalid IL or missing references) ((Graphic)image).color = color; ((Graphic)image).rectTransform.sizeDelta = new Vector2(arrowSize, arrowSize); ((Transform)((Graphic)image).rectTransform).localRotation = Quaternion.Euler(0f, 0f, GetArrowRotation(direction)); LayoutElement component = ((Component)image).GetComponent(); if (component != null) { component.preferredWidth = arrowSize; component.preferredHeight = arrowSize; component.minWidth = arrowSize; component.minHeight = arrowSize; } } private static float GetArrowRotation(HelldiverInputDirection direction) { return direction switch { HelldiverInputDirection.Up => 0f, HelldiverInputDirection.Right => -90f, HelldiverInputDirection.Down => 180f, HelldiverInputDirection.Left => 90f, _ => 0f, }; } private static TextMeshProUGUI CreateText(string name, Transform parent, string text, float fontSize, Color color, FontStyles fontStyle) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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) GameObject val = new GameObject(name, new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val.transform.SetParent(parent, false); TextMeshProUGUI component = val.GetComponent(); ((TMP_Text)component).text = text; ((TMP_Text)component).fontSize = fontSize; ((Graphic)component).color = color; ((TMP_Text)component).fontStyle = fontStyle; ((TMP_Text)component).enableWordWrapping = false; ((TMP_Text)component).richText = false; ((Graphic)component).raycastTarget = false; return component; } private static void EnsureSprites() { if (solidSprite == null) { solidSprite = CreateSolidSprite(); } if (arrowSprite == null) { arrowSprite = CreateArrowSprite(); } if (circleSprite == null) { circleSprite = CreateCircleSprite(); } } private static Sprite CreateSolidSprite() { //IL_0004: 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) //IL_0010: 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) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false) { filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)1 }; val.SetPixel(0, 0, Color.white); val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f), 1f); } private static Sprite CreateArrowSprite() { //IL_0006: 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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false) { filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; Color val2 = default(Color); ((Color)(ref val2))..ctor(1f, 1f, 1f, 0f); for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { val.SetPixel(j, i, val2); } } for (int k = 0; k < 64; k++) { for (int l = 0; l < 64; l++) { if (IsInsideArrowShape((float)l + 0.5f, (float)k + 0.5f, 64)) { val.SetPixel(l, k, Color.white); } } } val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 64f); } private static bool IsInsideArrowShape(float x, float y, int size) { float num = x / (float)size; float num2 = y / (float)size; if (num >= 0.32f && num <= 0.68f && num2 >= 0.08f && num2 <= 0.58f) { return true; } if (num2 < 0.5f || num2 > 0.95f) { return false; } float num3 = 0.5f; float num4 = (0.95f - num2) * 1.25f; if (num >= num3 - num4) { return num <= num3 + num4; } return false; } private static Sprite CreateCircleSprite() { //IL_0006: 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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false) { filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; float num = 15.5f; float num2 = 7.68f; Color val2 = default(Color); ((Color)(ref val2))..ctor(1f, 1f, 1f, 0f); for (int i = 0; i < 32; i++) { for (int j = 0; j < 32; j++) { float num3 = (float)j - num; float num4 = (float)i - num; val.SetPixel(j, i, (num3 * num3 + num4 * num4 <= num2 * num2) ? Color.white : val2); } } val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, 32f, 32f), new Vector2(0.5f, 0.5f), 32f); } private static Color GetAccentColor(HelldiverStratagemType type) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (type != HelldiverStratagemType.EagleRearm) { if (!HelldiverClassRegistry.IsOrbitalStratagem(type) && !HelldiverClassRegistry.IsEagleStratagem(type)) { return GenericColor; } return OrbitalAndEagleColor; } return GenericColor; } private static Color HexToColor(string hex) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) Color result = default(Color); if (!ColorUtility.TryParseHtmlString("#" + hex, ref result)) { return Color.white; } return result; } } internal struct HelldiverHudEntryState { internal HelldiverStratagemType Type { get; } internal string DisplayName { get; } internal IReadOnlyList Code { get; } internal bool IsSelected { get; } internal bool IsCooldownActive { get; } internal float CooldownDisplayRemaining { get; } internal int RemainingUses { get; } internal int MaxUses { get; } internal bool IsSpent { get { if (MaxUses > 0) { return RemainingUses <= 0; } return false; } } internal HelldiverHudEntryState(HelldiverStratagemType type, string displayName, IReadOnlyList code, bool isSelected, bool isCooldownActive, float cooldownDisplayRemaining, int remainingUses, int maxUses) { Type = type; DisplayName = displayName; Code = code; IsSelected = isSelected; IsCooldownActive = isCooldownActive; CooldownDisplayRemaining = cooldownDisplayRemaining; RemainingUses = remainingUses; MaxUses = maxUses; } } internal sealed class HelldiverLodgedShellVisual : MonoBehaviour { private Vector2 point; private float length; private float width; private float angleDegrees; private float lifetime; private float elapsed; private Color color; private LineRenderer? bodyRenderer; private Material? bodyMaterial; private LineRenderer? glowRenderer; private Material? glowMaterial; internal void Configure(Vector2 point, Color color, float length, float width, float angleDegrees, float lifetime) { //IL_0001: 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_0008: 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) //IL_0033: 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) this.point = point; this.color = color; this.length = length; this.width = width; this.angleDegrees = angleDegrees; this.lifetime = lifetime; ((Component)this).transform.position = Vector2.op_Implicit(point); bodyRenderer = CreateRenderer("Body", ref bodyMaterial, 1413); glowRenderer = CreateRenderer("Glow", ref glowMaterial, 1412); RenderShell(1f); } private void Update() { elapsed += TimeHandler.deltaTime; float alpha = Mathf.Clamp01(1f - elapsed / Mathf.Max(0.001f, lifetime)); RenderShell(alpha); } private void OnDestroy() { if (bodyMaterial != null) { Object.Destroy((Object)(object)bodyMaterial); } if (glowMaterial != null) { Object.Destroy((Object)(object)glowMaterial); } } private void RenderShell(float alpha) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) Vector2 val = Vector2.op_Implicit(Quaternion.Euler(0f, 0f, angleDegrees) * Vector3.up); float num = length * 0.52f; Vector2 val2 = point + val * (num * 0.12f); Vector2 val3 = val2 - val * num; if (bodyRenderer != null) { Color val4 = Color.Lerp(color, new Color(0.22f, 0.22f, 0.22f, 1f), 0.45f); val4.a = 0.94f * alpha; bodyRenderer.startColor = val4; bodyRenderer.endColor = val4; bodyRenderer.startWidth = width * 0.8f; bodyRenderer.endWidth = width; bodyRenderer.SetPosition(0, Vector2.op_Implicit(val3)); bodyRenderer.SetPosition(1, Vector2.op_Implicit(val2)); } if (glowRenderer != null) { Color val5 = Color.Lerp(color, Color.white, 0.25f); val5.a = 0.42f * alpha; glowRenderer.startColor = val5; glowRenderer.endColor = new Color(val5.r, val5.g, val5.b, 0f); glowRenderer.startWidth = width * 1.8f; glowRenderer.endWidth = width * 0.6f; glowRenderer.SetPosition(0, Vector2.op_Implicit(val3)); glowRenderer.SetPosition(1, Vector2.op_Implicit(val2)); } } private LineRenderer CreateRenderer(string childName, ref Material? material, int sortingOrder) { //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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown GameObject val = new GameObject(childName); val.transform.SetParent(((Component)this).transform, false); material = new Material(Shader.Find("Sprites/Default")); LineRenderer obj = val.AddComponent(); ((Renderer)obj).material = material; obj.positionCount = 2; obj.useWorldSpace = true; obj.numCapVertices = 10; obj.numCornerVertices = 10; obj.textureMode = (LineTextureMode)0; obj.alignment = (LineAlignment)0; ((Renderer)obj).sortingOrder = sortingOrder; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; return obj; } } internal sealed class HelldiverHellpodController : MonoBehaviour { private const float HellpodHealth = 1000f; private const float DropSearchHeight = 8f; private const float DropSearchDepth = 8f; private const float IgnoreCeilingUnlockDepth = 2f; private const float DropSpeed = 112f; private const float MinFallDuration = 0.09f; private const float MaxFallDuration = 0.375f; private const float LandingCastWidth = 1.25f; private const float LandingCastHeight = 0.2f; private const float MinimumLandingNormalY = 0.1f; private const float ImpactDamageRadius = 1.25f; private const float ImpactPercentDamage = 0.5f; private Vector2 fallStart; private Vector2 lodgedPosition; private Vector2 landingPoint; private HelldiverStratagemType sentryType; private int ownerPlayerId; private int seed; private double startTime; private float fallDuration; private bool landed; private bool sentrySpawned; private BoxCollider2D? solidCollider; private HelldiverHellpodDamageable? damageable; internal int Seed => seed; internal int OwnerPlayerId => ownerPlayerId; internal void Configure(HelldiverStratagemType sentryType, Vector2 targetPoint, int ownerPlayerId, int seed, double startTime) { //IL_0000: 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_000d: Unknown result type (might be due to invalid IL or missing references) ResolveDeployment(targetPoint, out var val, out var val2); ConfigureResolved(sentryType, val, val2, ownerPlayerId, seed, startTime); } internal void ConfigureResolved(HelldiverStratagemType sentryType, Vector2 fallStart, Vector2 landingPoint, int ownerPlayerId, int seed, double startTime) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) this.sentryType = sentryType; this.ownerPlayerId = ownerPlayerId; this.seed = seed; this.startTime = startTime; ((Object)((Component)this).gameObject).name = $"DOLY_{sentryType}_Hellpod_{seed}"; ((Component)this).gameObject.layer = ResolveSolidLayer(); this.fallStart = fallStart; this.landingPoint = landingPoint; lodgedPosition = landingPoint - Vector2.up * 2.2f; fallDuration = Mathf.Clamp(Vector2.Distance(fallStart, lodgedPosition) / 112f, 0.09f, 0.375f); ((Component)this).transform.position = Vector2.op_Implicit(fallStart); HelldiverVectorArt.BuildHellpodVisual(((Component)this).transform); solidCollider = ((Component)this).gameObject.AddComponent(); solidCollider.size = new Vector2(1.4f, 2.2f); ((Collider2D)solidCollider).offset = new Vector2(0f, 1.1f); ((Behaviour)solidCollider).enabled = false; damageable = ((Component)this).gameObject.AddComponent(); damageable.Configure(this, 1000f); } private void Update() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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) //IL_0056: Unknown result type (might be due to invalid IL or missing references) double num = (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time); if (!landed) { float num2 = Mathf.Clamp01((float)((num - startTime) / (double)Math.Max(0.0001f, fallDuration))); ((Component)this).transform.position = Vector2.op_Implicit(Vector2.Lerp(fallStart, lodgedPosition, num2)); if (num2 < 1f) { return; } Land(); } if (!sentrySpawned) { sentrySpawned = true; SpawnSentry(startTime + (double)fallDuration); } } private void Land() { //IL_000e: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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) landed = true; ((Component)this).transform.position = Vector2.op_Implicit(lodgedPosition); if (solidCollider != null) { ((Behaviour)solidCollider).enabled = true; } HelldiverStrikeController.SpawnImpactFlash(landingPoint, HelldiverClassRegistry.GetDefinition(sentryType).Color); if (IsOwnerAuthority()) { HelldiverMachineGunSentryController.BroadcastSentryRadialPlayerDamage(landingPoint, 1.25f, 0f, 0.5f, 1f, ownerPlayerId, ignoreWalls: true); HelldiverSentryDamageable.ApplyRadialDamage(landingPoint, 1.25f, 0f, 0.5f, 1f, ownerPlayerId, ignoreWalls: true); } } private void SpawnSentry(double now) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_003c: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject($"DOLY_{sentryType}_{seed}") { layer = ResolveSolidLayer() }; val.transform.position = Vector2.op_Implicit(landingPoint); val.AddComponent().Configure(sentryType, ownerPlayerId, seed, now); } internal void HandleDestroyedByDamage(Vector2 damagePosition) { //IL_0000: 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) HelldiverStrikeController.SpawnImpactFlash(damagePosition, HelldiverClassRegistry.GetDefinition(sentryType).Color); Object.Destroy((Object)(object)((Component)this).gameObject); } private bool IsOwnerAuthority() { if (PhotonNetwork.OfflineMode) { return true; } Player val = HolySmiteEffect.ResolvePlayerById(ownerPlayerId); if (val?.data?.view != null) { return val.data.view.IsMine; } return false; } internal static void ResolveDeployment(Vector2 targetPoint, out Vector2 fallStart, out Vector2 landingPoint) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) fallStart = new Vector2(targetPoint.x, ResolveDropStartY(targetPoint)); landingPoint = ResolveLandingPoint(targetPoint, fallStart.y); } private static float ResolveDropStartY(Vector2 targetPoint) { //IL_0000: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) float num = targetPoint.y + 8f; Camera main = Camera.main; if (main == null) { return num; } Vector3 val = main.ViewportToWorldPoint(new Vector3(0.5f, 1.04f, Mathf.Abs(((Component)main).transform.position.z))); return Mathf.Max(num, val.y); } private static Vector2 ResolveLandingPoint(Vector2 targetPoint, float startY) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_0025: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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_00dc: Unknown result type (might be due to invalid IL or missing references) Vector2 val = new Vector2(targetPoint.x, startY); float num = Mathf.Max(0.1f, startY - (targetPoint.y - 8f)); float num2 = targetPoint.y + 2f; int num3 = ((PlayerManager.instance != null) ? ((LayerMask)(ref PlayerManager.instance.canSeePlayerMask)).value : (-1)); RaycastHit2D[] array = Physics2D.BoxCastAll(val, new Vector2(1.25f, 0.2f), 0f, Vector2.down, num, num3); Array.Sort(array, (RaycastHit2D a, RaycastHit2D b) => ((RaycastHit2D)(ref a)).distance.CompareTo(((RaycastHit2D)(ref b)).distance)); for (int i = 0; i < array.Length; i++) { RaycastHit2D val2 = array[i]; if (((RaycastHit2D)(ref val2)).collider != null && !(((RaycastHit2D)(ref val2)).point.y > num2) && !(((RaycastHit2D)(ref val2)).normal.y < 0.1f) && IsMapCollider(((RaycastHit2D)(ref val2)).collider)) { return ((RaycastHit2D)(ref val2)).point; } } return targetPoint; } private static bool IsMapCollider(Collider2D collider) { MapManager instance = MapManager.instance; object obj; if (instance == null) { obj = null; } else { MapWrapper currentMap = instance.currentMap; obj = ((currentMap != null) ? currentMap.Map : null); } Map val = (Map)obj; if (val != null && !((Object)(object)((Component)collider).transform == (Object)(object)((Component)val).transform)) { return ((Component)collider).transform.IsChildOf(((Component)val).transform); } return true; } internal static int ResolveSolidLayer() { int num = LayerMask.NameToLayer("Default"); if (num < 0) { return 0; } return num; } } internal sealed class HelldiverHellpodDamageable : Damagable { private sealed class PendingHellpodDamage { internal Vector2 Damage { get; } internal Vector2 DamagePosition { get; } internal int DamagingPlayerId { get; } internal PendingHellpodDamage(Vector2 damage, Vector2 damagePosition, int damagingPlayerId) { //IL_0007: 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_000e: 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) Damage = damage; DamagePosition = damagePosition; DamagingPlayerId = damagingPlayerId; } } private static readonly Dictionary> PendingDamageBySeed = new Dictionary>(); private HelldiverHellpodController? controller; private float currentHealth; private float maxHealth; private bool destroyed; internal int Seed => controller?.Seed ?? (-1); internal float MaxHealth => maxHealth; internal bool IsDestroyed => destroyed; internal void Configure(HelldiverHellpodController controller, float maxHealth) { this.controller = controller; this.maxHealth = Mathf.Max(1f, maxHealth); currentHealth = this.maxHealth; destroyed = false; ApplyPendingSyncedDamage(); } public override void CallTakeDamage(Vector2 damage, Vector2 damagePosition, GameObject? damagingWeapon = null, Player? damagingPlayer = null, bool lethal = true) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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_0055: 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) if (!CanTakeDamage(damage)) { return; } Player val = damagingPlayer ?? ResolveControllerOwner(); if (val == null) { ApplyLocalDamage(damage, damagePosition); return; } PhotonView val2 = val.data?.view; if (PhotonNetwork.OfflineMode || val2 == null || val2.IsMine) { HelldiverRuntime.GetOrAdd(val).BroadcastHellpodDamaged(Seed, damage, damagePosition, damagingPlayer?.playerID ?? (-1)); } } public override void TakeDamage(Vector2 damage, Vector2 damagePosition, GameObject? damagingWeapon = null, Player? damagingPlayer = null, bool lethal = true, bool ignoreBlock = false) { //IL_0001: 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) ApplyLocalDamage(damage, damagePosition); } public override void TakeDamage(Vector2 damage, Vector2 damagePosition, Color dmgColor, GameObject? damagingWeapon = null, Player? damagingPlayer = null, bool lethal = true, bool ignoreBlock = false) { //IL_0001: 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) ((Damagable)this).TakeDamage(damage, damagePosition, damagingWeapon, damagingPlayer, lethal, ignoreBlock); } internal void ApplySyncedDamage(Vector2 damage, Vector2 damagePosition, int damagingPlayerId) { //IL_0001: 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) ApplyLocalDamage(damage, damagePosition); } internal static void ApplyOrBufferSyncedDamage(int seed, Vector2 damage, Vector2 damagePosition, int damagingPlayerId) { //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_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) if (TryResolveBySeed(seed, out HelldiverHellpodDamageable hellpod)) { hellpod.ApplySyncedDamage(damage, damagePosition, damagingPlayerId); return; } if (!PendingDamageBySeed.TryGetValue(seed, out List value)) { value = new List(); PendingDamageBySeed[seed] = value; } value.Add(new PendingHellpodDamage(damage, damagePosition, damagingPlayerId)); } internal static void ClearPendingSyncedDamage() { PendingDamageBySeed.Clear(); } internal static bool TryResolveBySeed(int seed, out HelldiverHellpodDamageable hellpod) { HelldiverHellpodDamageable[] array = Object.FindObjectsOfType(); foreach (HelldiverHellpodDamageable helldiverHellpodDamageable in array) { if (helldiverHellpodDamageable != null && helldiverHellpodDamageable.Seed == seed && !helldiverHellpodDamageable.destroyed) { hellpod = helldiverHellpodDamageable; return true; } } hellpod = null; return false; } internal static bool TryGetFromHit(HitInfo hit, out HelldiverHellpodDamageable hellpod) { if (hit.collider != null && TryGetFromCollider(hit.collider, out hellpod)) { return true; } hellpod = ((hit.transform == null) ? null : ((Component)hit.transform).GetComponentInParent()); if (hellpod != null) { return !hellpod.destroyed; } return false; } internal static bool TryGetFromCollider(Collider2D collider, out HelldiverHellpodDamageable hellpod) { hellpod = ((Component)collider).GetComponentInParent(); if (hellpod != null) { return !hellpod.destroyed; } return false; } internal static void TryHandleProjectileHit(ProjectileHit projectileHit, HitInfo hit, bool forceCall) { //IL_0018: 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_0044: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) if (projectileHit != null && ShouldProcessProjectile(projectileHit, forceCall) && TryGetFromHit(hit, out HelldiverHellpodDamageable hellpod) && hellpod.CanTakeDamage(Vector2.one) && TryResolveProjectileDamage(projectileHit, hellpod.maxHealth, out float damageAmount, out Player damagingPlayer)) { Vector2 val = ResolveProjectileDirection(((Component)projectileHit).transform, hit.normal); ((Damagable)hellpod).CallTakeDamage(val * damageAmount, hit.point, projectileHit.ownWeapon, damagingPlayer ?? projectileHit.ownPlayer, true); } } private bool CanTakeDamage(Vector2 damage) { if (!destroyed && controller != null && Seed >= 0) { return ((Vector2)(ref damage)).sqrMagnitude > 0.0001f; } return false; } private void ApplyLocalDamage(Vector2 damage, Vector2 damagePosition) { //IL_0001: 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) if (CanTakeDamage(damage)) { currentHealth = Mathf.Max(0f, currentHealth - ((Vector2)(ref damage)).magnitude); if (!(currentHealth > 0f)) { destroyed = true; controller.HandleDestroyedByDamage(damagePosition); } } } private void ApplyPendingSyncedDamage() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) int seed = Seed; if (seed < 0 || !PendingDamageBySeed.TryGetValue(seed, out List value)) { return; } PendingDamageBySeed.Remove(seed); for (int i = 0; i < value.Count; i++) { if (destroyed) { break; } PendingHellpodDamage pendingHellpodDamage = value[i]; ApplySyncedDamage(pendingHellpodDamage.Damage, pendingHellpodDamage.DamagePosition, pendingHellpodDamage.DamagingPlayerId); } } private Player? ResolveControllerOwner() { if (controller != null) { return HolySmiteEffect.ResolvePlayerById(controller.OwnerPlayerId); } return null; } private static bool ShouldProcessProjectile(ProjectileHit projectileHit, bool forceCall) { if (forceCall) { return true; } if (projectileHit.view != null) { return projectileHit.view.IsMine; } return true; } private static bool TryResolveProjectileDamage(ProjectileHit projectileHit, float targetMaxHealth, out float damageAmount, out Player? damagingPlayer) { damagingPlayer = projectileHit.ownPlayer; HelldiverSentryProjectileController component = ((Component)projectileHit).GetComponent(); if (component != null && component.TryGetDamageAgainstSentry(targetMaxHealth, out damageAmount, out damagingPlayer)) { return damageAmount > 0f; } float num = (projectileHit.bulletCanDealDeamage ? projectileHit.damage : 1f); damageAmount = (num + projectileHit.percentageDamage * targetMaxHealth) * projectileHit.dealDamageMultiplierr; return damageAmount > 0f; } private static Vector2 ResolveProjectileDirection(Transform projectileTransform, Vector2 hitNormal) { //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_0009: 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_004c: 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_0044: 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_0049: Unknown result type (might be due to invalid IL or missing references) Vector3 forward = projectileTransform.forward; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(forward.x, forward.y); if (((Vector2)(ref val)).sqrMagnitude <= 0.0001f) { val = ((((Vector2)(ref hitNormal)).sqrMagnitude > 0.0001f) ? (-((Vector2)(ref hitNormal)).normalized) : Vector2.up); } return ((Vector2)(ref val)).normalized; } } internal enum HelldiverSentryFireMode { Continuous, Burst, Laser } internal sealed class HelldiverSentryConfig { internal const float DefaultHealth = 100f; internal const float DefaultMaxHealthLossPerHitFraction = 0.4f; internal static readonly IReadOnlyDictionary All = new Dictionary { [HelldiverStratagemType.MachineGunSentry] = new HelldiverSentryConfig(HelldiverStratagemType.MachineGunSentry, 30f, 80, 35f, 0f, 8f, 0.02f, 2f, 0.12f, 1, 0f, 3f, 120f, 55f, 10f, 0.4f, 0.1f, HelldiverSentryFireMode.Continuous, 0f, 0f, 0f, 0f, 0, 1f, consumesAmmo: true, 200f, 0.6f), [HelldiverStratagemType.RocketSentry] = new HelldiverSentryConfig(HelldiverStratagemType.RocketSentry, 40f, 16, 20f, 0f, 60f, 0.1f, 4f, 1f, 1, 0f, 2f, 120f, 45f, 6f, 0.2f, 0.2f, HelldiverSentryFireMode.Continuous, 60f, 0.1f, 4f, 0f, 0, 1f, consumesAmmo: true, 300f, 0.35f), [HelldiverStratagemType.AutocannonSentry] = new HelldiverSentryConfig(HelldiverStratagemType.AutocannonSentry, 45f, 24, 55f, 0.5f, 80f, 0.2f, 3f, 1.5f, 3, 0.3f, 1f, 120f, 35f, 6f, 0.15f, 0.15f, HelldiverSentryFireMode.Burst, 0f, 0f, 0f, 0f, 0, 1f, consumesAmmo: true, 350f, 0.35f), [HelldiverStratagemType.GatlingSentry] = new HelldiverSentryConfig(HelldiverStratagemType.GatlingSentry, 40f, 200, 35f, 0f, 8f, 0.02f, 2f, 0.06f, 1, 0f, 3f, 120f, 45f, 12f, 1.2f, 0.3f, HelldiverSentryFireMode.Continuous, 0f, 0f, 0f, 0f, 0, 1f, consumesAmmo: true, 250f, 0.35f), [HelldiverStratagemType.LaserSentry] = new HelldiverSentryConfig(HelldiverStratagemType.LaserSentry, 40f, 0, 0f, 0f, 5f, 0.01f, 1f, 0.05f, 1, 0f, 0f, 120f, 40f, 12f, 1.5f, 0.5f, HelldiverSentryFireMode.Laser, 0f, 0f, 0f, 100f, 2, 1f, consumesAmmo: false, 250f, 0.6f) }; internal HelldiverStratagemType Type { get; } internal float Health { get; } internal float MaxHealthLossPerHitFraction { get; } internal float LifetimeSeconds { get; } internal int MaxAmmo { get; } internal float ProjectileSpeed { get; } internal float ProjectileGravity { get; } internal float Damage { get; } internal float PercentDamage { get; } internal float ProjectileVisualScale { get; } internal float FireIntervalSeconds { get; } internal int BurstCount { get; } internal float BurstShotIntervalSeconds { get; } internal float SpreadDegrees { get; } internal float MaxAimAngleDegrees { get; } internal float AimSpeedDegreesPerSecond { get; } internal float TargetingAngleDegrees { get; } internal float ContinueShootingSeconds { get; } internal float LockOnDelaySeconds { get; } internal HelldiverSentryFireMode FireMode { get; } internal float ExplosionDamage { get; } internal float ExplosionPercentDamage { get; } internal float ExplosionRadius { get; } internal float BeamRange { get; } internal int BeamBounces { get; } internal float ReflectedDamageMultiplier { get; } internal bool ConsumesAmmo { get; } internal bool HasExplosion { get { if (ExplosionRadius > 0f) { if (!(ExplosionDamage > 0f)) { return ExplosionPercentDamage > 0f; } return true; } return false; } } private HelldiverSentryConfig(HelldiverStratagemType type, float lifetimeSeconds, int maxAmmo, float projectileSpeed, float projectileGravity, float damage, float percentDamage, float projectileVisualScale, float fireIntervalSeconds, int burstCount, float burstShotIntervalSeconds, float spreadDegrees, float maxAimAngleDegrees, float aimSpeedDegreesPerSecond, float targetingAngleDegrees, float continueShootingSeconds, float lockOnDelaySeconds, HelldiverSentryFireMode fireMode, float explosionDamage = 0f, float explosionPercentDamage = 0f, float explosionRadius = 0f, float beamRange = 0f, int beamBounces = 0, float reflectedDamageMultiplier = 1f, bool consumesAmmo = true, float health = 100f, float maxHealthLossPerHitFraction = 0.4f) { Type = type; Health = Mathf.Max(1f, health); MaxHealthLossPerHitFraction = Mathf.Max(0.01f, maxHealthLossPerHitFraction); LifetimeSeconds = lifetimeSeconds; MaxAmmo = maxAmmo; ProjectileSpeed = projectileSpeed; ProjectileGravity = projectileGravity; Damage = damage; PercentDamage = percentDamage; ProjectileVisualScale = projectileVisualScale; FireIntervalSeconds = fireIntervalSeconds; BurstCount = burstCount; BurstShotIntervalSeconds = burstShotIntervalSeconds; SpreadDegrees = spreadDegrees; MaxAimAngleDegrees = maxAimAngleDegrees; AimSpeedDegreesPerSecond = aimSpeedDegreesPerSecond; TargetingAngleDegrees = targetingAngleDegrees; ContinueShootingSeconds = continueShootingSeconds; LockOnDelaySeconds = lockOnDelaySeconds; FireMode = fireMode; ExplosionDamage = explosionDamage; ExplosionPercentDamage = explosionPercentDamage; ExplosionRadius = explosionRadius; BeamRange = beamRange; BeamBounces = beamBounces; ReflectedDamageMultiplier = reflectedDamageMultiplier; ConsumesAmmo = consumesAmmo; } internal static HelldiverSentryConfig Get(HelldiverStratagemType type) { return All[type]; } } internal sealed class HelldiverMachineGunSentryController : MonoBehaviour { internal const float EmergenceDurationSeconds = 0.8f; internal const float RetractionDurationSeconds = 0.8f; private const float MaxAimAccelerationAngleDegrees = 180f; private const float AimAccelerationExponent = 2f; private const float MaxAimSpeedErrorMultiplier = 6f; private const float AimSyncIntervalSeconds = 0.08f; private const float AimSyncMinDeltaDegrees = 0.5f; private int ownerPlayerId; private int seed; private HelldiverStratagemType sentryType; private HelldiverSentryConfig config = HelldiverSentryConfig.Get(HelldiverStratagemType.MachineGunSentry); private double spawnTime; private double activeStartTime; private double retractStartTime; private int remainingAmmo; private float currentAimAngle; private float lastShootAllowedUntil; private double nextFireTime; private double targetLockReadyTime; private double nextTargetSearchTime; private Vector2 lastSeenTargetPoint; private double nextAimSyncTime; private float lastBroadcastAimAngle = float.NaN; private double nextBurstShotTime; private int burstShotsRemaining; private bool configured; private bool active; private bool retracting; private bool depletionBroadcast; private bool hasLastSeenTargetPoint; private Transform? liftRoot; private HelldiverSentryVisual visual; private HelldiverSentryDamageable? damageable; private Player? currentTarget; internal int Seed => seed; internal int OwnerPlayerId => ownerPlayerId; internal void Configure(HelldiverStratagemType sentryType, int ownerPlayerId, int seed, double spawnTime) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) this.sentryType = sentryType; config = HelldiverSentryConfig.Get(sentryType); this.ownerPlayerId = ownerPlayerId; this.seed = seed; this.spawnTime = spawnTime; activeStartTime = spawnTime + 0.800000011920929; remainingAmmo = GetResolvedMaxAmmo(); ((Component)this).gameObject.layer = HelldiverHellpodController.ResolveSolidLayer(); configured = true; liftRoot = new GameObject("SentryLiftRoot").transform; liftRoot.SetParent(((Component)this).transform, false); liftRoot.localPosition = new Vector3(0f, -1.775f, 0f); liftRoot.localRotation = Quaternion.identity; visual = HelldiverVectorArt.BuildSentryVisual(liftRoot, sentryType); BoxCollider2D solidCollider = CreateSolidCollider(((Component)liftRoot).gameObject); damageable = ((Component)this).gameObject.AddComponent(); damageable.Configure(this, GetResolvedMaxHealth(), config.MaxHealthLossPerHitFraction, (Collider2D)(object)solidCollider); ((Component)this).gameObject.AddComponent().Configure(damageable, liftRoot, HelldiverClassRegistry.GetDefinition(sentryType).Color); HelldiverSentryGunPool.Warm(); } internal void BeginRetraction(double? syncedStartTime = null) { if (configured && !retracting) { HelldiverSentryLaserBeam.ClearVisual(seed); retracting = true; active = false; currentTarget = null; targetLockReadyTime = 0.0; nextTargetSearchTime = 0.0; hasLastSeenTargetPoint = false; retractStartTime = syncedStartTime ?? (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time); } } internal static void SpawnSyncedShot(HelldiverStratagemType sentryType, int ownerPlayerId, Vector2 spawnPoint, Vector2 direction) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) Player val = HolySmiteEffect.ResolvePlayerById(ownerPlayerId); if (val != null) { HelldiverSentryConfig helldiverSentryConfig = HelldiverSentryConfig.Get(sentryType); Color color = HelldiverClassRegistry.GetDefinition(sentryType).Color; if (HelldiverSentryGunPool.Configure(val, helldiverSentryConfig, color, direction)) { HelldiverSentryGunPool.Fire(val, spawnPoint, direction); } } } internal static void SpawnSyncedLaser(HelldiverStratagemType sentryType, int sentrySeed, int ownerPlayerId, Vector2 origin, Vector2 firstEnd, bool hasBounce, Vector2 secondEnd) { //IL_0006: 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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_0014: Unknown result type (might be due to invalid IL or missing references) Color color = HelldiverClassRegistry.GetDefinition(sentryType).Color; HelldiverSentryLaserBeam.SpawnVisual(sentrySeed, origin, firstEnd, hasBounce, secondEnd, color); } internal static void RetireSyncedSentry(int seed, double retireStartTime) { HelldiverMachineGunSentryController[] array = Object.FindObjectsOfType(); foreach (HelldiverMachineGunSentryController helldiverMachineGunSentryController in array) { if (helldiverMachineGunSentryController != null && helldiverMachineGunSentryController.Seed == seed) { helldiverMachineGunSentryController.BeginRetraction(retireStartTime); } } } internal static void ApplySyncedAim(int seed, float aimAngle) { HelldiverMachineGunSentryController[] array = Object.FindObjectsOfType(); foreach (HelldiverMachineGunSentryController helldiverMachineGunSentryController in array) { if (helldiverMachineGunSentryController != null && helldiverMachineGunSentryController.Seed == seed) { helldiverMachineGunSentryController.currentAimAngle = aimAngle; helldiverMachineGunSentryController.ApplyAimVisual(); } } } internal static void ApplySyncedSentryPlayerDamage(int ownerPlayerId, int targetPlayerId, Vector2 damage, Vector2 damagePoint, bool ignoreBlock) { //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) Player val = HolySmiteEffect.ResolvePlayerById(targetPlayerId); if (val?.data == null || val.data.dead || val.data.healthHandler == null) { return; } Player val2 = HolySmiteEffect.ResolvePlayerById(ownerPlayerId); object obj; if (val2 == null) { obj = null; } else { CharacterData data = val2.data; if (data == null) { obj = null; } else { WeaponHandler weaponHandler = data.weaponHandler; if (weaponHandler == null) { obj = null; } else { Gun gun = weaponHandler.gun; obj = ((gun != null) ? ((Component)gun).gameObject : null); } } } GameObject val3 = (GameObject)obj; ((Damagable)val.data.healthHandler).TakeDamage(damage, damagePoint, val3, val2, true, ignoreBlock); } internal static void BroadcastSentryPlayerDamage(Player owner, Player target, Vector2 damage, Vector2 damagePoint, bool ignoreBlock) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (target?.data != null && !target.data.dead && target.data.healthHandler != null && !(((Vector2)(ref damage)).sqrMagnitude <= 0.0001f)) { HelldiverRuntime.GetOrAdd(owner).BroadcastSentryPlayerDamage(owner.playerID, target.playerID, damage, damagePoint, ignoreBlock); } } internal static void BroadcastSentryRadialPlayerDamage(Vector2 center, float radius, float flatDamage, float percentageDamage, float edgeMultiplier, int ownerPlayerId, bool ignoreWalls, int ignoredPlayerId = -1) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: 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_0150: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) if (radius <= 0f || (flatDamage <= 0f && percentageDamage <= 0f)) { return; } Player val = HolySmiteEffect.ResolvePlayerById(ownerPlayerId); List list = PlayerManager.instance?.players; if (val == null || list == null) { return; } foreach (Player item in list) { if (item == null || item.data == null || item.data.dead || item.data.healthHandler == null || (ignoredPlayerId >= 0 && item.playerID == ignoredPlayerId) || !HelldiverStrikeController.CanAffectPlayer(item, center, ignoreWalls)) { continue; } Bounds val2 = (Bounds)((item.data.mainCol != null) ? item.data.mainCol.bounds : new Bounds(((Component)item).transform.position, Vector3.one)); float num = Vector2.Distance(Vector2.op_Implicit(((Bounds)(ref val2)).ClosestPoint(Vector2.op_Implicit(center))), center); if (num > radius) { continue; } float num2 = Mathf.Lerp(1f, Mathf.Clamp01(edgeMultiplier), (radius <= 0.0001f) ? 1f : (num / radius)); float num3 = (flatDamage + percentageDamage * item.data.maxHealth) * num2; if (!(num3 <= 0f)) { Vector2 val3 = Vector2.op_Implicit(((Component)item).transform.position) - center; if (((Vector2)(ref val3)).sqrMagnitude <= 0.0001f) { val3 = Vector2.up; } BroadcastSentryPlayerDamage(val, item, ((Vector2)(ref val3)).normalized * num3, center, ignoreBlock: false); } } } internal static void ApplySyncedSentryDamage(int seed, Vector2 damage, Vector2 damagePosition, int damagingPlayerId) { //IL_0001: 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) HelldiverSentryDamageable.ApplyOrBufferSyncedDamage(seed, damage, damagePosition, damagingPlayerId); } internal void HandleDestroyedByDamage(Vector2 damagePosition, Vector2 damage, Player? damagingPlayer) { //IL_0000: 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) HelldiverStrikeController.SpawnImpactFlash(damagePosition, HelldiverClassRegistry.GetDefinition(sentryType).Color); HelldiverSentryLaserBeam.ClearVisual(seed); Object.Destroy((Object)(object)((Component)this).gameObject); } private void Update() { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) if (!configured || liftRoot == null) { return; } double num = (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time); if (retracting) { UpdateRetraction(num); return; } if (!active) { float num2 = Mathf.Clamp01((float)((num - spawnTime) / 0.800000011920929)); liftRoot.localPosition = new Vector3(0f, Mathf.Lerp(-1.775f, 0f, SmoothStep(num2)), 0f); if (num2 < 1f) { return; } active = true; liftRoot.localPosition = Vector3.zero; nextFireTime = num; } UpdateTargeting(num); if (num >= activeStartTime + (double)config.LifetimeSeconds && IsOwnerAuthority()) { BroadcastRetired(num); } } private void UpdateTargeting(double now) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!IsOwnerAuthority()) { ApplyAimVisual(); return; } if (TryResolveTargetAimPoint(now, out var targetPoint, out var hasFreshLineOfSight)) { float clampedAimAngle = GetClampedAimAngle(targetPoint - GetBallCenter()); float aimAngleDeltaDegrees = GetAimAngleDeltaDegrees(currentAimAngle, clampedAimAngle); currentAimAngle = Mathf.MoveTowards(currentAimAngle, clampedAimAngle, GetResolvedAimSpeedDegreesPerSecond(aimAngleDeltaDegrees) * TimeHandler.deltaTime); aimAngleDeltaDegrees = GetAimAngleDeltaDegrees(currentAimAngle, clampedAimAngle); if (hasFreshLineOfSight && aimAngleDeltaDegrees <= config.TargetingAngleDegrees && now >= targetLockReadyTime) { lastShootAllowedUntil = Time.time + config.ContinueShootingSeconds; } } BroadcastAimIfNeeded(now); ApplyAimVisual(); if (Time.time <= lastShootAllowedUntil || HasActiveBurst()) { TryFire(now); } } private bool TryResolveTargetAimPoint(double now, out Vector2 targetPoint, out bool hasFreshLineOfSight) { //IL_0001: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: 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_00f2: Unknown result type (might be due to invalid IL or missing references) targetPoint = default(Vector2); hasFreshLineOfSight = false; if (currentTarget != null) { if (IsValidLockedTarget(currentTarget) && HasLineOfSight(currentTarget)) { targetPoint = GetTargetPoint(currentTarget); SetLastSeenTargetPoint(targetPoint); nextTargetSearchTime = 0.0; hasFreshLineOfSight = true; return true; } ArmNextTargetSearch(now); if (now < nextTargetSearchTime) { if (hasLastSeenTargetPoint) { targetPoint = lastSeenTargetPoint; return true; } return false; } ClearCurrentTarget(); } Player val = HolySmiteEffect.ResolvePlayerById(ownerPlayerId); List list = PlayerManager.instance?.players; if (val == null || list == null) { return false; } for (int i = 0; i < list.Count; i++) { Player val2 = list[i]; if (IsValidEnemy(val, val2) && IsWithinMechanicalRange(val2) && HasLineOfSight(val2)) { SetCurrentTarget(val2, now); targetPoint = GetTargetPoint(val2); SetLastSeenTargetPoint(targetPoint); hasFreshLineOfSight = true; return true; } } return false; } private void SetCurrentTarget(Player target, double now) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (currentTarget != null && currentTarget.playerID == target.playerID) { currentTarget = target; SetLastSeenTargetPoint(GetTargetPoint(target)); nextTargetSearchTime = 0.0; } else { currentTarget = target; targetLockReadyTime = now + (double)config.LockOnDelaySeconds; nextTargetSearchTime = 0.0; SetLastSeenTargetPoint(GetTargetPoint(target)); lastShootAllowedUntil = 0f; } } private void ClearCurrentTarget() { currentTarget = null; targetLockReadyTime = 0.0; nextTargetSearchTime = 0.0; hasLastSeenTargetPoint = false; lastShootAllowedUntil = 0f; } private void SetLastSeenTargetPoint(Vector2 targetPoint) { //IL_0001: 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) lastSeenTargetPoint = targetPoint; hasLastSeenTargetPoint = true; } private void ArmNextTargetSearch(double now) { if (nextTargetSearchTime <= 0.0) { nextTargetSearchTime = now + (double)config.LockOnDelaySeconds; } } private bool IsValidLockedTarget(Player? player) { if (IsValidEnemy(HolySmiteEffect.ResolvePlayerById(ownerPlayerId), player)) { return IsWithinLockedTargetRange(player); } return false; } private static bool IsValidEnemy(Player? owner, Player? player) { if (owner != null && player != null && player.data != null && !player.data.dead && player.data.healthHandler != null && player.playerID != owner.playerID) { if (!PhotonNetwork.OfflineMode) { return player.teamID != owner.teamID; } return true; } return false; } private bool IsWithinMechanicalRange(Player? player) { return IsWithinSentryAngle(player, config.MaxAimAngleDegrees); } private bool IsWithinLockedTargetRange(Player? player) { return IsWithinSentryAngle(player, config.MaxAimAngleDegrees + config.TargetingAngleDegrees); } private bool IsWithinSentryAngle(Player? player, float maximumAngleDegrees) { //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_0012: 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) if (player == null) { return false; } return Mathf.Abs(Vector2.SignedAngle(Vector2.up, GetTargetPoint(player) - GetBallCenter())) <= maximumAngleDegrees; } private bool HasLineOfSight(Player player) { //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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) Vector2 ballCenter = GetBallCenter(); Vector2 val = GetTargetPoint(player) - ballCenter; float magnitude = ((Vector2)(ref val)).magnitude; if (magnitude <= 0.0001f) { return true; } Vector2 val2 = val / magnitude; int num = ((PlayerManager.instance != null) ? ((LayerMask)(ref PlayerManager.instance.canSeePlayerMask)).value : (-1)); RaycastHit2D[] array = Physics2D.RaycastAll(ballCenter, val2, magnitude, num); Array.Sort(array, (RaycastHit2D a, RaycastHit2D b) => ((RaycastHit2D)(ref a)).distance.CompareTo(((RaycastHit2D)(ref b)).distance)); for (int i = 0; i < array.Length; i++) { Collider2D collider = ((RaycastHit2D)(ref array[i])).collider; if (collider == null || IsIgnoredLineOfSightCollider(collider)) { continue; } Player componentInParent = ((Component)collider).GetComponentInParent(); if (componentInParent != null) { if (componentInParent.playerID == player.playerID) { return true; } } else if (((Component)collider).GetComponentInParent() == null) { return false; } } return true; } private void TryFire(double now) { if (config.ConsumesAmmo && remainingAmmo <= 0) { BroadcastDepleted(); } else if (config.FireMode == HelldiverSentryFireMode.Laser) { if (!(now < nextFireTime)) { nextFireTime = now + (double)config.FireIntervalSeconds; FireLaserPulse(); } } else if (config.FireMode == HelldiverSentryFireMode.Burst) { TryFireBurst(now); } else if (!(now < nextFireTime)) { nextFireTime = now + (double)config.FireIntervalSeconds; FireSingleShot(); } } private void TryFireBurst(double now) { if (burstShotsRemaining <= 0) { if (now < nextFireTime) { return; } burstShotsRemaining = Mathf.Max(1, config.BurstCount); nextBurstShotTime = now; } if (!(now < nextBurstShotTime)) { FireSingleShot(); burstShotsRemaining--; if (burstShotsRemaining > 0 && remainingAmmo > 0) { nextBurstShotTime = now + (double)Mathf.Max(0.01f, config.BurstShotIntervalSeconds); return; } burstShotsRemaining = 0; nextFireTime = now + (double)config.FireIntervalSeconds; } } private bool HasActiveBurst() { if (config.FireMode == HelldiverSentryFireMode.Burst) { return burstShotsRemaining > 0; } return false; } private void FireSingleShot() { //IL_003a: 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_0044: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (config.ConsumesAmmo && remainingAmmo <= 0) { BroadcastDepleted(); return; } if (config.ConsumesAmmo) { remainingAmmo--; } Vector2 direction = ApplyBulletSpread(GetAimDirection()); Vector2 muzzlePoint = GetMuzzlePoint(direction); Player val = HolySmiteEffect.ResolvePlayerById(ownerPlayerId); if (val != null) { HelldiverRuntime.GetOrAdd(val).BroadcastSentryShot(sentryType, seed, ownerPlayerId, muzzlePoint, direction, currentAimAngle); } if (config.ConsumesAmmo && remainingAmmo <= 0) { BroadcastDepleted(); } } private void FireLaserPulse() { //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_0008: 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) //IL_000e: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_0063: Unknown result type (might be due to invalid IL or missing references) Vector2 aimDirection = GetAimDirection(); Vector2 muzzlePoint = GetMuzzlePoint(aimDirection); Player val = HolySmiteEffect.ResolvePlayerById(ownerPlayerId); if (val != null) { HelldiverSentryLaserResult helldiverSentryLaserResult = HelldiverSentryLaserBeam.FireAuthorityPulse(config, val, muzzlePoint, aimDirection, ((Component)this).transform); HelldiverRuntime.GetOrAdd(val).BroadcastSentryLaser(sentryType, seed, ownerPlayerId, helldiverSentryLaserResult.Origin, helldiverSentryLaserResult.FirstEnd, helldiverSentryLaserResult.HasBounce, helldiverSentryLaserResult.SecondEnd, currentAimAngle); } } private void BroadcastDepleted() { BroadcastRetired(PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time); } private void BroadcastRetired(double retireStartTime) { if (!depletionBroadcast) { depletionBroadcast = true; Player val = HolySmiteEffect.ResolvePlayerById(ownerPlayerId); if (val != null) { HelldiverRuntime.GetOrAdd(val).BroadcastSentryRetired(seed, retireStartTime); } } } private void BroadcastAimIfNeeded(double now) { if ((!(now < nextAimSyncTime) || float.IsNaN(lastBroadcastAimAngle)) && (float.IsNaN(lastBroadcastAimAngle) || !(Mathf.Abs(currentAimAngle - lastBroadcastAimAngle) < 0.5f))) { Player val = HolySmiteEffect.ResolvePlayerById(ownerPlayerId); if (val != null) { lastBroadcastAimAngle = currentAimAngle; nextAimSyncTime = now + 0.07999999821186066; HelldiverRuntime.GetOrAdd(val).BroadcastSentryAim(seed, currentAimAngle); } } } private void UpdateRetraction(double now) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) if (liftRoot == null) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } currentAimAngle = Mathf.MoveTowards(currentAimAngle, 0f, GetResolvedAimSpeedDegreesPerSecond() * 3f * TimeHandler.deltaTime); ApplyAimVisual(); float num = Mathf.Clamp01((float)((now - retractStartTime) / 0.800000011920929)); liftRoot.localPosition = new Vector3(0f, Mathf.Lerp(0f, -1.775f, SmoothStep(num)), 0f); if (num >= 1f) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void ApplyAimVisual() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (visual.GunPivot != null) { visual.GunPivot.localRotation = Quaternion.Euler(0f, 0f, currentAimAngle); } } private Vector2 GetBallCenter() { //IL_0025: 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_002a: Unknown result type (might be due to invalid IL or missing references) return Vector2.op_Implicit((visual.BallCenter == null) ? ((Component)this).transform.position : visual.BallCenter.position); } private Vector2 GetMuzzlePoint(Vector2 direction) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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) if (visual.BallCenter == null) { return Vector2.op_Implicit(((Component)this).transform.position) + direction * 0.65f; } Vector2 val = Vector2.op_Implicit(visual.BallCenter.position); Vector2 muzzleOffsetFromPivot = visual.MuzzleOffsetFromPivot; return val + direction * Mathf.Max(0.65f, ((Vector2)(ref muzzleOffsetFromPivot)).magnitude); } private Vector2 GetAimDirection() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) return Vector2.op_Implicit(Quaternion.Euler(0f, 0f, currentAimAngle) * Vector2.op_Implicit(Vector2.up)); } private Vector2 ApplyBulletSpread(Vector2 direction) { //IL_003c: 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) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (config.SpreadDegrees <= 0f) { return direction; } float num = Random.Range(0f - config.SpreadDegrees, config.SpreadDegrees); return Vector2.op_Implicit(Quaternion.Euler(0f, 0f, num) * Vector2.op_Implicit(((Vector2)(ref direction)).normalized)); } private Vector2 GetTargetPoint(Player player) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (player.data?.mainCol != null) { Bounds bounds = player.data.mainCol.bounds; return Vector2.op_Implicit(((Bounds)(ref bounds)).center); } return Vector2.op_Implicit(((Component)player).transform.position); } private float GetClampedAimAngle(Vector2 direction) { //IL_0015: 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) if (((Vector2)(ref direction)).sqrMagnitude <= 0.0001f) { return currentAimAngle; } return Mathf.Clamp(Vector2.SignedAngle(Vector2.up, ((Vector2)(ref direction)).normalized), 0f - config.MaxAimAngleDegrees, config.MaxAimAngleDegrees); } private int GetResolvedMaxAmmo() { Player? obj = HolySmiteEffect.ResolvePlayerById(ownerPlayerId); float valueOrDefault = ((obj == null) ? null : ((Component)obj).GetComponent()?.GetSentryAmmoMultiplier()).GetValueOrDefault(1f); return Mathf.Max(1, Mathf.RoundToInt((float)config.MaxAmmo * valueOrDefault)); } private float GetResolvedMaxHealth() { Player? obj = HolySmiteEffect.ResolvePlayerById(ownerPlayerId); float valueOrDefault = ((obj == null) ? null : ((Component)obj).GetComponent()?.GetSentryHealthMultiplier()).GetValueOrDefault(1f); return Mathf.Max(1f, config.Health * valueOrDefault); } private float GetResolvedAimSpeedDegreesPerSecond(float angleDeltaDegrees = 0f) { Player? obj = HolySmiteEffect.ResolvePlayerById(ownerPlayerId); float valueOrDefault = ((obj == null) ? null : ((Component)obj).GetComponent()?.GetSentryTargetingSpeedMultiplier()).GetValueOrDefault(1f); return config.AimSpeedDegreesPerSecond * Mathf.Max(0.01f, valueOrDefault) * GetAimErrorSpeedMultiplier(angleDeltaDegrees); } private float GetAimErrorSpeedMultiplier(float angleDeltaDegrees) { float num = Mathf.InverseLerp(config.TargetingAngleDegrees, 180f, Mathf.Clamp(angleDeltaDegrees, config.TargetingAngleDegrees, 180f)); return Mathf.Lerp(1f, 6f, Mathf.Pow(num, 2f)); } private static float GetAimAngleDeltaDegrees(float currentAngle, float desiredAngle) { return Mathf.Abs(desiredAngle - currentAngle); } private bool IsOwnerAuthority() { if (PhotonNetwork.OfflineMode) { return true; } Player val = HolySmiteEffect.ResolvePlayerById(ownerPlayerId); if (val?.data?.view != null) { return val.data.view.IsMine; } return false; } private bool IsIgnoredLineOfSightCollider(Collider2D collider) { if (!collider.isTrigger && !((Object)(object)((Component)collider).transform == (Object)(object)((Component)this).transform) && !((Component)collider).transform.IsChildOf(((Component)this).transform) && ((Component)collider).GetComponentInParent() == null) { return ((Component)collider).GetComponentInParent() != null; } return true; } private static BoxCollider2D CreateSolidCollider(GameObject target) { //IL_001c: 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) target.layer = HelldiverHellpodController.ResolveSolidLayer(); BoxCollider2D obj = target.AddComponent(); obj.size = new Vector2(1.35f, 1.775f); ((Collider2D)obj).offset = new Vector2(0f, 0.8875f); return obj; } private static float SmoothStep(float value) { value = Mathf.Clamp01(value); return value * value * (3f - 2f * value); } } internal static class HelldiverPrecisionGunPool { private static readonly Dictionary sharedGuns = new Dictionary(); private static Gun? defaultGunTemplate; private static float? defaultProjectileBaseDamage; internal static void Warm(HelldiverShellImpactMode mode = HelldiverShellImpactMode.ImmediateExplosion) { GetOrCreateSharedGun(mode); } internal static void Invalidate() { foreach (SimulatedGun value in sharedGuns.Values) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)((Component)value).gameObject); } } sharedGuns.Clear(); defaultGunTemplate = null; defaultProjectileBaseDamage = null; } internal static bool Configure(Player owner, float directDamage, float percentageDamage, HelldiverShellImpactConfig impactConfig) { //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) HelldiverShellImpactConfig impactConfig2 = impactConfig; if (owner.data == null) { return false; } SimulatedGun orCreateSharedGun = GetOrCreateSharedGun(impactConfig2.Mode); Gun val = GetDefaultGunTemplate(); if (orCreateSharedGun == null || val == null) { return false; } orCreateSharedGun.CopyGunStatsExceptActions(val); ((Gun)orCreateSharedGun).player = owner; ((Gun)orCreateSharedGun).damage = directDamage / GetDefaultProjectileBaseDamage(); ((Gun)orCreateSharedGun).percentageDamage = percentageDamage; ((Gun)orCreateSharedGun).knockback = 0f; ((Gun)orCreateSharedGun).slow = 0f; ((Gun)orCreateSharedGun).spread = 0f; ((Gun)orCreateSharedGun).evenSpread = 0f; ((Gun)orCreateSharedGun).numberOfProjectiles = 1; ((Gun)orCreateSharedGun).bursts = 1; ((Gun)orCreateSharedGun).timeBetweenBullets = 0f; ((Gun)orCreateSharedGun).drag = 0f; ((Gun)orCreateSharedGun).dragMinSpeed = 0f; ((Gun)orCreateSharedGun).gravity = 0f; ((Gun)orCreateSharedGun).projectileSpeed = 1f; ((Gun)orCreateSharedGun).projectielSimulatonSpeed = 1f; ((Gun)orCreateSharedGun).shake = 0f; ((Gun)orCreateSharedGun).shakeM = 0f; ((Gun)orCreateSharedGun).forceSpecificShake = true; ((Gun)orCreateSharedGun).ignoreWalls = true; ((Gun)orCreateSharedGun).destroyBulletAfter = 4f; ((Gun)orCreateSharedGun).projectileColor = impactConfig2.Color; ((Gun)orCreateSharedGun).ShootPojectileAction = delegate { }; ((Gun)orCreateSharedGun).ShootPojectileAction = (Action)Delegate.Combine(((Gun)orCreateSharedGun).ShootPojectileAction, (Action)delegate(GameObject bullet) { HelldiverPrecisionProjectileController helldiverPrecisionProjectileController = bullet.GetComponent(); if (helldiverPrecisionProjectileController == null) { helldiverPrecisionProjectileController = bullet.AddComponent(); } ProjectileHit component = bullet.GetComponent(); if (component != null) { component.fullSelfDamage = true; component.holdPlayerFor = 0f; component.destroyOnBlock = true; component.force = 0f; component.shake = 0f; component.movementSlow = 0f; } RayCastTrail component2 = bullet.GetComponent(); if (component2 != null) { component2.teamID = -1; component2.timeAtSpawn = 0f; } helldiverPrecisionProjectileController.Configure(impactConfig2); }); return true; } internal static bool Fire(Player owner, Vector2 spawnPoint, HelldiverShellImpactMode mode = HelldiverShellImpactMode.ImmediateExplosion) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (owner.data == null) { return false; } SimulatedGun orCreateSharedGun = GetOrCreateSharedGun(mode); if (orCreateSharedGun == null) { return false; } return orCreateSharedGun.SimulatedAttack(owner.playerID, Vector2.op_Implicit(spawnPoint), Vector3.down, 0f, 1f, (Transform)null, false); } private static SimulatedGun? GetOrCreateSharedGun(HelldiverShellImpactMode mode) { //IL_002a: 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) //IL_0035: Expected O, but got Unknown if (sharedGuns.TryGetValue(mode, out SimulatedGun value) && (Object)(object)value != (Object)null) { return value; } GameObject val = new GameObject($"DOLY_HelldiverPrecisionGun_{mode}"); Object.DontDestroyOnLoad((Object)val); SimulatedGun val2 = val.AddComponent(); sharedGuns[mode] = val2; return val2; } private static Gun? GetDefaultGunTemplate() { if ((Object)(object)defaultGunTemplate != (Object)null) { return defaultGunTemplate; } GameObject val = Resources.Load("Player"); if (val == null) { return null; } Holdable val2 = val.GetComponent()?.holdable; defaultGunTemplate = ((val2 != null) ? ((Component)val2).GetComponent() : null); return defaultGunTemplate; } private static float GetDefaultProjectileBaseDamage() { if (defaultProjectileBaseDamage.HasValue) { return defaultProjectileBaseDamage.Value; } ProjectilesToSpawn[] array = GetDefaultGunTemplate()?.projectiles; GameObject obj = ((array != null && array.Length > 0) ? array[0].objectToSpawn : null); float valueOrDefault = ((obj == null) ? null : obj.GetComponent()?.damage).GetValueOrDefault(1f); defaultProjectileBaseDamage = Mathf.Max(0.0001f, valueOrDefault); return defaultProjectileBaseDamage.Value; } } internal sealed class HelldiverPrecisionProjectileController : MonoBehaviour { private HelldiverShellImpactConfig? impactConfig; private LayerMask defaultRayMask; private bool configured; private bool defaultRayMaskCaptured; private bool hitHooked; private bool wallsUnlocked; private bool resolved; private MoveTransform? moveTransform; private ProjectileHit? projectileHit; private RayCastTrail? rayCastTrail; private SpawnedAttack? spawnedAttack; private Rigidbody2D? rigidbody2D; internal void Configure(HelldiverShellImpactConfig impactConfig) { //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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) this.impactConfig = impactConfig; configured = false; wallsUnlocked = false; resolved = false; if (moveTransform != null) { ((Behaviour)moveTransform).enabled = true; moveTransform.velocity = Vector3.zero; } if (projectileHit != null) { ((Behaviour)projectileHit).enabled = true; } if (rayCastTrail != null && defaultRayMaskCaptured) { rayCastTrail.mask = defaultRayMask; } if (rigidbody2D != null) { rigidbody2D.velocity = Vector2.zero; rigidbody2D.angularVelocity = 0f; } TryApplyConfiguration(); } private void Update() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) if (!configured) { TryApplyConfiguration(); } if (!configured) { return; } HelldiverShellImpactConfig helldiverShellImpactConfig = impactConfig; if (helldiverShellImpactConfig == null) { return; } if (!wallsUnlocked && ((Component)this).transform.position.y <= helldiverShellImpactConfig.UnlockDepthY) { wallsUnlocked = true; if (rayCastTrail != null) { rayCastTrail.mask = ((PlayerManager.instance != null) ? PlayerManager.instance.canSeePlayerMask : LayerMask.op_Implicit(-1)); } } if (moveTransform != null) { Vector2 flightDirection = helldiverShellImpactConfig.FlightDirection; Vector2 val; if (!(((Vector2)(ref flightDirection)).sqrMagnitude > 0.0001f)) { val = Vector2.down; } else { flightDirection = helldiverShellImpactConfig.FlightDirection; val = ((Vector2)(ref flightDirection)).normalized; } Vector2 val2 = val; moveTransform.velocity = Vector2.op_Implicit(val2 * helldiverShellImpactConfig.Speed); ((Component)this).transform.rotation = Quaternion.LookRotation(Vector2.op_Implicit(val2), Vector3.forward); } } private void TryApplyConfiguration() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) if (moveTransform == null) { moveTransform = ((Component)this).GetComponent(); } if (projectileHit == null) { projectileHit = ((Component)this).GetComponent(); } if (rayCastTrail == null) { rayCastTrail = ((Component)this).GetComponent(); } if (spawnedAttack == null) { spawnedAttack = ((Component)this).GetComponent(); } if (rigidbody2D == null) { rigidbody2D = ((Component)this).GetComponent(); } if (!defaultRayMaskCaptured && rayCastTrail != null) { defaultRayMask = rayCastTrail.mask; defaultRayMaskCaptured = true; } if (impactConfig == null || moveTransform == null || projectileHit == null || rayCastTrail == null) { return; } if (!hitHooked) { projectileHit.AddHitActionWithData((Action)HandleImpact); hitHooked = true; } if (!configured) { configured = true; moveTransform.gravity = 0f; moveTransform.drag = 0f; moveTransform.dragMinSpeed = 0f; moveTransform.simulateGravity = 0; moveTransform.localForce = Vector3.zero; moveTransform.worldForce = Vector3.zero; Vector2 flightDirection = impactConfig.FlightDirection; Vector2 val; if (!(((Vector2)(ref flightDirection)).sqrMagnitude > 0.0001f)) { val = Vector2.down; } else { flightDirection = impactConfig.FlightDirection; val = ((Vector2)(ref flightDirection)).normalized; } Vector2 val2 = val; moveTransform.velocity = Vector2.op_Implicit(val2 * impactConfig.Speed); if (rigidbody2D != null) { rigidbody2D.gravityScale = 0f; rigidbody2D.drag = 0f; rigidbody2D.velocity = val2 * impactConfig.Speed; } ((Component)this).transform.rotation = Quaternion.LookRotation(Vector2.op_Implicit(val2), Vector3.forward); rayCastTrail.MoveRay(); } } private void HandleImpact(HitInfo hitInfo) { //IL_0037: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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) if (!resolved && impactConfig != null) { resolved = true; Vector2 val = ((((Vector2)(ref hitInfo.normal)).sqrMagnitude > 0.0001f) ? ((Vector2)(ref hitInfo.normal)).normalized : Vector2.up); Vector2 impactPoint = hitInfo.point + val * impactConfig.ExplosionSurfaceOffset; ResolveImpact(impactPoint, val, -1, useVanillaExplosionDamage: true); } } internal void HandleBlocked(Player blocker, Vector2 hitPoint, Vector2 incomingDirection) { //IL_002f: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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) if (!resolved && impactConfig != null) { resolved = true; Vector2 val = ((((Vector2)(ref incomingDirection)).sqrMagnitude > 0.0001f) ? (-((Vector2)(ref incomingDirection)).normalized) : Vector2.up); Vector2 impactPoint = hitPoint + val * impactConfig.ExplosionSurfaceOffset; ResolveImpact(impactPoint, val, blocker.playerID, useVanillaExplosionDamage: false); } } private void ResolveImpact(Vector2 impactPoint, Vector2 normal, int ignoredPlayerId, bool useVanillaExplosionDamage) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) switch (impactConfig.Mode) { case HelldiverShellImpactMode.GasCloud: TriggerGasCloud(impactPoint); break; case HelldiverShellImpactMode.EmsField: TriggerEmsField(impactPoint); break; case HelldiverShellImpactMode.Eagle500kg: TriggerEagleBomb(impactPoint, normal, ignoredPlayerId); break; case HelldiverShellImpactMode.DelayedExplosion: TriggerDelayedExplosion(impactPoint, ignoredPlayerId); break; default: TriggerExplosion(impactPoint, useVanillaExplosionDamage, ignoredPlayerId); break; } } private void TriggerExplosion(Vector2 explosionPoint, bool useVanillaExplosionDamage, int ignoredPlayerId) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) HelldiverStrikeController.SpawnImpactFlash(explosionPoint, impactConfig.Color); HelldiverDelayedExplosionPayload helldiverDelayedExplosionPayload = new GameObject("DOLY_HelldiverImmediateExplosion").AddComponent(); float explosionRadius = impactConfig.ExplosionRadius; float explosionDamage = impactConfig.ExplosionDamage; float explosionPercentDamage = impactConfig.ExplosionPercentDamage; float explosionEdgeDamageMultiplier = impactConfig.ExplosionEdgeDamageMultiplier; int ownerPlayerId = impactConfig.OwnerPlayerId; SpawnedAttack? obj = spawnedAttack; helldiverDelayedExplosionPayload.Configure(explosionPoint, explosionRadius, explosionDamage, explosionPercentDamage, explosionEdgeDamageMultiplier, 0.01f, ownerPlayerId, ignoredPlayerId, ignoreWalls: false, obj != null && obj.IsMine(), impactConfig.ExplosionPresentationSize, impactConfig.ExplosionSoundSize, impactConfig.ExplosionSoundVolumeMultiplier, impactConfig.Color, 0f, 0f, 0f); } private void TriggerGasCloud(Vector2 impactPoint) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) if (ShouldBroadcastSyncedPayload()) { ResolveOwnerRuntime()?.BroadcastGasCloudPayload(impactPoint, impactConfig.GasRadius, impactConfig.GasDuration, impactConfig.GasTickInterval, impactConfig.GasTickDamage, impactConfig.GasTickPercentDamage, impactConfig.GasSlowAmount, impactConfig.OwnerPlayerId, impactConfig.Color); } } private void TriggerEmsField(Vector2 impactPoint) { //IL_0014: 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) if (ShouldBroadcastSyncedPayload()) { ResolveOwnerRuntime()?.BroadcastEmsFieldPayload(impactPoint, impactConfig.EmsRadius, impactConfig.EmsDuration, impactConfig.EmsInitialStunDuration, impactConfig.EmsSlowAmount, impactConfig.Color); } } private void TriggerDelayedExplosion(Vector2 impactPoint, int ignoredPlayerId) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) HelldiverStrikeController.SpawnImpactFlash(impactPoint, impactConfig.Color); HelldiverDelayedExplosionPayload helldiverDelayedExplosionPayload = new GameObject("DOLY_HelldiverDelayedExplosion").AddComponent(); float explosionRadius = impactConfig.ExplosionRadius; float explosionDamage = impactConfig.ExplosionDamage; float explosionPercentDamage = impactConfig.ExplosionPercentDamage; float explosionEdgeDamageMultiplier = impactConfig.ExplosionEdgeDamageMultiplier; float detonationDelaySeconds = impactConfig.DetonationDelaySeconds; int valueOrDefault = (spawnedAttack?.spawner?.playerID).GetValueOrDefault(-1); SpawnedAttack? obj = spawnedAttack; helldiverDelayedExplosionPayload.Configure(impactPoint, explosionRadius, explosionDamage, explosionPercentDamage, explosionEdgeDamageMultiplier, detonationDelaySeconds, valueOrDefault, ignoredPlayerId, ignoreWalls: false, obj != null && obj.IsMine(), impactConfig.ExplosionPresentationSize, impactConfig.ExplosionSoundSize, impactConfig.ExplosionSoundVolumeMultiplier, impactConfig.Color, impactConfig.LodgedShellLength, impactConfig.LodgedShellWidth, impactConfig.LodgedShellAngleDegrees); } private void TriggerEagleBomb(Vector2 impactPoint, Vector2 normal, int ignoredPlayerId) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_0020: 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) HelldiverStrikeController.SpawnImpactFlash(impactPoint, impactConfig.Color); HelldiverEagleBombPayload helldiverEagleBombPayload = new GameObject("DOLY_HelldiverEagleBomb").AddComponent(); float explosionRadius = impactConfig.ExplosionRadius; float explosionDamage = impactConfig.ExplosionDamage; float explosionPercentDamage = impactConfig.ExplosionPercentDamage; float explosionEdgeDamageMultiplier = impactConfig.ExplosionEdgeDamageMultiplier; float detonationDelaySeconds = impactConfig.DetonationDelaySeconds; int valueOrDefault = (spawnedAttack?.spawner?.playerID).GetValueOrDefault(-1); SpawnedAttack? obj = spawnedAttack; helldiverEagleBombPayload.Configure(impactPoint, normal, explosionRadius, explosionDamage, explosionPercentDamage, explosionEdgeDamageMultiplier, detonationDelaySeconds, valueOrDefault, ignoredPlayerId, ignoreWalls: false, obj != null && obj.IsMine(), impactConfig.ExplosionPresentationSize, impactConfig.ExplosionSoundSize, impactConfig.ExplosionSoundVolumeMultiplier, impactConfig.LodgedShellLength, impactConfig.LodgedShellWidth); } private bool ShouldBroadcastSyncedPayload() { if (!PhotonNetwork.OfflineMode) { SpawnedAttack? obj = spawnedAttack; if (obj == null) { return false; } return obj.IsMine(); } return true; } private HelldiverRuntime? ResolveOwnerRuntime() { Player val = ResolvePlayerById(impactConfig?.OwnerPlayerId ?? (spawnedAttack?.spawner?.playerID).GetValueOrDefault(-1)); if (val != null) { return HelldiverRuntime.GetOrAdd(val); } return null; } private static Player? ResolvePlayerById(int playerId) { List list = PlayerManager.instance?.players; if (list == null) { return null; } foreach (Player item in list) { if (item != null && item.playerID == playerId) { return item; } } return null; } } internal sealed class HelldiverReadyGlow : MonoBehaviour { private const int SegmentCount = 72; private const float VisibilitySpeed = 9f; private const float RingPadding = 0.34f; private const float RingWidth = 0.13f; private const float PulseWidth = 0.026f; private const float BaseAlpha = 0.2f; private readonly Vector3[] ringPositions = (Vector3[])(object)new Vector3[73]; private CharacterData? ownerData; private LineRenderer? ringRenderer; private Material? ringMaterial; private Color targetColor = new Color(0.48f, 0.86f, 1f, 1f); private float targetVisibility; private float visibility; internal void Bind(CharacterData data) { ownerData = data; EnsureRenderer(); } internal void SetState(bool isArmed, Color color) { //IL_0016: 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) targetVisibility = (isArmed ? 1f : 0f); targetColor = color; } internal void SetArmed(bool isArmed) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) SetState(isArmed, new Color(0.48f, 0.86f, 1f, 1f)); } private void LateUpdate() { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_009b: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) if (ownerData == null) { ownerData = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); } if (ownerData == null) { return; } EnsureRenderer(); if (ringRenderer == null) { return; } visibility = Mathf.MoveTowards(visibility, targetVisibility, TimeHandler.deltaTime * 9f); if (visibility <= 0.001f) { ((Renderer)ringRenderer).enabled = false; return; } ((Renderer)ringRenderer).enabled = true; Bounds val = (Bounds)((ownerData.mainCol != null) ? ownerData.mainCol.bounds : new Bounds(((Component)this).transform.position, Vector3.one)); Vector3 center = ((Bounds)(ref val)).center; float num = ((Bounds)(ref val)).extents.x + 0.34f; float num2 = ((Bounds)(ref val)).extents.y + 0.34f; float num3 = 0.5f + 0.5f * Mathf.Sin(Time.time * 6.5f); for (int i = 0; i <= 72; i++) { float num4 = (float)i / 72f; float num5 = MathF.PI / 2f - num4 * MathF.PI * 2f; ringPositions[i] = center + new Vector3(Mathf.Cos(num5) * num, Mathf.Sin(num5) * num2, 0f); } Color val2 = targetColor; val2.a = (0.2f + num3 * 0.08f) * visibility; float num6 = 0.13f + 0.026f * num3 * visibility; ringRenderer.positionCount = 73; ringRenderer.SetPositions(ringPositions); ringRenderer.startWidth = num6; ringRenderer.endWidth = num6; ringRenderer.startColor = val2; ringRenderer.endColor = val2; } private void OnDestroy() { if (ringMaterial != null) { Object.Destroy((Object)(object)ringMaterial); } } private void EnsureRenderer() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_002c: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown if (ringRenderer == null) { GameObject val = new GameObject("HelldiverReadyGlow"); val.transform.SetParent(((Component)this).transform, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; ringRenderer = val.AddComponent(); ringMaterial = new Material(Shader.Find("Sprites/Default")); ((Renderer)ringRenderer).material = ringMaterial; ringRenderer.useWorldSpace = true; ringRenderer.loop = false; ringRenderer.positionCount = 0; ringRenderer.numCapVertices = 8; ringRenderer.numCornerVertices = 8; ringRenderer.textureMode = (LineTextureMode)0; ringRenderer.alignment = (LineAlignment)0; ((Renderer)ringRenderer).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)ringRenderer).receiveShadows = false; ((Renderer)ringRenderer).sortingOrder = 1260; ((Renderer)ringRenderer).enabled = false; } } } internal sealed class HelldiverRuntime : MonoBehaviour { private sealed class PendingBeaconDeployment { internal Vector2 SettledPosition { get; } internal int StuckPlayerId { get; } internal Vector2 StuckOffset { get; } internal double DeployTime { get; } internal double ExecuteTime { get; } internal PendingBeaconDeployment(Vector2 settledPosition, int stuckPlayerId, Vector2 stuckOffset, double deployTime, double executeTime) { //IL_0007: 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_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) SettledPosition = settledPosition; StuckPlayerId = stuckPlayerId; StuckOffset = stuckOffset; DeployTime = deployTime; ExecuteTime = executeTime; } } private static readonly Dictionary StratagemsByCardName = new Dictionary { ["Helldiver"] = HelldiverStratagemType.OrbitalPrecisionStrike, ["Orbital Gatling Barrage"] = HelldiverStratagemType.OrbitalGatlingBarrage, ["Orbital EMS Strike"] = HelldiverStratagemType.OrbitalEmsStrike, ["Orbital 120mm HE Barrage"] = HelldiverStratagemType.Orbital120mmHEBarrage, ["Orbital 380mm HE Barrage"] = HelldiverStratagemType.Orbital380mmHEBarrage, ["Orbital Gas Strike"] = HelldiverStratagemType.OrbitalGasStrike, ["Eagle 500kg Bomb"] = HelldiverStratagemType.Eagle500kgBomb, ["Eagle Strafing Run"] = HelldiverStratagemType.EagleStrafingRun, ["Eagle Airstrike"] = HelldiverStratagemType.EagleAirstrike, ["Eagle Cluster Bomb"] = HelldiverStratagemType.EagleClusterBomb, ["Eagle Rearm"] = HelldiverStratagemType.EagleRearm, ["A/MG-43 Machine Gun Sentry"] = HelldiverStratagemType.MachineGunSentry, ["A/MLS-4X Rocket Sentry"] = HelldiverStratagemType.RocketSentry, ["A/AC-8 Autocannon Sentry"] = HelldiverStratagemType.AutocannonSentry, ["A/G-16 Gatling Sentry"] = HelldiverStratagemType.GatlingSentry, ["A/LAS-98 Laser Sentry"] = HelldiverStratagemType.LaserSentry }; private CharacterData? ownerData; private Player? ownerPlayer; private HelldiverEffect? effect; private int lastCardFingerprint = int.MinValue; private readonly Dictionary trackedBeacons = new Dictionary(); private readonly Dictionary bufferedBeaconDeployments = new Dictionary(); private readonly HashSet bufferedBeaconCancellations = new HashSet(); internal static HelldiverRuntime GetOrAdd(Player player) { return ((Component)player).gameObject.GetOrAddComponent(); } private void Start() { ResolveOwner(); SynchronizeFromCards(force: true); } private void Update() { ResolveOwner(); SynchronizeFromCards(force: false); } internal void BroadcastSpawnHelldiverBeacon(HelldiverStratagemType type, Vector2 position, Vector2 velocity, float gravity, float callInDelaySeconds, int seed, int ownerPlayerId) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) ResolveOwner(); if (ownerData?.view != null) { double num = (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time); if (PhotonNetwork.OfflineMode) { RPCA_SpawnHelldiverBeacon((int)type, position.x, position.y, velocity.x, velocity.y, gravity, callInDelaySeconds, seed, ownerPlayerId, num); return; } ownerData.view.RPC("RPCA_SpawnHelldiverBeacon", (RpcTarget)0, new object[10] { (int)type, position.x, position.y, velocity.x, velocity.y, gravity, callInDelaySeconds, seed, ownerPlayerId, num }); } } internal void BroadcastExecute(HelldiverStratagemType type, Vector2 point, Vector2 runDirection, int seed, double executeTime) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0030: 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) ResolveOwner(); if (ownerData?.view != null) { if (PhotonNetwork.OfflineMode) { RPCA_ExecuteHelldiverStratagem((int)type, point.x, point.y, runDirection.x, runDirection.y, seed, ownerPlayer?.playerID ?? (-1), executeTime); return; } ownerData.view.RPC("RPCA_ExecuteHelldiverStratagem", (RpcTarget)0, new object[8] { (int)type, point.x, point.y, runDirection.x, runDirection.y, seed, ownerPlayer?.playerID ?? (-1), executeTime }); } } internal void BroadcastSpawnSentryHellpod(HelldiverStratagemType sentryType, int ownerPlayerId, int sentrySeed, Vector2 fallStart, Vector2 landingPoint, double startTime) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) ResolveOwner(); if (PhotonNetwork.OfflineMode) { RPCA_SpawnSentryHellpod((int)sentryType, ownerPlayerId, sentrySeed, fallStart.x, fallStart.y, landingPoint.x, landingPoint.y, startTime); } else if (ownerData?.view != null) { ownerData.view.RPC("RPCA_SpawnSentryHellpod", (RpcTarget)0, new object[8] { (int)sentryType, ownerPlayerId, sentrySeed, fallStart.x, fallStart.y, landingPoint.x, landingPoint.y, startTime }); } } internal void BroadcastDeployHelldiverBeacon(HelldiverStratagemType type, int beaconSeed, Vector2 settledPosition, int stuckPlayerId, Vector2 stuckOffset, double deployTime, double executeTime) { //IL_0008: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) ResolveOwner(); ApplyHelldiverBeaconDeployment(beaconSeed, settledPosition, stuckPlayerId, stuckOffset, deployTime, executeTime); if (!PhotonNetwork.OfflineMode && ownerData?.view != null) { ownerData.view.RPC("RPCA_DeployHelldiverBeacon", (RpcTarget)1, new object[9] { (int)type, beaconSeed, settledPosition.x, settledPosition.y, stuckPlayerId, stuckOffset.x, stuckOffset.y, deployTime, executeTime }); } } internal void BroadcastCancelHelldiverBeacon(int beaconSeed) { ResolveOwner(); CancelHelldiverBeacon(beaconSeed); if (!PhotonNetwork.OfflineMode && ownerData?.view != null) { ownerData.view.RPC("RPCA_CancelHelldiverBeacon", (RpcTarget)1, new object[1] { beaconSeed }); } } internal void BroadcastGasCloudPayload(Vector2 center, float radius, float duration, float tickInterval, float flatDamage, float percentageDamage, float slowAmount, int damageOwnerPlayerId, Color flashColor) { //IL_001b: 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_0066: 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_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) ResolveOwner(); double num = (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time); SpawnGasCloudPayload(center, radius, duration, tickInterval, flatDamage, percentageDamage, slowAmount, damageOwnerPlayerId, flashColor, num); if (!PhotonNetwork.OfflineMode && ownerData?.view != null) { ownerData.view.RPC("RPCA_SpawnHelldiverGasCloud", (RpcTarget)1, new object[14] { center.x, center.y, radius, duration, tickInterval, flatDamage, percentageDamage, slowAmount, damageOwnerPlayerId, flashColor.r, flashColor.g, flashColor.b, flashColor.a, num }); } } internal void BroadcastEmsFieldPayload(Vector2 center, float radius, float duration, float initialStunDuration, float slowAmount, Color flashColor) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) ResolveOwner(); double num = (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time); SpawnEmsFieldPayload(center, radius, duration, initialStunDuration, slowAmount, flashColor, num); if (!PhotonNetwork.OfflineMode && ownerData?.view != null) { ownerData.view.RPC("RPCA_SpawnHelldiverEmsField", (RpcTarget)1, new object[11] { center.x, center.y, radius, duration, initialStunDuration, slowAmount, flashColor.r, flashColor.g, flashColor.b, flashColor.a, num }); } } internal void BroadcastSentryAim(int sentrySeed, float aimAngle) { ResolveOwner(); if (PhotonNetwork.OfflineMode) { RPCA_SetSentryAim(sentrySeed, aimAngle); } else if (ownerData?.view != null) { ownerData.view.RPC("RPCA_SetSentryAim", (RpcTarget)1, new object[2] { sentrySeed, aimAngle }); } } internal void BroadcastSentryShot(HelldiverStratagemType sentryType, int sentrySeed, int ownerPlayerId, Vector2 spawnPoint, Vector2 direction, float aimAngle) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) ResolveOwner(); if (PhotonNetwork.OfflineMode) { RPCA_FireSentryShot((int)sentryType, sentrySeed, ownerPlayerId, spawnPoint.x, spawnPoint.y, direction.x, direction.y, aimAngle); } else if (ownerData?.view != null) { ownerData.view.RPC("RPCA_FireSentryShot", (RpcTarget)0, new object[8] { (int)sentryType, sentrySeed, ownerPlayerId, spawnPoint.x, spawnPoint.y, direction.x, direction.y, aimAngle }); } } internal void BroadcastSentryRetired(int seed, double retireStartTime) { ResolveOwner(); if (PhotonNetwork.OfflineMode) { RPCA_RetireSentry(seed, retireStartTime); } else if (ownerData?.view != null) { ownerData.view.RPC("RPCA_RetireSentry", (RpcTarget)0, new object[2] { seed, retireStartTime }); } } internal void BroadcastSentryPlayerDamage(int ownerPlayerId, int targetPlayerId, Vector2 damage, Vector2 damagePoint, bool ignoreBlock) { //IL_0010: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) ResolveOwner(); if (PhotonNetwork.OfflineMode) { RPCA_DamagePlayerFromSentry(ownerPlayerId, targetPlayerId, damage.x, damage.y, damagePoint.x, damagePoint.y, ignoreBlock); } else if (ownerData?.view != null) { ownerData.view.RPC("RPCA_DamagePlayerFromSentry", (RpcTarget)0, new object[7] { ownerPlayerId, targetPlayerId, damage.x, damage.y, damagePoint.x, damagePoint.y, ignoreBlock }); } } internal void BroadcastSentryDamaged(int seed, Vector2 damage, Vector2 damagePoint, int damagingPlayerId) { //IL_0007: 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_004e: 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) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) ResolveOwner(); HelldiverMachineGunSentryController.ApplySyncedSentryDamage(seed, damage, damagePoint, damagingPlayerId); if (!PhotonNetwork.OfflineMode && ownerData?.view != null) { ownerData.view.RPC("RPCA_DamageSentry", (RpcTarget)1, new object[6] { seed, damage.x, damage.y, damagePoint.x, damagePoint.y, damagingPlayerId }); } } internal void BroadcastHellpodDamaged(int seed, Vector2 damage, Vector2 damagePoint, int damagingPlayerId) { //IL_0007: 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_004e: 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) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) ResolveOwner(); HelldiverHellpodDamageable.ApplyOrBufferSyncedDamage(seed, damage, damagePoint, damagingPlayerId); if (!PhotonNetwork.OfflineMode && ownerData?.view != null) { ownerData.view.RPC("RPCA_DamageHellpod", (RpcTarget)1, new object[6] { seed, damage.x, damage.y, damagePoint.x, damagePoint.y, damagingPlayerId }); } } internal void BroadcastSentryLaser(HelldiverStratagemType sentryType, int sentrySeed, int ownerPlayerId, Vector2 origin, Vector2 firstEnd, bool hasBounce, Vector2 secondEnd, float aimAngle) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) ResolveOwner(); if (PhotonNetwork.OfflineMode) { RPCA_DrawSentryLaser((int)sentryType, sentrySeed, ownerPlayerId, origin.x, origin.y, firstEnd.x, firstEnd.y, hasBounce, secondEnd.x, secondEnd.y, aimAngle); } else if (ownerData?.view != null) { ownerData.view.RPC("RPCA_DrawSentryLaser", (RpcTarget)0, new object[11] { (int)sentryType, sentrySeed, ownerPlayerId, origin.x, origin.y, firstEnd.x, firstEnd.y, hasBounce, secondEnd.x, secondEnd.y, aimAngle }); } } internal void HandleRoundOver() { ResolveOwner(); SynchronizeFromCards(force: true); effect?.HandleRoundOver(); ClearPointState(); } internal void HandlePointOver() { ResolveOwner(); SynchronizeFromCards(force: true); effect?.HandlePointOver(); ClearPointState(); } private void ClearPointState() { foreach (HelldiverBeacon value in trackedBeacons.Values) { value?.CancelAndDestroy(); } trackedBeacons.Clear(); bufferedBeaconDeployments.Clear(); bufferedBeaconCancellations.Clear(); } internal void RegisterTrackedBeacon(int beaconSeed, HelldiverBeacon beacon) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) trackedBeacons[beaconSeed] = beacon; PendingBeaconDeployment value; if (bufferedBeaconCancellations.Remove(beaconSeed)) { bufferedBeaconDeployments.Remove(beaconSeed); beacon.CancelAndDestroy(); } else if (bufferedBeaconDeployments.TryGetValue(beaconSeed, out value)) { bufferedBeaconDeployments.Remove(beaconSeed); beacon.ApplyAuthoritativeDeployment(value.SettledPosition, value.StuckPlayerId, value.StuckOffset, value.DeployTime, value.ExecuteTime); } } internal void NotifyTrackedBeaconDestroyed(int beaconSeed, HelldiverBeacon beacon) { if (trackedBeacons.TryGetValue(beaconSeed, out HelldiverBeacon value) && (Object)(object)value == (Object)(object)beacon) { trackedBeacons.Remove(beaconSeed); } } [PunRPC] internal void RPCA_SpawnHelldiverBeacon(int stratagemType, float positionX, float positionY, float velocityX, float velocityY, float gravity, float callInDelaySeconds, int seed, int ownerPlayerId, double spawnTime) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) ResolveOwner(); SynchronizeFromCards(force: true); HelldiverStratagemDefinition definition = HelldiverClassRegistry.GetDefinition((HelldiverStratagemType)stratagemType); new GameObject("DOLY_" + definition.DisplayName.Replace(" ", string.Empty) + "_Beacon").AddComponent().Configure(effect, (HelldiverStratagemType)stratagemType, new Vector2(positionX, positionY), new Vector2(velocityX, velocityY), gravity, ownerPlayerId, seed, callInDelaySeconds, ownerData?.view != null && ownerData.view.IsMine, spawnTime, this); } [PunRPC] internal void RPCA_ExecuteHelldiverStratagem(int stratagemType, float centerX, float centerY, float runDirectionX, float runDirectionY, int seed, int ownerPlayerId, double executeTime) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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) new GameObject($"DOLY_{(HelldiverStratagemType)stratagemType}_Strike").AddComponent().Configure((HelldiverStratagemType)stratagemType, new Vector2(centerX, centerY), new Vector2(runDirectionX, runDirectionY), ownerPlayerId, seed, executeTime); } [PunRPC] internal void RPCA_SpawnSentryHellpod(int sentryType, int ownerPlayerId, int sentrySeed, float fallStartX, float fallStartY, float landingPointX, float landingPointY, double startTime) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) new GameObject($"DOLY_{(HelldiverStratagemType)sentryType}_Hellpod").AddComponent().ConfigureResolved((HelldiverStratagemType)sentryType, new Vector2(fallStartX, fallStartY), new Vector2(landingPointX, landingPointY), ownerPlayerId, sentrySeed, startTime); } [PunRPC] internal void RPCA_DeployHelldiverBeacon(int stratagemType, int beaconSeed, float settledPositionX, float settledPositionY, int stuckPlayerId, float stuckOffsetX, float stuckOffsetY, double deployTime, double executeTime) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) ResolveOwner(); SynchronizeFromCards(force: true); ApplyHelldiverBeaconDeployment(beaconSeed, new Vector2(settledPositionX, settledPositionY), stuckPlayerId, new Vector2(stuckOffsetX, stuckOffsetY), deployTime, executeTime); } [PunRPC] internal void RPCA_CancelHelldiverBeacon(int beaconSeed) { ResolveOwner(); SynchronizeFromCards(force: true); CancelHelldiverBeacon(beaconSeed); } [PunRPC] internal void RPCA_SpawnHelldiverGasCloud(float centerX, float centerY, float radius, float duration, float tickInterval, float flatDamage, float percentageDamage, float slowAmount, int ownerPlayerId, float flashColorR, float flashColorG, float flashColorB, float flashColorA, double startTime) { //IL_0002: 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) SpawnGasCloudPayload(new Vector2(centerX, centerY), radius, duration, tickInterval, flatDamage, percentageDamage, slowAmount, ownerPlayerId, new Color(flashColorR, flashColorG, flashColorB, flashColorA), startTime); } [PunRPC] internal void RPCA_SpawnHelldiverEmsField(float centerX, float centerY, float radius, float duration, float initialStunDuration, float slowAmount, float flashColorR, float flashColorG, float flashColorB, float flashColorA, double startTime) { //IL_0002: 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) SpawnEmsFieldPayload(new Vector2(centerX, centerY), radius, duration, initialStunDuration, slowAmount, new Color(flashColorR, flashColorG, flashColorB, flashColorA), startTime); } [PunRPC] internal void RPCA_FireSentryShot(int sentryType, int sentrySeed, int ownerPlayerId, float spawnPointX, float spawnPointY, float directionX, float directionY, float aimAngle) { //IL_000e: 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) HelldiverMachineGunSentryController.ApplySyncedAim(sentrySeed, aimAngle); HelldiverMachineGunSentryController.SpawnSyncedShot((HelldiverStratagemType)sentryType, ownerPlayerId, new Vector2(spawnPointX, spawnPointY), new Vector2(directionX, directionY)); } [PunRPC] internal void RPCA_SetSentryAim(int sentrySeed, float aimAngle) { HelldiverMachineGunSentryController.ApplySyncedAim(sentrySeed, aimAngle); } [PunRPC] internal void RPCA_RetireSentry(int seed, double retireStartTime) { HelldiverMachineGunSentryController.RetireSyncedSentry(seed, retireStartTime); } [PunRPC] internal void RPCA_DamagePlayerFromSentry(int ownerPlayerId, int targetPlayerId, float damageX, float damageY, float damagePointX, float damagePointY, bool ignoreBlock) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) HelldiverMachineGunSentryController.ApplySyncedSentryPlayerDamage(ownerPlayerId, targetPlayerId, new Vector2(damageX, damageY), new Vector2(damagePointX, damagePointY), ignoreBlock); } [PunRPC] internal void RPCA_DamageSentry(int seed, float damageX, float damageY, float damagePointX, float damagePointY, int damagingPlayerId) { //IL_0003: 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) HelldiverMachineGunSentryController.ApplySyncedSentryDamage(seed, new Vector2(damageX, damageY), new Vector2(damagePointX, damagePointY), damagingPlayerId); } [PunRPC] internal void RPCA_DamageHellpod(int seed, float damageX, float damageY, float damagePointX, float damagePointY, int damagingPlayerId) { //IL_0003: 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) HelldiverHellpodDamageable.ApplyOrBufferSyncedDamage(seed, new Vector2(damageX, damageY), new Vector2(damagePointX, damagePointY), damagingPlayerId); } [PunRPC] internal void RPCA_DrawSentryLaser(int sentryType, int sentrySeed, int ownerPlayerId, float originX, float originY, float firstEndX, float firstEndY, bool hasBounce, float secondEndX, float secondEndY, float aimAngle) { //IL_000f: 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_0023: Unknown result type (might be due to invalid IL or missing references) HelldiverMachineGunSentryController.ApplySyncedAim(sentrySeed, aimAngle); HelldiverMachineGunSentryController.SpawnSyncedLaser((HelldiverStratagemType)sentryType, sentrySeed, ownerPlayerId, new Vector2(originX, originY), new Vector2(firstEndX, firstEndY), hasBounce, new Vector2(secondEndX, secondEndY)); } private void ResolveOwner() { if (ownerData == null) { ownerData = ((Component)this).GetComponentInParent(); } if (ownerPlayer == null) { ownerPlayer = ((Component)this).GetComponentInParent(); } if ((Object)(object)effect == (Object)null) { effect = ((Component)this).GetComponentInParent(); } } private void SynchronizeFromCards(bool force) { ResolveOwner(); List list = ownerData?.currentCards; if (ownerPlayer == null || list == null) { return; } int num = ComputeCardFingerprint(list); if (!force && num == lastCardFingerprint) { return; } lastCardFingerprint = num; bool flag = false; bool flag2 = false; bool flag3 = false; int num2 = 0; int num3 = 0; int num4 = 0; HashSet hashSet = new HashSet(); for (int i = 0; i < list.Count; i++) { string text = list[i]?.cardName; if (!string.IsNullOrEmpty(text)) { switch (text) { case "Helldiver": flag = true; break; case "Expanded Weapons Bay": flag2 = true; break; case "Targeting Software Upgrade": flag3 = true; break; case "High-Quality Lubricant": num2++; break; case "Shock Absorption Gel": num3++; break; case "Advanced Construction": num4++; break; } if (StratagemsByCardName.TryGetValue(text, out var value)) { hashSet.Add(value); } } } if (!flag && hashSet.Count == 0 && !flag2 && !flag3 && num2 <= 0 && num3 <= 0 && num4 <= 0) { if (effect != null) { effect.SynchronizeCardState(hasEntryCard: false, hasExpandedWeaponsBay: false, hasTargetingSoftwareUpgrade: false, 0, 0, 0, hashSet); if (effect.IsEmpty) { Object.Destroy((Object)(object)effect); effect = null; } } } else { if (effect == null) { effect = ((Component)this).gameObject.GetOrAddComponent(); } effect.SynchronizeCardState(flag, flag2, flag3, num2, num3, num4, hashSet); } } private static int ComputeCardFingerprint(IList cards) { int num = 17; num = num * 31 + cards.Count; for (int i = 0; i < cards.Count; i++) { num = num * 31 + (cards[i]?.cardName?.GetHashCode()).GetValueOrDefault(); } return num; } private static void SpawnGasCloudPayload(Vector2 center, float radius, float duration, float tickInterval, float flatDamage, float percentageDamage, float slowAmount, int ownerPlayerId, Color flashColor, double startTime) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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) HelldiverStrikeController.SpawnImpactFlash(center, flashColor); new GameObject("DOLY_HelldiverGasCloud").AddComponent().Configure(center, radius, duration, tickInterval, flatDamage, percentageDamage, slowAmount, ownerPlayerId, startTime); } private static void SpawnEmsFieldPayload(Vector2 center, float radius, float duration, float initialStunDuration, float slowAmount, Color flashColor, double startTime) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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) HelldiverStrikeController.SpawnImpactFlash(center, flashColor); new GameObject("DOLY_HelldiverEmsField").AddComponent().Configure(center, radius, duration, initialStunDuration, slowAmount, startTime); } private void ApplyHelldiverBeaconDeployment(int beaconSeed, Vector2 settledPosition, int stuckPlayerId, Vector2 stuckOffset, double deployTime, double executeTime) { //IL_000e: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) HelldiverEffect? helldiverEffect = effect; HelldiverBeacon beacon; if (helldiverEffect != null && helldiverEffect.TryApplyAuthoritativeBeaconDeployment(beaconSeed, settledPosition, stuckPlayerId, stuckOffset, deployTime, executeTime)) { bufferedBeaconDeployments.Remove(beaconSeed); bufferedBeaconCancellations.Remove(beaconSeed); } else if (TryGetTrackedBeacon(beaconSeed, out beacon)) { bufferedBeaconDeployments.Remove(beaconSeed); bufferedBeaconCancellations.Remove(beaconSeed); beacon.ApplyAuthoritativeDeployment(settledPosition, stuckPlayerId, stuckOffset, deployTime, executeTime); } else { bufferedBeaconDeployments[beaconSeed] = new PendingBeaconDeployment(settledPosition, stuckPlayerId, stuckOffset, deployTime, executeTime); bufferedBeaconCancellations.Remove(beaconSeed); } } private void CancelHelldiverBeacon(int beaconSeed) { HelldiverEffect? helldiverEffect = effect; HelldiverBeacon beacon; if (helldiverEffect != null && helldiverEffect.TryCancelPendingBeacon(beaconSeed)) { bufferedBeaconDeployments.Remove(beaconSeed); bufferedBeaconCancellations.Remove(beaconSeed); } else if (TryGetTrackedBeacon(beaconSeed, out beacon)) { trackedBeacons.Remove(beaconSeed); bufferedBeaconDeployments.Remove(beaconSeed); bufferedBeaconCancellations.Remove(beaconSeed); beacon.CancelAndDestroy(); } else { bufferedBeaconDeployments.Remove(beaconSeed); bufferedBeaconCancellations.Add(beaconSeed); } } private bool TryGetTrackedBeacon(int beaconSeed, out HelldiverBeacon beacon) { if (!trackedBeacons.TryGetValue(beaconSeed, out HelldiverBeacon value) || (Object)(object)value == (Object)null) { trackedBeacons.Remove(beaconSeed); beacon = null; return false; } beacon = value; return true; } } internal sealed class HelldiverSentryDamageable : Damagable { private sealed class PendingSentryDamage { internal Vector2 Damage { get; } internal Vector2 DamagePosition { get; } internal int DamagingPlayerId { get; } internal PendingSentryDamage(Vector2 damage, Vector2 damagePosition, int damagingPlayerId) { //IL_0007: 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_000e: 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) Damage = damage; DamagePosition = damagePosition; DamagingPlayerId = damagingPlayerId; } } private static readonly Dictionary> PendingDamageBySeed = new Dictionary>(); private HelldiverMachineGunSentryController? controller; private Collider2D? solidCollider; private float currentHealth; private float maxHealth; private float maxHealthLossPerHitFraction = 0.4f; private bool destroyed; internal int Seed => controller?.Seed ?? (-1); internal float MaxHealth => maxHealth; internal float CurrentHealth => Mathf.Max(0f, currentHealth); internal float HealthFraction { get { if (!(maxHealth <= 0f)) { return Mathf.Clamp01(CurrentHealth / maxHealth); } return 0f; } } internal bool IsDestroyed => destroyed; internal Collider2D? SolidCollider => solidCollider; internal void Configure(HelldiverMachineGunSentryController controller, float maxHealth, float maxHealthLossPerHitFraction, Collider2D solidCollider) { this.controller = controller; this.solidCollider = solidCollider; this.maxHealth = Mathf.Max(1f, maxHealth); this.maxHealthLossPerHitFraction = Mathf.Max(0.01f, maxHealthLossPerHitFraction); currentHealth = this.maxHealth; destroyed = false; ApplyPendingSyncedDamage(); } public override void CallTakeDamage(Vector2 damage, Vector2 damagePosition, GameObject? damagingWeapon = null, Player? damagingPlayer = null, bool lethal = true) { //IL_0001: 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_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) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (!CanTakeDamage(damage)) { return; } Vector2 damage2 = ClampDamageToMaxHealthLoss(damage); Player val = damagingPlayer ?? ResolveControllerOwner(); if (val == null) { ApplyLocalDamage(damage2, damagePosition, damagingPlayer); return; } PhotonView val2 = val.data?.view; if (PhotonNetwork.OfflineMode || val2 == null || val2.IsMine) { HelldiverRuntime.GetOrAdd(val).BroadcastSentryDamaged(Seed, damage2, damagePosition, damagingPlayer?.playerID ?? (-1)); } } public override void TakeDamage(Vector2 damage, Vector2 damagePosition, GameObject? damagingWeapon = null, Player? damagingPlayer = null, bool lethal = true, bool ignoreBlock = false) { //IL_0001: 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) ApplyLocalDamage(damage, damagePosition, damagingPlayer); } public override void TakeDamage(Vector2 damage, Vector2 damagePosition, Color dmgColor, GameObject? damagingWeapon = null, Player? damagingPlayer = null, bool lethal = true, bool ignoreBlock = false) { //IL_0001: 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) ((Damagable)this).TakeDamage(damage, damagePosition, damagingWeapon, damagingPlayer, lethal, ignoreBlock); } internal void ApplySyncedDamage(Vector2 damage, Vector2 damagePosition, int damagingPlayerId) { //IL_0001: 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) ApplyLocalDamage(damage, damagePosition, HolySmiteEffect.ResolvePlayerById(damagingPlayerId)); } internal static void ApplyOrBufferSyncedDamage(int seed, Vector2 damage, Vector2 damagePosition, int damagingPlayerId) { //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_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) if (TryResolveBySeed(seed, out HelldiverSentryDamageable sentry)) { sentry.ApplySyncedDamage(damage, damagePosition, damagingPlayerId); return; } if (!PendingDamageBySeed.TryGetValue(seed, out List value)) { value = new List(); PendingDamageBySeed[seed] = value; } value.Add(new PendingSentryDamage(damage, damagePosition, damagingPlayerId)); } internal static void ClearPendingSyncedDamage() { PendingDamageBySeed.Clear(); } internal static bool TryResolveBySeed(int seed, out HelldiverSentryDamageable sentry) { HelldiverSentryDamageable[] array = Object.FindObjectsOfType(); foreach (HelldiverSentryDamageable helldiverSentryDamageable in array) { if (helldiverSentryDamageable != null && helldiverSentryDamageable.Seed == seed && !helldiverSentryDamageable.destroyed) { sentry = helldiverSentryDamageable; return true; } } sentry = null; return false; } internal static bool TryResolveTargetBySeed(int seed, out Collider2D collider, out Transform targetTransform) { collider = null; targetTransform = null; if (!TryResolveBySeed(seed, out HelldiverSentryDamageable sentry) || (Object)(object)sentry.solidCollider == (Object)null) { return false; } collider = sentry.solidCollider; targetTransform = ((Component)sentry).transform; return true; } internal static bool TryGetFromHit(HitInfo hit, out HelldiverSentryDamageable sentry) { if (hit.collider != null && TryGetFromCollider(hit.collider, out sentry)) { return true; } sentry = ((hit.transform == null) ? null : ((Component)hit.transform).GetComponentInParent()); if (sentry != null) { return !sentry.destroyed; } return false; } internal static bool TryGetFromCollider(Collider2D collider, out HelldiverSentryDamageable sentry) { sentry = ((Component)collider).GetComponentInParent(); if (sentry != null) { return !sentry.destroyed; } return false; } internal static void TryHandleProjectileHit(ProjectileHit projectileHit, HitInfo hit, bool forceCall) { //IL_0018: 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_0044: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) if (projectileHit != null && ShouldProcessProjectile(projectileHit, forceCall) && TryGetFromHit(hit, out HelldiverSentryDamageable sentry) && sentry.CanTakeDamage(Vector2.one) && TryResolveProjectileDamage(projectileHit, sentry.maxHealth, out float damageAmount, out Player damagingPlayer)) { Vector2 val = ResolveProjectileDirection(((Component)projectileHit).transform, hit.normal); ((Damagable)sentry).CallTakeDamage(val * damageAmount, hit.point, projectileHit.ownWeapon, damagingPlayer ?? projectileHit.ownPlayer, true); } } internal static void ApplyRadialDamage(Vector2 center, float radius, float flatDamage, float percentageDamage, float edgeMultiplier, int ownerPlayerId, bool ignoreWalls) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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_0107: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) if (radius <= 0f || (flatDamage <= 0f && percentageDamage <= 0f)) { return; } Player val = HolySmiteEffect.ResolvePlayerById(ownerPlayerId); HelldiverSentryDamageable[] array = Object.FindObjectsOfType(); foreach (HelldiverSentryDamageable helldiverSentryDamageable in array) { if (helldiverSentryDamageable == null || helldiverSentryDamageable.destroyed || (Object)(object)helldiverSentryDamageable.solidCollider == (Object)null) { continue; } Bounds bounds = helldiverSentryDamageable.solidCollider.bounds; Vector3 val2 = ((Bounds)(ref bounds)).ClosestPoint(Vector2.op_Implicit(center)); float num = Vector2.Distance(Vector2.op_Implicit(val2), center); if (num > radius || !CanAffectSentry(helldiverSentryDamageable, center, Vector2.op_Implicit(val2), ignoreWalls)) { continue; } float num2 = Mathf.Lerp(1f, Mathf.Clamp01(edgeMultiplier), num / radius); float num3 = (flatDamage + percentageDamage * helldiverSentryDamageable.maxHealth) * num2; if (num3 <= 0f) { continue; } Vector2 val3 = Vector2.op_Implicit(((Component)helldiverSentryDamageable).transform.position) - center; if (((Vector2)(ref val3)).sqrMagnitude <= 0.0001f) { val3 = Vector2.up; } Vector2 val4 = ((Vector2)(ref val3)).normalized * num3; object obj; if (val == null) { obj = null; } else { CharacterData data = val.data; if (data == null) { obj = null; } else { WeaponHandler weaponHandler = data.weaponHandler; if (weaponHandler == null) { obj = null; } else { Gun gun = weaponHandler.gun; obj = ((gun != null) ? ((Component)gun).gameObject : null); } } } ((Damagable)helldiverSentryDamageable).CallTakeDamage(val4, center, (GameObject)obj, val, true); } } private static bool CanAffectSentry(HelldiverSentryDamageable sentry, Vector2 origin, Vector2 targetPoint, bool ignoreWalls) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_0026: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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) if (ignoreWalls || PlayerManager.instance == null) { return true; } Vector2 val = targetPoint - origin; float magnitude = ((Vector2)(ref val)).magnitude; if (magnitude <= 0.0001f) { return true; } Vector2 val2 = val / magnitude; RaycastHit2D[] array = Physics2D.RaycastAll(origin, val2, magnitude, ((LayerMask)(ref PlayerManager.instance.canSeePlayerMask)).value); Array.Sort(array, (RaycastHit2D left, RaycastHit2D right) => ((RaycastHit2D)(ref left)).distance.CompareTo(((RaycastHit2D)(ref right)).distance)); for (int i = 0; i < array.Length; i++) { Collider2D collider = ((RaycastHit2D)(ref array[i])).collider; if (collider != null && !collider.isTrigger) { if ((Object)(object)((Component)collider).transform == (Object)(object)((Component)sentry).transform || ((Component)collider).transform.IsChildOf(((Component)sentry).transform)) { return true; } return false; } } return true; } private bool CanTakeDamage(Vector2 damage) { if (!destroyed && controller != null && Seed >= 0) { return ((Vector2)(ref damage)).sqrMagnitude > 0.0001f; } return false; } private void ApplyLocalDamage(Vector2 damage, Vector2 damagePosition, Player? damagingPlayer) { //IL_0001: 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_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) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (CanTakeDamage(damage)) { Vector2 damage2 = ClampDamageToMaxHealthLoss(damage); currentHealth = Mathf.Max(0f, currentHealth - ((Vector2)(ref damage2)).magnitude); if (!(currentHealth > 0f)) { destroyed = true; controller.HandleDestroyedByDamage(damagePosition, damage2, damagingPlayer); } } } private Vector2 ClampDamageToMaxHealthLoss(Vector2 damage) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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) float magnitude = ((Vector2)(ref damage)).magnitude; float num = Mathf.Max(1f, maxHealth * maxHealthLossPerHitFraction); if (!(magnitude <= num)) { return ((Vector2)(ref damage)).normalized * num; } return damage; } private void ApplyPendingSyncedDamage() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) int seed = Seed; if (seed < 0 || !PendingDamageBySeed.TryGetValue(seed, out List value)) { return; } PendingDamageBySeed.Remove(seed); for (int i = 0; i < value.Count; i++) { if (destroyed) { break; } PendingSentryDamage pendingSentryDamage = value[i]; ApplySyncedDamage(pendingSentryDamage.Damage, pendingSentryDamage.DamagePosition, pendingSentryDamage.DamagingPlayerId); } } private Player? ResolveControllerOwner() { if (controller != null) { return HolySmiteEffect.ResolvePlayerById(controller.OwnerPlayerId); } return null; } private static bool ShouldProcessProjectile(ProjectileHit projectileHit, bool forceCall) { if (forceCall) { return true; } if (projectileHit.view != null) { return projectileHit.view.IsMine; } return true; } private static bool TryResolveProjectileDamage(ProjectileHit projectileHit, float targetMaxHealth, out float damageAmount, out Player? damagingPlayer) { damagingPlayer = projectileHit.ownPlayer; HelldiverSentryProjectileController component = ((Component)projectileHit).GetComponent(); if (component != null && component.TryGetDamageAgainstSentry(targetMaxHealth, out damageAmount, out damagingPlayer)) { return damageAmount > 0f; } float num = (projectileHit.bulletCanDealDeamage ? projectileHit.damage : 1f); damageAmount = (num + projectileHit.percentageDamage * targetMaxHealth) * projectileHit.dealDamageMultiplierr; return damageAmount > 0f; } private static Vector2 ResolveProjectileDirection(Transform projectileTransform, Vector2 hitNormal) { //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_0009: 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_004c: 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_0044: 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_0049: Unknown result type (might be due to invalid IL or missing references) Vector3 forward = projectileTransform.forward; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(forward.x, forward.y); if (((Vector2)(ref val)).sqrMagnitude <= 0.0001f) { val = ((((Vector2)(ref hitNormal)).sqrMagnitude > 0.0001f) ? (-((Vector2)(ref hitNormal)).normalized) : Vector2.up); } return ((Vector2)(ref val)).normalized; } } internal static class HelldiverSentryGunPool { private const float RayCastTrailMinimumSize = 0.3f; private const float DefaultPlayerHealthForProjectileSizing = 100f; private static SimulatedGun? sharedGun; private static Gun? defaultGunTemplate; internal static void Warm() { GetOrCreateSharedGun(); } internal static void Invalidate() { if ((Object)(object)sharedGun != (Object)null) { Object.Destroy((Object)(object)((Component)sharedGun).gameObject); } sharedGun = null; defaultGunTemplate = null; } internal static bool Configure(Player owner, HelldiverSentryConfig config, Color color, Vector2 flightDirection) { //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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0159: 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) HelldiverSentryConfig config2 = config; Player owner2 = owner; if (owner2.data == null) { return false; } SimulatedGun orCreateSharedGun = GetOrCreateSharedGun(); Gun val = GetDefaultGunTemplate(); if (orCreateSharedGun == null || val == null) { return false; } Vector2 direction = ((((Vector2)(ref flightDirection)).sqrMagnitude > 0.0001f) ? ((Vector2)(ref flightDirection)).normalized : Vector2.up); orCreateSharedGun.CopyGunStatsExceptActions(val); ((Gun)orCreateSharedGun).player = owner2; ((Gun)orCreateSharedGun).damage = 0f; ((Gun)orCreateSharedGun).percentageDamage = 0f; ((Gun)orCreateSharedGun).knockback = 0f; ((Gun)orCreateSharedGun).slow = 0f; ((Gun)orCreateSharedGun).reflects = 0; ((Gun)orCreateSharedGun).size = 0f; ((Gun)orCreateSharedGun).projectileSize = 0f; ((Gun)orCreateSharedGun).spread = 0f; ((Gun)orCreateSharedGun).evenSpread = 0f; ((Gun)orCreateSharedGun).numberOfProjectiles = 1; ((Gun)orCreateSharedGun).bursts = 1; ((Gun)orCreateSharedGun).timeBetweenBullets = 0f; ((Gun)orCreateSharedGun).drag = 0f; ((Gun)orCreateSharedGun).dragMinSpeed = 0f; ((Gun)orCreateSharedGun).gravity = config2.ProjectileGravity; ((Gun)orCreateSharedGun).projectileSpeed = 1f; ((Gun)orCreateSharedGun).projectielSimulatonSpeed = 1f; ((Gun)orCreateSharedGun).shake = 0f; ((Gun)orCreateSharedGun).shakeM = 0f; ((Gun)orCreateSharedGun).forceSpecificShake = true; ((Gun)orCreateSharedGun).ignoreWalls = false; ((Gun)orCreateSharedGun).destroyBulletAfter = 3f; ((Gun)orCreateSharedGun).projectileColor = color; ((Gun)orCreateSharedGun).ShootPojectileAction = delegate { }; ((Gun)orCreateSharedGun).ShootPojectileAction = (Action)Delegate.Combine(((Gun)orCreateSharedGun).ShootPojectileAction, (Action)delegate(GameObject bullet) { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) HelldiverSentryProjectileController helldiverSentryProjectileController = bullet.GetComponent(); if (helldiverSentryProjectileController == null) { helldiverSentryProjectileController = bullet.AddComponent(); } ProjectileHit component = bullet.GetComponent(); if (component != null) { component.damage = ResolveProjectileVisualDamage(config2); component.percentageDamage = 0f; component.dealDamageMultiplierr = 0f; component.canPushBox = false; component.fullSelfDamage = true; component.holdPlayerFor = 0f; component.force = 0f; component.shake = 0f; component.movementSlow = 0f; } RayCastTrail component2 = bullet.GetComponent(); if (component2 != null) { component2.teamID = -1; component2.timeAtSpawn = 0f; ApplyProjectileSize(bullet, component2, bullet.GetComponent(), config2); } helldiverSentryProjectileController.Configure(config2, owner2.playerID, color, direction); }); return true; } internal static void ApplyProjectileSize(GameObject bullet, RayCastTrail rayCastTrail, ProjectileHit? projectileHit, HelldiverSentryConfig config) { //IL_0068: 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_007a: Unknown result type (might be due to invalid IL or missing references) float num = ResolveRayCastTrailBaseSize(projectileHit); float num2 = ResolveRayCastTrailBaseSize(ResolveProjectileSizingDamage(config)); float num3 = Mathf.Max(num, num2 * Mathf.Max(0f, config.ProjectileVisualScale)); rayCastTrail.extraSize = Mathf.Max(0f, num3 - num); rayCastTrail.size = num3; SetScaleFromSizeAndExtraSize[] componentsInChildren = bullet.GetComponentsInChildren(true); foreach (SetScaleFromSizeAndExtraSize val in componentsInChildren) { ((Behaviour)val).enabled = false; ((Component)val).transform.localScale = Vector3.one * num3 * val.scalePerSize; } } private static float ResolveRayCastTrailBaseSize(ProjectileHit? projectileHit) { if (projectileHit != null) { return ResolveRayCastTrailBaseSize(projectileHit.damage); } return 0.3f; } private static float ResolveRayCastTrailBaseSize(float damage) { return Mathf.Clamp(Mathf.Pow(Mathf.Max(0f, damage), 0.85f) / 400f, 0f, 100f) + 0.3f; } private static float ResolveProjectileSizingDamage(HelldiverSentryConfig config) { return config.Damage + config.PercentDamage * 100f; } private static float ResolveProjectileVisualDamage(HelldiverSentryConfig config) { return ResolveProjectileSizingDamage(config) * Mathf.Max(1f, config.ProjectileVisualScale); } internal static bool Fire(Player owner, Vector2 spawnPoint, Vector2 flightDirection) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_0039: 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_003f: 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) if (owner.data == null) { return false; } SimulatedGun orCreateSharedGun = GetOrCreateSharedGun(); if (orCreateSharedGun == null) { return false; } Vector2 val = ((((Vector2)(ref flightDirection)).sqrMagnitude > 0.0001f) ? ((Vector2)(ref flightDirection)).normalized : Vector2.up); return orCreateSharedGun.SimulatedAttack(owner.playerID, Vector2.op_Implicit(spawnPoint), Vector2.op_Implicit(val), 0f, 1f, (Transform)null, false); } private static SimulatedGun? GetOrCreateSharedGun() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown if ((Object)(object)sharedGun != (Object)null) { return sharedGun; } GameObject val = new GameObject("DOLY_HelldiverSentryGun"); Object.DontDestroyOnLoad((Object)val); sharedGun = val.AddComponent(); return sharedGun; } private static Gun? GetDefaultGunTemplate() { if ((Object)(object)defaultGunTemplate != (Object)null) { return defaultGunTemplate; } GameObject val = Resources.Load("Player"); if (val == null) { return null; } Holdable val2 = val.GetComponent()?.holdable; defaultGunTemplate = ((val2 != null) ? ((Component)val2).GetComponent() : null); return defaultGunTemplate; } } internal sealed class HelldiverSentryProjectileController : MonoBehaviour { private const float BlockReflectSurfaceOffset = 0.12f; private const float BlockReflectHeldSeconds = 0.12f; private const float DefaultObjectHealthForImpactDamage = 100f; private HelldiverSentryConfig? config; private int ownerPlayerId; private Color color = Color.white; private float speed; private float gravity; private Vector2 flightDirection = Vector2.up; private Vector2 currentVelocity = Vector2.up; private bool configured; private bool hitHooked; private bool resolved; private MoveTransform? moveTransform; private ProjectileHit? projectileHit; private RayCastTrail? rayCastTrail; private Rigidbody2D? rigidbody2D; private SpawnedAttack? spawnedAttack; internal void Configure(HelldiverSentryConfig config, int ownerPlayerId, Color color, Vector2 flightDirection) { //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_0059: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) this.config = config; this.ownerPlayerId = ownerPlayerId; this.color = color; speed = Mathf.Max(0.01f, config.ProjectileSpeed); gravity = Mathf.Max(0f, config.ProjectileGravity); this.flightDirection = ((((Vector2)(ref flightDirection)).sqrMagnitude > 0.0001f) ? ((Vector2)(ref flightDirection)).normalized : Vector2.up); currentVelocity = this.flightDirection * speed; configured = false; hitHooked = false; resolved = false; if (moveTransform != null) { ((Behaviour)moveTransform).enabled = true; moveTransform.velocity = Vector3.zero; } if (rigidbody2D != null) { rigidbody2D.velocity = Vector2.zero; rigidbody2D.angularVelocity = 0f; } TryApplyConfiguration(); } internal void HandleBlocked(Player blocker, Vector2 hitPoint, Vector2 incomingDirection) { //IL_0007: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_0069: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) CacheComponents(); Vector2 val = ResolveTravelDirection(); Vector2 val2 = ((((Vector2)(ref val)).sqrMagnitude > 0.0001f) ? (-((Vector2)(ref val)).normalized) : (-((Vector2)(ref incomingDirection)).normalized)); if (((Vector2)(ref val2)).sqrMagnitude <= 0.0001f) { val2 = Vector2.up; } flightDirection = ((Vector2)(ref val2)).normalized; currentVelocity = flightDirection * speed; ((Component)this).transform.position = Vector2.op_Implicit(hitPoint + flightDirection * 0.12f); if (projectileHit != null) { projectileHit.RemoveOwnPlayerFromPlayersHit(); if (blocker.data?.healthHandler != null) { float holdPlayerFor = projectileHit.holdPlayerFor; projectileHit.holdPlayerFor = Mathf.Max(projectileHit.holdPlayerFor, 0.12f); projectileHit.AddPlayerToHeld(blocker.data.healthHandler); projectileHit.holdPlayerFor = holdPlayerFor; } } if (rayCastTrail != null) { rayCastTrail.WasBlocked(); } ApplyVelocity(); RayCastTrail? obj = rayCastTrail; if (obj != null) { obj.MoveRay(); } } internal bool TryGetDamageAgainstSentry(float targetMaxHealth, out float damageAmount, out Player? owner) { owner = HolySmiteEffect.ResolvePlayerById(ownerPlayerId); damageAmount = ((config == null) ? 0f : (config.Damage + config.PercentDamage * Mathf.Max(0f, targetMaxHealth))); return damageAmount > 0f; } private void Awake() { TryApplyConfiguration(); } private void Start() { TryApplyConfiguration(); } private void Update() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) TryApplyConfiguration(); if (!configured) { return; } if (gravity > 0f) { currentVelocity += Vector2.down * gravity * TimeHandler.deltaTime; if (((Vector2)(ref currentVelocity)).sqrMagnitude > 0.0001f) { flightDirection = ((Vector2)(ref currentVelocity)).normalized; } } if (moveTransform != null) { ApplyVelocity(); } } private void TryApplyConfiguration() { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) if (configured) { return; } CacheComponents(); if (moveTransform != null && rayCastTrail != null) { if (!hitHooked && projectileHit != null) { projectileHit.AddHitActionWithData((Action)HandleImpact); hitHooked = true; } if (config != null) { HelldiverSentryGunPool.ApplyProjectileSize(((Component)this).gameObject, rayCastTrail, projectileHit, config); } configured = true; moveTransform.gravity = gravity; moveTransform.drag = 0f; moveTransform.dragMinSpeed = 0f; moveTransform.simulateGravity = 0; moveTransform.localForce = Vector3.zero; moveTransform.worldForce = Vector3.zero; if (rigidbody2D != null) { rigidbody2D.gravityScale = 0f; rigidbody2D.drag = 0f; } ApplyVelocity(); rayCastTrail.MoveRay(); } } private void CacheComponents() { if (moveTransform == null) { moveTransform = ((Component)this).GetComponent(); } if (projectileHit == null) { projectileHit = ((Component)this).GetComponent(); } if (rayCastTrail == null) { rayCastTrail = ((Component)this).GetComponent(); } if (rigidbody2D == null) { rigidbody2D = ((Component)this).GetComponent(); } if (spawnedAttack == null) { spawnedAttack = ((Component)this).GetComponent(); } } private void ApplyVelocity() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_006c: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (((Vector2)(ref currentVelocity)).sqrMagnitude <= 0.0001f) { currentVelocity = ((((Vector2)(ref flightDirection)).sqrMagnitude > 0.0001f) ? ((Vector2)(ref flightDirection)).normalized : Vector2.up) * speed; } Vector2 normalized = ((Vector2)(ref currentVelocity)).normalized; if (moveTransform != null) { moveTransform.velocity = Vector2.op_Implicit(currentVelocity); } if (rigidbody2D != null) { rigidbody2D.velocity = currentVelocity; } ((Component)this).transform.rotation = Quaternion.LookRotation(Vector2.op_Implicit(normalized), Vector3.forward); } private Vector2 ResolveTravelDirection() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) if (((Vector2)(ref flightDirection)).sqrMagnitude > 0.0001f) { return ((Vector2)(ref flightDirection)).normalized; } if (moveTransform != null && ((Vector3)(ref moveTransform.velocity)).sqrMagnitude > 0.0001f) { return Vector2.op_Implicit(((Vector3)(ref moveTransform.velocity)).normalized); } if (rigidbody2D != null) { Vector2 velocity = rigidbody2D.velocity; if (((Vector2)(ref velocity)).sqrMagnitude > 0.0001f) { velocity = rigidbody2D.velocity; return ((Vector2)(ref velocity)).normalized; } } return Vector2.zero; } private void HandleImpact(HitInfo hitInfo) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_004f: 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_0059: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) if (resolved || config == null) { return; } resolved = true; Vector2 val = ((((Vector2)(ref hitInfo.normal)).sqrMagnitude > 0.0001f) ? ((Vector2)(ref hitInfo.normal)).normalized : (-flightDirection)); Vector2 val2 = hitInfo.point + val * 0.08f; if (config.HasExplosion) { HelldiverStrikeController.SpawnImpactFlash(val2, color); } if (!PhotonNetwork.OfflineMode) { SpawnedAttack? obj = spawnedAttack; if (obj == null || !obj.IsMine()) { return; } } ApplyDirectImpactDamage(hitInfo, val2); if (config.HasExplosion) { HelldiverMachineGunSentryController.BroadcastSentryRadialPlayerDamage(val2, config.ExplosionRadius, config.ExplosionDamage, config.ExplosionPercentDamage, 1f, ownerPlayerId, ignoreWalls: false); HelldiverSentryDamageable.ApplyRadialDamage(val2, config.ExplosionRadius, config.ExplosionDamage, config.ExplosionPercentDamage, 1f, ownerPlayerId, ignoreWalls: false); } } private void ApplyDirectImpactDamage(HitInfo hitInfo, Vector2 impactPoint) { //IL_0041: 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) if (config != null) { Transform transform = hitInfo.transform; object obj = ((transform != null) ? ((Component)transform).GetComponent() : null); if (obj == null) { Transform transform2 = hitInfo.transform; obj = ((transform2 != null) ? ((Component)transform2).GetComponentInParent() : null); } HealthHandler val = (HealthHandler)obj; if (val != null) { ApplyDirectPlayerImpactDamage(hitInfo, impactPoint, val); } else { ApplyDirectDamagableImpactDamage(hitInfo, impactPoint); } } } private void ApplyDirectPlayerImpactDamage(HitInfo hitInfo, Vector2 impactPoint, HealthHandler targetHealth) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) Transform transform = hitInfo.transform; object obj = ((transform != null) ? ((Component)transform).GetComponent() : null); if (obj == null) { Transform transform2 = hitInfo.transform; obj = ((transform2 != null) ? ((Component)transform2).GetComponentInParent() : null); } Player val = (Player)obj; if (val?.data == null || config == null) { return; } float num = config.Damage + config.PercentDamage * val.data.maxHealth; if (!(num <= 0f)) { Player val2 = HolySmiteEffect.ResolvePlayerById(ownerPlayerId); Vector2 val3 = Vector2.op_Implicit(((Component)val).transform.position) - impactPoint; if (((Vector2)(ref val3)).sqrMagnitude <= 0.0001f) { val3 = ((((Vector2)(ref flightDirection)).sqrMagnitude > 0.0001f) ? flightDirection : Vector2.up); } if (val2 != null) { HelldiverMachineGunSentryController.BroadcastSentryPlayerDamage(val2, val, ((Vector2)(ref val3)).normalized * num, impactPoint, ignoreBlock: false); } } } private void ApplyDirectDamagableImpactDamage(HitInfo hitInfo, Vector2 impactPoint) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) if (config == null) { return; } Collider2D collider = hitInfo.collider; object obj = ((collider != null) ? ((Component)collider).GetComponentInParent() : null); if (obj == null) { Transform transform = hitInfo.transform; obj = ((transform != null) ? ((Component)transform).GetComponentInParent() : null); } Damagable val = (Damagable)obj; if (val == null || val is HelldiverSentryDamageable || val is HelldiverHellpodDamageable) { return; } float num = config.Damage + config.PercentDamage * 100f; if (num <= 0f) { return; } Player val2 = HolySmiteEffect.ResolvePlayerById(ownerPlayerId); if (val2 == null) { return; } Vector2 val3 = ((((Vector2)(ref flightDirection)).sqrMagnitude > 0.0001f) ? ((Vector2)(ref flightDirection)).normalized : Vector2.up); Vector2 val4 = val3 * num; CharacterData data = val2.data; object obj2; if (data == null) { obj2 = null; } else { WeaponHandler weaponHandler = data.weaponHandler; if (weaponHandler == null) { obj2 = null; } else { Gun gun = weaponHandler.gun; obj2 = ((gun != null) ? ((Component)gun).gameObject : null); } } val.CallTakeDamage(val4, impactPoint, (GameObject)obj2, val2, true); } } internal sealed class HelldiverSentryHealthBar : MonoBehaviour { private const float BarWidth = 0.94095004f; private const float BarYOffset = 0.125f; private const float TrackWidth = 0.288f; private const float FillWidth = 0.207f; private const int TrackSortingOrder = 1490; private const int FillSortingOrder = 1491; private HelldiverSentryDamageable? damageable; private LineRenderer? trackRenderer; private LineRenderer? fillRenderer; private Material? material; private float lastFraction = -1f; internal void Configure(HelldiverSentryDamageable damageable, Transform parent, Color accentColor) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //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_0073: Expected O, but got Unknown this.damageable = damageable; GameObject val = new GameObject("SentryHealthBar"); val.transform.SetParent(parent, false); val.transform.localPosition = new Vector3(0f, 0.125f, 0f); val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; material = new Material(Shader.Find("Sprites/Default")); trackRenderer = CreateRenderer(val.transform, "Track", 0.288f, 1490); fillRenderer = CreateRenderer(val.transform, "Fill", 0.207f, 1491); SetTrackLine(); UpdateFillLine(1f); } private void Update() { if (damageable == null || trackRenderer == null || fillRenderer == null) { return; } if (damageable.IsDestroyed) { ((Renderer)trackRenderer).enabled = false; ((Renderer)fillRenderer).enabled = false; return; } float healthFraction = damageable.HealthFraction; if (!(Mathf.Abs(healthFraction - lastFraction) <= 0.001f)) { UpdateFillLine(healthFraction); } } private void OnDestroy() { if (material != null) { Object.Destroy((Object)(object)material); } } private LineRenderer CreateRenderer(Transform parent, string name, float width, int sortingOrder) { //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_0013: 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_0023: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; LineRenderer obj = val.AddComponent(); ((Renderer)obj).material = material; obj.useWorldSpace = false; obj.loop = false; obj.positionCount = 2; obj.numCapVertices = 3; obj.numCornerVertices = 3; obj.textureMode = (LineTextureMode)0; obj.alignment = (LineAlignment)0; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; ((Renderer)obj).sortingOrder = sortingOrder; obj.startWidth = width; obj.endWidth = width; return obj; } private void SetTrackLine() { //IL_002a: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) if (trackRenderer != null) { Color val = default(Color); ((Color)(ref val))..ctor(0.02f, 0.02f, 0.02f, 0.72f); trackRenderer.startColor = val; trackRenderer.endColor = val; trackRenderer.SetPosition(0, new Vector3(-0.47047502f, 0f, 0f)); trackRenderer.SetPosition(1, new Vector3(0.47047502f, 0f, 0f)); } } private void UpdateFillLine(float fraction) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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) if (fillRenderer != null) { fraction = Mathf.Clamp01(fraction); lastFraction = fraction; ((Renderer)fillRenderer).enabled = fraction > 0.001f; float num = -0.47047502f; float num2 = Mathf.Lerp(num, 0.47047502f, fraction); Color val = ResolveFillColor(fraction); fillRenderer.startColor = val; fillRenderer.endColor = val; fillRenderer.SetPosition(0, new Vector3(num, 0f, 0f)); fillRenderer.SetPosition(1, new Vector3(num2, 0f, 0f)); } } private Color ResolveFillColor(float fraction) { //IL_006e: 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) //IL_0077: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) Color val = default(Color); ((Color)(ref val))..ctor(1f, 0.16f, 0.08f, 0.95f); Color val2 = default(Color); ((Color)(ref val2))..ctor(1f, 0.75f, 0.18f, 0.95f); Color val3 = default(Color); ((Color)(ref val3))..ctor(0.42f, 1f, 0.2f, 0.98f); if (!(fraction < 0.35f)) { return Color.Lerp(val2, val3, (fraction - 0.35f) / 0.65f); } return Color.Lerp(val, val2, fraction / 0.35f); } } internal struct HelldiverSentryLaserResult { internal Vector2 Origin { get; } internal Vector2 FirstEnd { get; } internal bool HasBounce { get; } internal Vector2 SecondEnd { get; } internal HelldiverSentryLaserResult(Vector2 origin, Vector2 firstEnd, bool hasBounce, Vector2 secondEnd) { //IL_0001: 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_0008: 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) //IL_0016: 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) Origin = origin; FirstEnd = firstEnd; HasBounce = hasBounce; SecondEnd = secondEnd; } } internal static class HelldiverSentryLaserBeam { private struct LaserTraceSegment { internal Vector2 End { get; } internal float Distance { get; } internal LaserTraceSegment(Vector2 end, float distance) { //IL_0001: 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) End = end; Distance = distance; } } private struct LaserBounce { internal Vector2 ReflectedDirection { get; } internal LaserBounce(Vector2 reflectedDirection) { //IL_0001: 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) ReflectedDirection = reflectedDirection; } } private const float SurfaceOffset = 0.04f; private const float VisualLifetimeSeconds = 0.12f; private const float DefaultObjectHealthForImpactDamage = 100f; private static readonly Dictionary ActiveVisualsBySentry = new Dictionary(); internal static HelldiverSentryLaserResult FireAuthorityPulse(HelldiverSentryConfig config, Player owner, Vector2 origin, Vector2 direction, Transform sourceSentry) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_0030: 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_0054: 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_005f: 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) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) Vector2 direction2 = ((((Vector2)(ref direction)).sqrMagnitude > 0.0001f) ? ((Vector2)(ref direction)).normalized : Vector2.up); float num = Mathf.Max(0.1f, config.BeamRange); LaserBounce? bounce; LaserTraceSegment laserTraceSegment = TraceSegment(config, owner, origin, direction2, num, 1f, sourceSentry, out bounce); if (!bounce.HasValue || config.BeamBounces <= 0) { return new HelldiverSentryLaserResult(origin, laserTraceSegment.End, hasBounce: false, laserTraceSegment.End); } float num2 = Mathf.Max(0f, num - laserTraceSegment.Distance); if (num2 <= 0.01f) { return new HelldiverSentryLaserResult(origin, laserTraceSegment.End, hasBounce: false, laserTraceSegment.End); } Vector2 origin2 = laserTraceSegment.End + bounce.Value.ReflectedDirection * 0.04f; LaserBounce? bounce2; LaserTraceSegment laserTraceSegment2 = TraceSegment(config, owner, origin2, bounce.Value.ReflectedDirection, num2, Mathf.Clamp01(config.ReflectedDamageMultiplier), sourceSentry, out bounce2); return new HelldiverSentryLaserResult(origin, laserTraceSegment.End, hasBounce: true, laserTraceSegment2.End); } internal static void SpawnVisual(int sentrySeed, Vector2 origin, Vector2 firstEnd, bool hasBounce, Vector2 secondEnd, Color color) { //IL_0016: 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) //IL_0030: 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_0034: Unknown result type (might be due to invalid IL or missing references) ClearVisual(sentrySeed); HelldiverSentryLaserVisual helldiverSentryLaserVisual = new GameObject($"DOLY_HelldiverSentryLaser_{sentrySeed}").AddComponent(); ActiveVisualsBySentry[sentrySeed] = helldiverSentryLaserVisual; helldiverSentryLaserVisual.Configure(sentrySeed, origin, firstEnd, hasBounce, secondEnd, color, 0.12f); } internal static void ClearVisual(int sentrySeed) { if (ActiveVisualsBySentry.TryGetValue(sentrySeed, out HelldiverSentryLaserVisual value)) { ActiveVisualsBySentry.Remove(sentrySeed); if ((Object)(object)value != (Object)null) { value.Hide(); Object.Destroy((Object)(object)((Component)value).gameObject); } } } internal static void UnregisterVisual(int sentrySeed, HelldiverSentryLaserVisual visual) { if (ActiveVisualsBySentry.TryGetValue(sentrySeed, out HelldiverSentryLaserVisual value) && (Object)(object)value == (Object)(object)visual) { ActiveVisualsBySentry.Remove(sentrySeed); } } private static LaserTraceSegment TraceSegment(HelldiverSentryConfig config, Player owner, Vector2 origin, Vector2 direction, float range, float damageMultiplier, Transform sourceSentry, out LaserBounce? bounce) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) bounce = null; int num = ((PlayerManager.instance != null) ? ((LayerMask)(ref PlayerManager.instance.canSeePlayerMask)).value : (-1)); RaycastHit2D[] array = Physics2D.RaycastAll(origin, direction, range, num); Array.Sort(array, (RaycastHit2D a, RaycastHit2D b) => ((RaycastHit2D)(ref a)).distance.CompareTo(((RaycastHit2D)(ref b)).distance)); for (int i = 0; i < array.Length; i++) { RaycastHit2D val = array[i]; Collider2D collider = ((RaycastHit2D)(ref val)).collider; if (collider == null || IsIgnoredCollider(collider, sourceSentry)) { continue; } Player componentInParent = ((Component)collider).GetComponentInParent(); Vector2 val2; if (componentInParent != null) { if (IsActivelyBlocking(componentInParent)) { val2 = -direction; bounce = new LaserBounce(((Vector2)(ref val2)).normalized); return new LaserTraceSegment(((RaycastHit2D)(ref val)).point, ((RaycastHit2D)(ref val)).distance); } TryApplyDamage(config, owner, componentInParent, ((RaycastHit2D)(ref val)).point, direction, damageMultiplier); return new LaserTraceSegment(((RaycastHit2D)(ref val)).point, ((RaycastHit2D)(ref val)).distance); } if (HelldiverSentryDamageable.TryGetFromCollider(collider, out HelldiverSentryDamageable sentry)) { TryApplyDamage(config, owner, sentry, ((RaycastHit2D)(ref val)).point, direction, damageMultiplier); return new LaserTraceSegment(((RaycastHit2D)(ref val)).point, ((RaycastHit2D)(ref val)).distance); } Damagable componentInParent2 = ((Component)collider).GetComponentInParent(); if (componentInParent2 != null && !(componentInParent2 is HelldiverSentryDamageable) && !(componentInParent2 is HelldiverHellpodDamageable)) { TryApplyDamage(config, owner, componentInParent2, ((RaycastHit2D)(ref val)).point, direction, damageMultiplier); return new LaserTraceSegment(((RaycastHit2D)(ref val)).point, ((RaycastHit2D)(ref val)).distance); } if (!collider.isTrigger) { val2 = ((RaycastHit2D)(ref val)).normal; Vector2 val3; if (!(((Vector2)(ref val2)).sqrMagnitude > 0.0001f)) { val3 = -direction; } else { val2 = ((RaycastHit2D)(ref val)).normal; val3 = ((Vector2)(ref val2)).normalized; } Vector2 val4 = val3; val2 = Vector2.Reflect(direction, val4); Vector2 normalized = ((Vector2)(ref val2)).normalized; bounce = new LaserBounce(normalized); return new LaserTraceSegment(((RaycastHit2D)(ref val)).point, ((RaycastHit2D)(ref val)).distance); } } return new LaserTraceSegment(origin + direction * range, range); } private static bool IsIgnoredCollider(Collider2D collider, Transform sourceSentry) { if (!((Object)(object)((Component)collider).transform == (Object)(object)sourceSentry)) { return ((Component)collider).transform.IsChildOf(sourceSentry); } return true; } private static bool IsActivelyBlocking(Player player) { Block componentInChildren = ((Component)player).GetComponentInChildren(); if (componentInChildren != null) { return componentInChildren.sinceBlock < 0.3f; } return false; } private static void TryApplyDamage(HelldiverSentryConfig config, Player owner, Player target, Vector2 hitPoint, Vector2 direction, float damageMultiplier) { //IL_0057: 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) //IL_0062: Unknown result type (might be due to invalid IL or missing references) if (target.data != null && !target.data.dead && target.data.healthHandler != null) { float num = (config.Damage + config.PercentDamage * target.data.maxHealth) * Mathf.Max(0f, damageMultiplier); if (!(num <= 0f)) { HelldiverMachineGunSentryController.BroadcastSentryPlayerDamage(owner, target, ((Vector2)(ref direction)).normalized * num, hitPoint, ignoreBlock: false); } } } private static void TryApplyDamage(HelldiverSentryConfig config, Player owner, HelldiverSentryDamageable target, Vector2 hitPoint, Vector2 direction, float damageMultiplier) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (target.IsDestroyed) { return; } float num = (config.Damage + config.PercentDamage * target.MaxHealth) * Mathf.Max(0f, damageMultiplier); if (num <= 0f) { return; } Vector2 val = ((Vector2)(ref direction)).normalized * num; CharacterData data = owner.data; object obj; if (data == null) { obj = null; } else { WeaponHandler weaponHandler = data.weaponHandler; if (weaponHandler == null) { obj = null; } else { Gun gun = weaponHandler.gun; obj = ((gun != null) ? ((Component)gun).gameObject : null); } } ((Damagable)target).CallTakeDamage(val, hitPoint, (GameObject)obj, owner, true); } private static void TryApplyDamage(HelldiverSentryConfig config, Player owner, Damagable target, Vector2 hitPoint, Vector2 direction, float damageMultiplier) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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) float num = (config.Damage + config.PercentDamage * 100f) * Mathf.Max(0f, damageMultiplier); if (num <= 0f) { return; } Vector2 val = ((Vector2)(ref direction)).normalized * num; CharacterData data = owner.data; object obj; if (data == null) { obj = null; } else { WeaponHandler weaponHandler = data.weaponHandler; if (weaponHandler == null) { obj = null; } else { Gun gun = weaponHandler.gun; obj = ((gun != null) ? ((Component)gun).gameObject : null); } } target.CallTakeDamage(val, hitPoint, (GameObject)obj, owner, true); } } internal sealed class HelldiverSentryLaserVisual : MonoBehaviour { private const float BeamWidth = 0.055f; private LineRenderer? lineRenderer; private Material? material; private int sentrySeed; private float lifetimeSeconds; private float elapsed; private bool configured; internal void Configure(int sentrySeed, Vector2 origin, Vector2 firstEnd, bool hasBounce, Vector2 secondEnd, Color color, float lifetimeSeconds) { //IL_0026: 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_0045: Expected O, but got Unknown //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0127: 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_0139: Unknown result type (might be due to invalid IL or missing references) //IL_014a: 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_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) this.sentrySeed = sentrySeed; this.lifetimeSeconds = Mathf.Max(0.01f, lifetimeSeconds); configured = true; ((Component)this).transform.position = Vector3.zero; material = new Material(Shader.Find("Sprites/Default")); lineRenderer = ((Component)this).gameObject.AddComponent(); ((Renderer)lineRenderer).material = material; lineRenderer.useWorldSpace = true; lineRenderer.loop = false; lineRenderer.positionCount = (hasBounce ? 3 : 2); lineRenderer.numCapVertices = 5; lineRenderer.numCornerVertices = 5; lineRenderer.alignment = (LineAlignment)0; ((Renderer)lineRenderer).sortingOrder = 1485; lineRenderer.startWidth = 0.055f; lineRenderer.endWidth = 0.055f; lineRenderer.startColor = color; lineRenderer.endColor = new Color(color.r, color.g * 0.55f, color.b * 0.55f, color.a * 0.65f); lineRenderer.SetPosition(0, Vector2.op_Implicit(origin)); lineRenderer.SetPosition(1, Vector2.op_Implicit(firstEnd)); if (hasBounce) { lineRenderer.SetPosition(2, Vector2.op_Implicit(secondEnd)); } } internal void Hide() { if (lineRenderer != null) { ((Renderer)lineRenderer).enabled = false; } } private void Update() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_0073: Unknown result type (might be due to invalid IL or missing references) elapsed += TimeHandler.deltaTime; if (lineRenderer != null) { float num = Mathf.Clamp01(1f - elapsed / lifetimeSeconds); Color startColor = lineRenderer.startColor; Color endColor = lineRenderer.endColor; startColor.a = num; endColor.a = num * 0.65f; lineRenderer.startColor = startColor; lineRenderer.endColor = endColor; } if (elapsed >= lifetimeSeconds) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void OnDestroy() { if (configured) { HelldiverSentryLaserBeam.UnregisterVisual(sentrySeed, this); } if (material != null) { Object.Destroy((Object)(object)material); } } } internal enum HelldiverShellImpactMode { ImmediateExplosion, DelayedExplosion, GasCloud, Eagle500kg, EmsField } internal sealed class HelldiverShellImpactConfig { internal HelldiverShellImpactMode Mode { get; set; } internal int OwnerPlayerId { get; set; } = -1; internal float ExplosionSurfaceOffset { get; set; } = 0.5f; internal float Speed { get; set; } internal float UnlockDepthY { get; set; } internal Vector2 FlightDirection { get; set; } = Vector2.down; internal float ExplosionRadius { get; set; } internal float ExplosionDamage { get; set; } internal float ExplosionPercentDamage { get; set; } internal float ExplosionEdgeDamageMultiplier { get; set; } internal float DetonationDelaySeconds { get; set; } internal float GasRadius { get; set; } internal float GasDuration { get; set; } internal float GasTickInterval { get; set; } internal float GasTickDamage { get; set; } internal float GasTickPercentDamage { get; set; } internal float GasSlowAmount { get; set; } internal float EmsRadius { get; set; } internal float EmsDuration { get; set; } internal float EmsInitialStunDuration { get; set; } internal float EmsSlowAmount { get; set; } internal float LodgedShellLength { get; set; } internal float LodgedShellWidth { get; set; } internal float LodgedShellAngleDegrees { get; set; } = -58f; internal Color Color { get; set; } = Color.white; internal HelldiverExplosionPresentationSize ExplosionPresentationSize { get; set; } = HelldiverExplosionPresentationSize.Medium; internal HelldiverExplosionPresentationSize ExplosionSoundSize { get; set; } = HelldiverExplosionPresentationSize.Medium; internal float ExplosionSoundVolumeMultiplier { get; set; } = 1f; } internal static class HelldiverStratagemIconLibrary { private const string StratagemIconResourcePrefix = "RoundsDolyMods.Assets.Stratagem.128px."; private static readonly Dictionary ResourceNames = new Dictionary { [HelldiverStratagemType.OrbitalPrecisionStrike] = "RoundsDolyMods.Assets.Stratagem.128px.Orbital_Precision_Strike_Stratagem_Icon.png", [HelldiverStratagemType.OrbitalGatlingBarrage] = "RoundsDolyMods.Assets.Stratagem.128px.Orbital_Gatling_Barrage_Stratagem_Icon.png", [HelldiverStratagemType.OrbitalGasStrike] = "RoundsDolyMods.Assets.Stratagem.128px.Orbital_Gas_Strike_Stratagem_Icon.png", [HelldiverStratagemType.OrbitalEmsStrike] = "RoundsDolyMods.Assets.Stratagem.128px.Orbital_EMS_Strike_Stratagem_Icon.png", [HelldiverStratagemType.Orbital120mmHEBarrage] = "RoundsDolyMods.Assets.Stratagem.128px.Orbital_120mm_HE_Barrage_Stratagem_Icon.png", [HelldiverStratagemType.Orbital380mmHEBarrage] = "RoundsDolyMods.Assets.Stratagem.128px.Orbital_380mm_HE_Barrage_Stratagem_Icon.png", [HelldiverStratagemType.Eagle500kgBomb] = "RoundsDolyMods.Assets.Stratagem.128px.Eagle_500kg_Bomb_Stratagem_Icon.png", [HelldiverStratagemType.EagleStrafingRun] = "RoundsDolyMods.Assets.Stratagem.128px.Eagle_Strafing_Run_Stratagem_Icon.png", [HelldiverStratagemType.EagleAirstrike] = "RoundsDolyMods.Assets.Stratagem.128px.Eagle_Airstrike_Stratagem_Icon.png", [HelldiverStratagemType.EagleClusterBomb] = "RoundsDolyMods.Assets.Stratagem.128px.Eagle_Cluster_Bomb_Stratagem_Icon.png", [HelldiverStratagemType.EagleRearm] = "RoundsDolyMods.Assets.Stratagem.128px.Eagle_Rearm_Stratagem_Icon.png", [HelldiverStratagemType.MachineGunSentry] = "RoundsDolyMods.Assets.Stratagem.128px.Machine_Gun_Sentry_Stratagem_Icon.png", [HelldiverStratagemType.RocketSentry] = "RoundsDolyMods.Assets.Stratagem.128px.Rocket_Sentry_Stratagem_Icon.png", [HelldiverStratagemType.AutocannonSentry] = "RoundsDolyMods.Assets.Stratagem.128px.Autocannon_Sentry_Stratagem_Icon.png", [HelldiverStratagemType.GatlingSentry] = "RoundsDolyMods.Assets.Stratagem.128px.Gatling_Sentry_Stratagem_Icon.png", [HelldiverStratagemType.LaserSentry] = "RoundsDolyMods.Assets.Stratagem.128px.Laser_Sentry_Stratagem_Icon.png" }; private static readonly Dictionary Sprites = new Dictionary(); internal static Sprite? GetSprite(HelldiverStratagemType type) { if (type == HelldiverStratagemType.None) { return null; } if (Sprites.TryGetValue(type, out Sprite value)) { return value; } if (!ResourceNames.TryGetValue(type, out string value2)) { Sprites[type] = null; return null; } Sprite val = LoadEmbeddedStratagemIcon(value2); Sprites[type] = val; return val; } private static Sprite? LoadEmbeddedStratagemIcon(string resourceName) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0042: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName); if (stream == null) { return null; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false) { filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1, name = resourceName }; if (!ImageConversion.LoadImage(val, memoryStream.ToArray(), false)) { Object.Destroy((Object)(object)val); return null; } return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), (float)((Texture)val).width); } } internal sealed class HelldiverStratagemTargetIcon : MonoBehaviour { private const float HoverOffset = 1.15f; private const float IconScale = 1.05f; private const float IconAlpha = 0.5f; private const float FadeInDurationSeconds = 0.12f; private const float FadeOutDurationSeconds = 0.45f; private const float MinimumVisibleDurationSeconds = 1f; private const int SortingOrder = 1412; private Transform? trackedTarget; private Vector2 frozenPoint; private double spawnTime; private double executeTime; private double fadeStartTime; private double destroyTime; private bool frozen; private SpriteRenderer? iconRenderer; internal static HelldiverStratagemTargetIcon? Spawn(Transform target, HelldiverStratagemType type, double executeTime) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) Sprite sprite = HelldiverStratagemIconLibrary.GetSprite(type); if (sprite == null) { return null; } HelldiverStratagemTargetIcon helldiverStratagemTargetIcon = new GameObject($"DOLY_{type}_TargetIcon").AddComponent(); helldiverStratagemTargetIcon.Configure(target, type, executeTime, sprite); return helldiverStratagemTargetIcon; } private void Configure(Transform target, HelldiverStratagemType type, double executeTime, Sprite sprite) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) trackedTarget = target; frozenPoint = Vector2.op_Implicit(target.position); spawnTime = (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time); this.executeTime = executeTime; float postFireHoldDurationSeconds = GetPostFireHoldDurationSeconds(type); fadeStartTime = Math.Max(spawnTime + 1.0, executeTime + (double)postFireHoldDurationSeconds); destroyTime = fadeStartTime + 0.44999998807907104; iconRenderer = ((Component)this).gameObject.AddComponent(); iconRenderer.sprite = sprite; ((Renderer)iconRenderer).sortingOrder = 1412; ((Renderer)iconRenderer).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)iconRenderer).receiveShadows = false; iconRenderer.color = new Color(1f, 1f, 1f, 0f); ((Component)this).transform.localScale = Vector3.one * 1.05f; UpdateVisual(frozenPoint, spawnTime); } internal void NotifySourceDestroyed() { FreezeAtCurrentPoint(); } private void Update() { //IL_0074: 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_007b: 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_0082: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) double num = (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time); if (num >= destroyTime) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } if (!frozen && (trackedTarget == null || num >= executeTime)) { FreezeAtCurrentPoint(); } UpdateVisual(frozenPoint = (frozen ? frozenPoint : ((trackedTarget != null) ? Vector2.op_Implicit(trackedTarget.position) : frozenPoint)), num); } private void FreezeAtCurrentPoint() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (!frozen) { if (trackedTarget != null) { frozenPoint = Vector2.op_Implicit(trackedTarget.position); } trackedTarget = null; frozen = true; } } private void UpdateVisual(Vector2 point, double currentTime) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) ((Component)this).transform.position = Vector2.op_Implicit(point + Vector2.up * 1.15f); if (iconRenderer != null) { float num = Mathf.Clamp01((float)((currentTime - spawnTime) / 0.11999999731779099)); if (currentTime >= fadeStartTime) { num *= Mathf.Clamp01((float)((destroyTime - currentTime) / 0.44999998807907104)); } iconRenderer.color = new Color(1f, 1f, 1f, 0.5f * num); } } private static float GetPostFireHoldDurationSeconds(HelldiverStratagemType type) { return type switch { HelldiverStratagemType.OrbitalGatlingBarrage => HelldiverStrikeController.GetActiveIndicatorDurationSeconds(type), HelldiverStratagemType.OrbitalGasStrike => HelldiverStrikeController.GetActiveIndicatorDurationSeconds(type), HelldiverStratagemType.OrbitalEmsStrike => HelldiverStrikeController.GetActiveIndicatorDurationSeconds(type), HelldiverStratagemType.Orbital120mmHEBarrage => HelldiverStrikeController.GetActiveIndicatorDurationSeconds(type), HelldiverStratagemType.Orbital380mmHEBarrage => HelldiverStrikeController.GetActiveIndicatorDurationSeconds(type), _ => 0f, }; } } internal sealed class HelldiverStrikeController : MonoBehaviour { private const float DefaultRunPerpendicularJitter = 1.05f; private const float DefaultRunForwardJitterFactor = 0.18f; private const float DefaultRunSideStagger = 1f; private const float DefaultRunSideDrift = 0.55f; private const float DefaultRunShotDelayMin = 0f; private const float DefaultRunShotDelayMax = 0.2f; private const float DefaultRunShotAngleMinDegrees = -2f; private const float DefaultRunShotAngleMaxDegrees = 2f; private const float EagleRunWideShotDelayMin = 0f; private const float EagleRunWideShotDelayMax = 0.2f; private const float EagleRunWideShotAngleMinDegrees = -3f; private const float EagleRunWideShotAngleMaxDegrees = 3f; private const float PrecisionRadius = 8f; private const float PrecisionDirectDamage = 300f; private const float PrecisionDirectPercentDamage = 0.3f; private const float PrecisionExplosionDamage = 300f; private const float PrecisionSpawnHeight = 8f; private const float PrecisionProjectileSpeed = 200f; private const float PrecisionWallUnlockOffset = 3f; private const float GatlingRadius = 6f; private const int GatlingBarrageCount = 200; private const int GatlingShotsPerBarrage = 2; private const float GatlingInterval = 0.05f; private const float GatlingDamage = 8f; private const float GatlingPercentDamage = 0.1f; private const float GatlingSpawnHeight = 8f; private const float GatlingProjectileSpeed = 200f; private const float GatlingWallUnlockOffset = 2f; private const float Artillery120mmRadius = 10f; private const int Artillery120mmBarrageCount = 20; private const int Artillery120mmShotsPerBarrage = 1; private const float Artillery120mmInterval = 0.4f; private const float Artillery120mmDirectDamage = 100f; private const float Artillery120mmDirectPercentDamage = 0.2f; private const float Artillery120mmExplosionRadius = 5f; private const float Artillery120mmExplosionDamage = 50f; private const float Artillery120mmExplosionPercentDamage = 0.2f; private const float Artillery120mmSpawnHeight = 8f; private const float Artillery120mmProjectileSpeed = 100f; private const float Artillery120mmWallUnlockOffset = 3f; private const float Artillery380mmRadius = 18f; private const int Artillery380mmBarrageCount = 16; private const int Artillery380mmShotsPerBarrage = 1; private const float Artillery380mmInterval = 0.9f; private const float Artillery380mmDirectDamage = 150f; private const float Artillery380mmDirectPercentDamage = 0.3f; private const float Artillery380mmExplosionRadius = 6.5f; private const float Artillery380mmExplosionDamage = 100f; private const float Artillery380mmExplosionPercentDamage = 0.3f; private const float Artillery380mmSpawnHeight = 8f; private const float Artillery380mmProjectileSpeed = 80f; private const float Artillery380mmWallUnlockOffset = 5f; private const float GasDirectDamage = 40f; private const float GasDirectPercentDamage = 0.1f; private const float GasRadius = 10f; private const float GasDuration = 10f; private const float GasTickInterval = 0.5f; private const float GasTickDamage = 8f; private const float GasTickPercentDamage = 0.08f; private const float GasSlowAmount = 0.4f; private const float GasSpawnHeight = 8f; private const float GasProjectileSpeed = 120f; private const float GasWallUnlockOffset = 3f; private const float EmsDirectDamage = 40f; private const float EmsDirectPercentDamage = 0.1f; private const float EmsRadius = 14f; private const float EmsDuration = 10f; private const float EmsInitialStunDuration = 1f; private const float EmsSlowAmount = 0.7f; private const float EmsSpawnHeight = 8f; private const float EmsProjectileSpeed = 160f; private const float EmsWallUnlockOffset = 2f; private const float EagleDirectDamage = 100f; private const float EagleDirectPercentDamage = 0.4f; private const float EagleRadius = 22f; private const float EagleDamage = 500f; private const float EaglePercentDamage = 1f; private const float EagleEdgeDamageMultiplier = 0f; private const float EagleExplosionDelaySeconds = 0.5f; private const float EagleSpawnHeight = 8f; private const float EagleProjectileSpeed = 120f; private const float EagleWallUnlockOffset = 4f; private const float EagleLodgedShellLength = 0.92f; private const float EagleLodgedShellWidth = 0.22f; private const int EagleStrafingRunCount = 80; private const float EagleStrafingRunStart = -5f; private const float EagleStrafingRunEnd = 18f; private const float EagleStrafingRunSpeed = 100f; private const float EagleStrafingRunDamage = 7f; private const float EagleStrafingRunPercentDamage = 0.03f; private const float EagleStrafingRunProjectileSpeed = 160f; private const float EagleStrafingRunWallUnlockOffset = 4f; private const int EagleAirstrikeCount = 22; private const float EagleAirstrikeStart = -4f; private const float EagleAirstrikeEnd = 14f; private const float EagleAirstrikeSpeed = 80f; private const float EagleAirstrikeDirectDamage = 10f; private const float EagleAirstrikeDirectPercentDamage = 0.04f; private const float EagleAirstrikeExplosionDamage = 20f; private const float EagleAirstrikeExplosionPercentDamage = 0.12f; private const float EagleAirstrikeExplosionRadius = 2.5f; private const float EagleAirstrikeProjectileSpeed = 120f; private const float EagleAirstrikeWallUnlockOffset = 4f; private const float EagleAirstrikeShotDelayMin = 0f; private const float EagleAirstrikeShotDelayMax = 0.5f; private const float EagleAirstrikeShotAngleMinDegrees = -5f; private const float EagleAirstrikeShotAngleMaxDegrees = 5f; private const int EagleClusterBombCount = 50; private const float EagleClusterBombStart = -6f; private const float EagleClusterBombEnd = 16f; private const float EagleClusterBombSpeed = 100f; private const float EagleClusterBombDirectDamage = 0f; private const float EagleClusterBombDirectPercentDamage = 0f; private const float EagleClusterBombExplosionDamage = 32f; private const float EagleClusterBombExplosionPercentDamage = 0f; private const float EagleClusterBombExplosionRadius = 3f; private const float EagleClusterBombProjectileSpeed = 80f; private const float EagleClusterBombWallUnlockOffset = 5f; private const int EagleClusterBombBounceCount = 3; private const float EagleClusterBombBounceSpeedRetention = 0.55f; private const float EagleClusterBombDetonationDelayMinSeconds = 2f; private const float EagleClusterBombDetonationDelayMaxSeconds = 3f; private const float EagleClusterBombShotDelayMin = 0f; private const float EagleClusterBombShotDelayMax = 0.4f; private const float EagleClusterBombShotAngleMinDegrees = -5f; private const float EagleClusterBombShotAngleMaxDegrees = 5f; private HelldiverStratagemType type; private Vector2 center; private Vector2 runDirection; private int ownerPlayerId; private double executeTime; private Random? random; private bool triggered; private bool arrivalFlashTriggered; private int barrageIndex; private double nextBarrageTime; private Color color; internal static float GetActiveIndicatorDurationSeconds(HelldiverStratagemType type) { switch (type) { case HelldiverStratagemType.OrbitalPrecisionStrike: return 1f; case HelldiverStratagemType.OrbitalGatlingBarrage: return 10.45f; case HelldiverStratagemType.OrbitalGasStrike: return 10f; case HelldiverStratagemType.OrbitalEmsStrike: return 10f; case HelldiverStratagemType.Orbital120mmHEBarrage: return 9.1f; case HelldiverStratagemType.Orbital380mmHEBarrage: return 15.9f; case HelldiverStratagemType.Eagle500kgBomb: return 1.85f; case HelldiverStratagemType.EagleStrafingRun: return GetRunDuration(-5f, 18f, 100f) + 0.45f; case HelldiverStratagemType.EagleAirstrike: return GetRunDuration(-4f, 14f, 80f) + 0.55f; case HelldiverStratagemType.EagleClusterBomb: return GetRunDuration(-6f, 16f, 100f) + 0.7f; case HelldiverStratagemType.EagleRearm: return 0f; default: if (HelldiverClassRegistry.IsSentryStratagem(type)) { return 0f; } return 1f; } } internal void Configure(HelldiverStratagemType type, Vector2 center, Vector2 runDirection, int ownerPlayerId, int seed, double executeTime) { //IL_0008: 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) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_0059: 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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) this.type = type; this.center = center; this.runDirection = ((((Vector2)(ref runDirection)).sqrMagnitude > 0.0001f) ? ((Vector2)(ref runDirection)).normalized : Vector2.right); this.ownerPlayerId = ownerPlayerId; this.executeTime = executeTime; random = new Random(seed); color = HelldiverClassRegistry.GetDefinition(type).Color; ((Component)this).transform.position = new Vector3(center.x, center.y, 0f); switch (type) { case HelldiverStratagemType.OrbitalGatlingBarrage: HelldiverGatlingGunPool.Warm(); return; case HelldiverStratagemType.EagleClusterBomb: HelldiverBombGunPool.Warm(); return; } if (HelldiverClassRegistry.IsSentryStratagem(type)) { HelldiverSentryGunPool.Warm(); } else { HelldiverPrecisionGunPool.Warm(GetPrecisionImpactMode(type)); } } private void Update() { double now = (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time); switch (type) { case HelldiverStratagemType.OrbitalPrecisionStrike: UpdatePrecision(now); break; case HelldiverStratagemType.OrbitalGatlingBarrage: UpdateGatling(now); break; case HelldiverStratagemType.OrbitalGasStrike: UpdateGas(now); break; case HelldiverStratagemType.OrbitalEmsStrike: UpdateEms(now); break; case HelldiverStratagemType.Orbital120mmHEBarrage: Update120mm(now); break; case HelldiverStratagemType.Orbital380mmHEBarrage: Update380mm(now); break; case HelldiverStratagemType.Eagle500kgBomb: UpdateEagle(now); break; case HelldiverStratagemType.EagleStrafingRun: UpdateEagleStrafingRun(now); break; case HelldiverStratagemType.EagleAirstrike: UpdateEagleAirstrike(now); break; case HelldiverStratagemType.EagleClusterBomb: UpdateEagleClusterBomb(now); break; case HelldiverStratagemType.EagleRearm: Object.Destroy((Object)(object)((Component)this).gameObject); break; case HelldiverStratagemType.MachineGunSentry: case HelldiverStratagemType.RocketSentry: case HelldiverStratagemType.AutocannonSentry: case HelldiverStratagemType.GatlingSentry: case HelldiverStratagemType.LaserSentry: UpdateSentry(now); break; } } private void OnDestroy() { } private void UpdatePrecision(double now) { if (!triggered && now >= executeTime) { triggered = true; FirePrecisionShot(); } if (triggered && now >= executeTime + 1.0) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void UpdateSentry(double now) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) if (!triggered && now >= executeTime) { triggered = true; Player val = HolySmiteEffect.ResolvePlayerById(ownerPlayerId); if (val != null && (PhotonNetwork.OfflineMode || (val.data?.view != null && val.data.view.IsMine))) { HelldiverHellpodController.ResolveDeployment(center, out var fallStart, out var landingPoint); HelldiverRuntime.GetOrAdd(val).BroadcastSpawnSentryHellpod(type, ownerPlayerId, random?.Next() ?? 0, fallStart, landingPoint, now); } } if (triggered) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void UpdateGatling(double now) { if (!arrivalFlashTriggered && now >= executeTime) { arrivalFlashTriggered = true; nextBarrageTime = executeTime; } while (arrivalFlashTriggered && barrageIndex < 200 && now >= nextBarrageTime) { FireGatlingBurst(); barrageIndex++; nextBarrageTime += 0.05000000074505806; } if (arrivalFlashTriggered && barrageIndex >= 200 && now >= nextBarrageTime + 0.44999998807907104) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void UpdateGas(double now) { if (!triggered && now >= executeTime) { triggered = true; FireGasShot(); } if (triggered && now >= executeTime + 1.5) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void Update120mm(double now) { if (!arrivalFlashTriggered && now >= executeTime) { arrivalFlashTriggered = true; nextBarrageTime = executeTime; } while (arrivalFlashTriggered && barrageIndex < 20 && now >= nextBarrageTime) { Fire120mmBurst(); barrageIndex++; nextBarrageTime += 0.4000000059604645; } if (arrivalFlashTriggered && barrageIndex >= 20 && now >= nextBarrageTime + 1.100000023841858) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void UpdateEms(double now) { if (!triggered && now >= executeTime) { triggered = true; FireEmsShot(); } if (triggered && now >= executeTime + 1.25) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void Update380mm(double now) { if (!arrivalFlashTriggered && now >= executeTime) { arrivalFlashTriggered = true; nextBarrageTime = executeTime; } while (arrivalFlashTriggered && barrageIndex < 16 && now >= nextBarrageTime) { Fire380mmBurst(); barrageIndex++; nextBarrageTime += 0.8999999761581421; } if (arrivalFlashTriggered && barrageIndex >= 16 && now >= nextBarrageTime + 1.5) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void UpdateEagle(double now) { if (!arrivalFlashTriggered && now >= executeTime) { arrivalFlashTriggered = true; FireEagleShot(); } if (arrivalFlashTriggered && now >= executeTime + 0.5 + 1.350000023841858) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void UpdateEagleStrafingRun(double now) { UpdateEagleRun(now, 80, -5f, 18f, 100f, SpawnEagleStrafingShot, 0f, 0.2f, -3f, 3f, 0.45f); } private void UpdateEagleAirstrike(double now) { UpdateEagleRun(now, 22, -4f, 14f, 80f, SpawnEagleAirstrikeShot, 0f, 0.5f, -5f, 5f, 0.55f); } private void UpdateEagleClusterBomb(double now) { UpdateEagleRun(now, 50, -6f, 16f, 100f, SpawnEagleClusterBombShot, 0f, 0.4f, -5f, 5f, 0.7f); } private void UpdateEagleRun(double now, int projectileCount, float runStart, float runEnd, float runSpeed, Action spawnAction, float shotDelayMin, float shotDelayMax, float shotAngleMinDegrees, float shotAngleMaxDegrees, float cleanupDelay) { //IL_0052: 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_005b: Unknown result type (might be due to invalid IL or missing references) if (!arrivalFlashTriggered && now >= executeTime) { arrivalFlashTriggered = true; nextBarrageTime = executeTime; barrageIndex = 0; } if (arrivalFlashTriggered && projectileCount > 0) { float runShotInterval = GetRunShotInterval(runStart, runEnd, runSpeed, projectileCount); while (barrageIndex < projectileCount && now >= nextBarrageTime) { Vector2 runShotTarget = GetRunShotTarget(runStart, runEnd, projectileCount, barrageIndex, runShotInterval); ScheduleRunShot(spawnAction, runShotTarget, GetRunShotDelay(shotDelayMin, shotDelayMax), GetRunShotAngleDegrees(shotAngleMinDegrees, shotAngleMaxDegrees)); barrageIndex++; nextBarrageTime += runShotInterval; } if (barrageIndex >= projectileCount && now >= nextBarrageTime + (double)cleanupDelay) { Object.Destroy((Object)(object)((Component)this).gameObject); } } } private void FireGatlingBurst() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (random != null) { Vector2 spawnPoint = default(Vector2); for (int i = 0; i < 2; i++) { float num = Mathf.Lerp(-6f, 6f, (float)random.NextDouble()); ((Vector2)(ref spawnPoint))..ctor(center.x + num, ResolveGatlingSpawnY()); float unlockDepthY = center.y + 2f; SpawnGatlingProjectile(spawnPoint, unlockDepthY); } } } private void SpawnEagleStrafingShot(Vector2 targetPoint, float angleDegrees) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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) //IL_0034: 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_0054: Unknown result type (might be due to invalid IL or missing references) Vector2 runShotFlightDirection = GetRunShotFlightDirection(angleDegrees); if (TryResolveProjectileOwner(out Player owner) && HelldiverGatlingGunPool.Configure(owner, 160f, 7f, 0.03f, targetPoint.y + 4f, color, runShotFlightDirection)) { HelldiverGatlingGunPool.Fire(owner, new Vector2(targetPoint.x, ResolveOrbitalSpawnY(8f))); } } private void SpawnEagleAirstrikeShot(Vector2 targetPoint, float angleDegrees) { //IL_0001: 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) SpawnEagleExplosiveShot(targetPoint, GetRunShotFlightDirection(angleDegrees), 120f, 4f, 10f, 0.04f, 2.5f, 20f, 0.12f); } private void SpawnEagleClusterBombShot(Vector2 targetPoint, float angleDegrees) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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) Vector2 runShotFlightDirection = GetRunShotFlightDirection(angleDegrees); if (TryResolveProjectileOwner(out Player owner) && HelldiverBombGunPool.Configure(owner, 80f, runShotFlightDirection, targetPoint.y + 5f, 0f, 0f, 3f, 32f, 0f, 3, 0.55f, GetClusterBombDetonationDelaySeconds())) { HelldiverBombGunPool.Fire(owner, new Vector2(targetPoint.x, ResolveOrbitalSpawnY(8f))); } } private void SpawnEagleExplosiveShot(Vector2 targetPoint, Vector2 flightDirection, float projectileSpeed, float wallUnlockOffset, float directDamage, float directPercentDamage, float explosionRadius, float explosionDamage, float explosionPercentDamage, HelldiverShellImpactMode impactMode = HelldiverShellImpactMode.ImmediateExplosion, float detonationDelaySeconds = 0f) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_00b0: Unknown result type (might be due to invalid IL or missing references) if (TryResolveProjectileOwner(out Player owner) && HelldiverPrecisionGunPool.Configure(owner, directDamage, directPercentDamage, new HelldiverShellImpactConfig { Mode = impactMode, OwnerPlayerId = owner.playerID, Speed = projectileSpeed, UnlockDepthY = targetPoint.y + wallUnlockOffset, FlightDirection = flightDirection, ExplosionSurfaceOffset = 0.5f, ExplosionRadius = explosionRadius, ExplosionDamage = explosionDamage, ExplosionPercentDamage = explosionPercentDamage, DetonationDelaySeconds = detonationDelaySeconds, Color = color, ExplosionPresentationSize = HelldiverExplosionPresentationSize.Small, ExplosionSoundSize = HelldiverExplosionPresentationSize.Small, ExplosionSoundVolumeMultiplier = 1f })) { HelldiverPrecisionGunPool.Fire(owner, new Vector2(targetPoint.x, ResolveOrbitalSpawnY(8f)), impactMode); } } private void Fire120mmBurst() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (random != null) { Vector2 spawnPoint = default(Vector2); for (int i = 0; i < 1; i++) { float num = Mathf.Lerp(-10f, 10f, (float)random.NextDouble()); ((Vector2)(ref spawnPoint))..ctor(center.x + num, Resolve120mmSpawnY()); float unlockDepthY = center.y + 3f; Spawn120mmProjectile(spawnPoint, unlockDepthY); } } } private void Fire380mmBurst() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (random != null) { Vector2 spawnPoint = default(Vector2); for (int i = 0; i < 1; i++) { float num = Mathf.Lerp(-18f, 18f, (float)random.NextDouble()); ((Vector2)(ref spawnPoint))..ctor(center.x + num, Resolve380mmSpawnY()); float unlockDepthY = center.y + 5f; Spawn380mmProjectile(spawnPoint, unlockDepthY); } } } internal static void SpawnImpactFlash(Vector2 point, Color flashColor) { //IL_0005: 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_0010: Unknown result type (might be due to invalid IL or missing references) new GameObject("DOLY_HelldiverImpactFlash").AddComponent().Configure(point, flashColor); } internal static void SpawnVanillaExplosion(Vector2 point, float radius, float damage, Player? owner, bool ignoreWalls) { //IL_0005: 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_0010: 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) GameObject val = new GameObject("DOLY_HelldiverExplosion"); val.transform.position = Vector2.op_Implicit(point); val.AddComponent().Configure(radius, damage, owner, ignoreWalls); } internal static void ApplyExplosionDamageSkippingPlayer(Vector2 center, float radius, float flatDamage, int ownerPlayerId, int ignoredPlayerId, bool ignoreWalls) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) ApplyRadialDamage(center, radius, flatDamage, 0f, 0f, ownerPlayerId, ignoreWalls, ignoredPlayerId); } internal static void ApplyRadialDamage(Vector2 center, float radius, float flatDamage, float percentageDamage, float edgeMultiplier, int ownerPlayerId, bool ignoreWalls, int ignoredPlayerId = -1) { //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: 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_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) List list = PlayerManager.instance?.players; Player val = ResolvePlayerById(ownerPlayerId); object obj; if (val == null) { obj = null; } else { CharacterData data = val.data; if (data == null) { obj = null; } else { WeaponHandler weaponHandler = data.weaponHandler; if (weaponHandler == null) { obj = null; } else { Gun gun = weaponHandler.gun; obj = ((gun != null) ? ((Component)gun).gameObject : null); } } } GameObject val2 = (GameObject)obj; if (list != null) { foreach (Player item in list) { if (item == null || item.data == null || item.data.dead || item.data.healthHandler == null || (ignoredPlayerId >= 0 && item.playerID == ignoredPlayerId) || !CanAffectPlayer(item, center, ignoreWalls)) { continue; } Bounds val3 = (Bounds)((item.data.mainCol != null) ? item.data.mainCol.bounds : new Bounds(((Component)item).transform.position, Vector3.one)); float num = Vector2.Distance(Vector2.op_Implicit(((Bounds)(ref val3)).ClosestPoint(Vector2.op_Implicit(center))), center); if (num > radius) { continue; } float num2 = Mathf.Lerp(1f, Mathf.Clamp01(edgeMultiplier), (radius <= 0.0001f) ? 1f : (num / radius)); float num3 = (flatDamage + percentageDamage * item.data.maxHealth) * num2; if (!(num3 <= 0f)) { Vector2 val4 = Vector2.op_Implicit(((Component)item).transform.position) - center; if (((Vector2)(ref val4)).sqrMagnitude <= 0.0001f) { val4 = Vector2.up; } ((Damagable)item.data.healthHandler).TakeDamage(((Vector2)(ref val4)).normalized * num3, center, val2, val, true, false); } } } HelldiverSentryDamageable.ApplyRadialDamage(center, radius, flatDamage, percentageDamage, edgeMultiplier, ownerPlayerId, ignoreWalls); } internal static bool CanAffectPlayer(Player player, Vector2 origin, bool ignoreWalls) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (ignoreWalls || PlayerManager.instance == null) { return true; } return PlayerManager.instance.CanSeePlayer(origin, player).canSee; } private void FirePrecisionShot() { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) if (TryResolveProjectileOwner(out Player owner)) { Vector2 spawnPoint = default(Vector2); ((Vector2)(ref spawnPoint))..ctor(center.x, ResolveOrbitalSpawnY(8f)); float unlockDepthY = center.y + 3f; if (HelldiverPrecisionGunPool.Configure(owner, 300f, 0.3f, new HelldiverShellImpactConfig { OwnerPlayerId = owner.playerID, Speed = 200f, UnlockDepthY = unlockDepthY, ExplosionSurfaceOffset = 0.5f, ExplosionRadius = 8f, ExplosionDamage = 300f, Color = color, ExplosionPresentationSize = HelldiverExplosionPresentationSize.Medium, ExplosionSoundSize = HelldiverExplosionPresentationSize.Small, ExplosionSoundVolumeMultiplier = 1f })) { HelldiverPrecisionGunPool.Fire(owner, spawnPoint); } } } private void SpawnGatlingProjectile(Vector2 spawnPoint, float unlockDepthY) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (TryResolveProjectileOwner(out Player owner) && HelldiverGatlingGunPool.Configure(owner, 200f, 8f, 0.1f, unlockDepthY, color)) { HelldiverGatlingGunPool.Fire(owner, spawnPoint); } } private void Spawn120mmProjectile(Vector2 spawnPoint, float unlockDepthY) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) if (TryResolveProjectileOwner(out Player owner) && HelldiverPrecisionGunPool.Configure(owner, 100f, 0.2f, new HelldiverShellImpactConfig { OwnerPlayerId = owner.playerID, Speed = 100f, UnlockDepthY = unlockDepthY, ExplosionSurfaceOffset = 0.5f, ExplosionRadius = 5f, ExplosionDamage = 50f, ExplosionPercentDamage = 0.2f, Color = color, ExplosionPresentationSize = HelldiverExplosionPresentationSize.Small, ExplosionSoundSize = HelldiverExplosionPresentationSize.Small, ExplosionSoundVolumeMultiplier = 1f })) { HelldiverPrecisionGunPool.Fire(owner, spawnPoint); } } private void Spawn380mmProjectile(Vector2 spawnPoint, float unlockDepthY) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) if (TryResolveProjectileOwner(out Player owner) && HelldiverPrecisionGunPool.Configure(owner, 150f, 0.3f, new HelldiverShellImpactConfig { OwnerPlayerId = owner.playerID, Speed = 80f, UnlockDepthY = unlockDepthY, ExplosionSurfaceOffset = 0.5f, ExplosionRadius = 6.5f, ExplosionDamage = 100f, ExplosionPercentDamage = 0.3f, Color = color, ExplosionPresentationSize = HelldiverExplosionPresentationSize.Medium, ExplosionSoundSize = HelldiverExplosionPresentationSize.Small, ExplosionSoundVolumeMultiplier = 1f })) { HelldiverPrecisionGunPool.Fire(owner, spawnPoint); } } private void FireGasShot() { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) if (TryResolveProjectileOwner(out Player owner)) { Vector2 spawnPoint = default(Vector2); ((Vector2)(ref spawnPoint))..ctor(center.x, ResolveOrbitalSpawnY(8f)); float unlockDepthY = center.y + 3f; if (HelldiverPrecisionGunPool.Configure(owner, 40f, 0.1f, new HelldiverShellImpactConfig { Mode = HelldiverShellImpactMode.GasCloud, OwnerPlayerId = owner.playerID, Speed = 120f, UnlockDepthY = unlockDepthY, ExplosionSurfaceOffset = 0.5f, GasRadius = 10f, GasDuration = 10f, GasTickInterval = 0.5f, GasTickDamage = 8f, GasTickPercentDamage = 0.08f, GasSlowAmount = 0.4f, Color = color, ExplosionPresentationSize = HelldiverExplosionPresentationSize.Small, ExplosionSoundSize = HelldiverExplosionPresentationSize.Small, ExplosionSoundVolumeMultiplier = 0.9f })) { HelldiverPrecisionGunPool.Fire(owner, spawnPoint, HelldiverShellImpactMode.GasCloud); } } } private void FireEmsShot() { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) if (TryResolveProjectileOwner(out Player owner)) { Vector2 spawnPoint = default(Vector2); ((Vector2)(ref spawnPoint))..ctor(center.x, ResolveOrbitalSpawnY(8f)); float unlockDepthY = center.y + 2f; if (HelldiverPrecisionGunPool.Configure(owner, 40f, 0.1f, new HelldiverShellImpactConfig { Mode = HelldiverShellImpactMode.EmsField, OwnerPlayerId = owner.playerID, Speed = 160f, UnlockDepthY = unlockDepthY, ExplosionSurfaceOffset = 0.5f, EmsRadius = 14f, EmsDuration = 10f, EmsInitialStunDuration = 1f, EmsSlowAmount = 0.7f, Color = color, ExplosionPresentationSize = HelldiverExplosionPresentationSize.Small, ExplosionSoundSize = HelldiverExplosionPresentationSize.Small, ExplosionSoundVolumeMultiplier = 0.85f })) { HelldiverPrecisionGunPool.Fire(owner, spawnPoint, HelldiverShellImpactMode.EmsField); } } } private void FireEagleShot() { //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) if (TryResolveProjectileOwner(out Player owner)) { Vector2 spawnPoint = default(Vector2); ((Vector2)(ref spawnPoint))..ctor(center.x, ResolveOrbitalSpawnY(8f)); float unlockDepthY = center.y + 4f; if (HelldiverPrecisionGunPool.Configure(owner, 100f, 0.4f, new HelldiverShellImpactConfig { Mode = HelldiverShellImpactMode.Eagle500kg, OwnerPlayerId = owner.playerID, Speed = 120f, UnlockDepthY = unlockDepthY, ExplosionSurfaceOffset = 1f, ExplosionRadius = 22f, ExplosionDamage = 500f, ExplosionPercentDamage = 1f, ExplosionEdgeDamageMultiplier = 0f, DetonationDelaySeconds = 0.5f, LodgedShellLength = 0.92f, LodgedShellWidth = 0.22f, LodgedShellAngleDegrees = -62f, Color = color, ExplosionPresentationSize = HelldiverExplosionPresentationSize.Large, ExplosionSoundSize = HelldiverExplosionPresentationSize.Large, ExplosionSoundVolumeMultiplier = 1f })) { HelldiverPrecisionGunPool.Fire(owner, spawnPoint, HelldiverShellImpactMode.Eagle500kg); } } } private bool TryResolveProjectileOwner([NotNullWhen(true)] out Player? owner) { owner = ResolvePlayerById(ownerPlayerId); return owner?.data != null; } private static HelldiverShellImpactMode GetPrecisionImpactMode(HelldiverStratagemType type) { return type switch { HelldiverStratagemType.OrbitalGasStrike => HelldiverShellImpactMode.GasCloud, HelldiverStratagemType.OrbitalEmsStrike => HelldiverShellImpactMode.EmsField, HelldiverStratagemType.Eagle500kgBomb => HelldiverShellImpactMode.Eagle500kg, _ => HelldiverShellImpactMode.ImmediateExplosion, }; } private float ResolveGatlingSpawnY() { return ResolveOrbitalSpawnY(8f); } private float Resolve120mmSpawnY() { return ResolveOrbitalSpawnY(8f); } private float Resolve380mmSpawnY() { return ResolveOrbitalSpawnY(8f); } private float ResolveOrbitalSpawnY(float fallbackHeight) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) float num = center.y + fallbackHeight; Camera main = Camera.main; if (main == null) { return num; } Vector3 val = main.ViewportToWorldPoint(new Vector3(0.5f, 1.04f, Mathf.Abs(((Component)main).transform.position.z))); return Mathf.Max(num, val.y); } private static float GetRunDuration(float runStart, float runEnd, float runSpeed) { return Mathf.Abs(runEnd - runStart) / Mathf.Max(0.0001f, runSpeed); } private static float GetRunShotInterval(float runStart, float runEnd, float runSpeed, int projectileCount) { if (projectileCount <= 1) { return GetRunDuration(runStart, runEnd, runSpeed); } return GetRunDuration(runStart, runEnd, runSpeed) / (float)(projectileCount - 1); } private Vector2 GetRunShotTarget(float runStart, float runEnd, int projectileCount, int shotIndex, float interval) { //IL_001f: 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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) Vector2 val = ((((Vector2)(ref runDirection)).sqrMagnitude > 0.0001f) ? ((Vector2)(ref runDirection)).normalized : Vector2.right); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0f - val.y, val.x); float num = ((projectileCount <= 1) ? 0.5f : ((float)shotIndex / (float)(projectileCount - 1))); float num2 = Mathf.Lerp(runStart, runEnd, num); float num3 = ((float)random.NextDouble() - 0.5f) * interval * Mathf.Max(1f, Mathf.Abs(runEnd - runStart)) * 0.18f; float num4 = ((((shotIndex + random.Next(0, 2)) & 1) == 0) ? (-1f) : 1f); float num5 = Mathf.Lerp(0.35f, 1f, (float)random.NextDouble()) * 1f; float num6 = ((float)random.NextDouble() - 0.5f) * 2f * 0.55f; float num7 = ((float)random.NextDouble() - 0.5f) * 2f * 1.05f; float num8 = num4 * num5 + num6 + num7; return center + val * (num2 + num3) + val2 * num8; } private float GetRunShotDelay(float minDelaySeconds, float maxDelaySeconds) { if (random != null) { return Mathf.Lerp(Mathf.Max(0f, minDelaySeconds), Mathf.Max(minDelaySeconds, maxDelaySeconds), (float)random.NextDouble()); } return Mathf.Max(0f, minDelaySeconds); } private float GetRunShotAngleDegrees(float minAngleDegrees, float maxAngleDegrees) { if (random == null) { return 0f; } return Mathf.Lerp(minAngleDegrees, maxAngleDegrees, (float)random.NextDouble()); } private float GetClusterBombDetonationDelaySeconds() { if (random == null) { return 2f; } return Mathf.Lerp(2f, 3f, (float)random.NextDouble()); } private Vector2 GetRunShotFlightDirection(float angleDegrees) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) Vector2 val = Vector2.op_Implicit(Quaternion.Euler(0f, 0f, angleDegrees) * Vector3.down); return ((Vector2)(ref val)).normalized; } private void ScheduleRunShot(Action spawnAction, Vector2 targetPoint, float delaySeconds, float angleDegrees) { //IL_0015: 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) if (delaySeconds <= 0.0001f) { spawnAction(targetPoint, angleDegrees); } else { ((MonoBehaviour)this).StartCoroutine(ExecuteRunShotAfterDelay(spawnAction, targetPoint, delaySeconds, angleDegrees)); } } private IEnumerator ExecuteRunShotAfterDelay(Action spawnAction, Vector2 targetPoint, float delaySeconds, float angleDegrees) { //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) yield return (object)new WaitForSecondsRealtime(delaySeconds); if ((Object)(object)this != (Object)null) { spawnAction(targetPoint, angleDegrees); } } private static Player? ResolvePlayerById(int playerId) { List list = PlayerManager.instance?.players; if (list == null) { return null; } foreach (Player item in list) { if (item != null && item.playerID == playerId) { return item; } } return null; } } internal sealed class HelldiverImpactFlash : MonoBehaviour { private const float LifetimeSeconds = 0.12f; private LineRenderer? beamRenderer; private Material? beamMaterial; private float elapsed; internal void Configure(Vector2 point, Color color) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_00c6: 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_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) ((Component)this).transform.position = Vector2.op_Implicit(point); beamRenderer = ((Component)this).gameObject.AddComponent(); beamMaterial = new Material(Shader.Find("Sprites/Default")); ((Renderer)beamRenderer).material = beamMaterial; beamRenderer.useWorldSpace = true; beamRenderer.loop = false; beamRenderer.positionCount = 2; beamRenderer.numCapVertices = 6; beamRenderer.numCornerVertices = 6; beamRenderer.alignment = (LineAlignment)0; ((Renderer)beamRenderer).sortingOrder = 1410; beamRenderer.startWidth = 0.04f; beamRenderer.endWidth = 0.18f; beamRenderer.startColor = color; beamRenderer.endColor = new Color(color.r, color.g, color.b, 0f); beamRenderer.SetPosition(0, Vector2.op_Implicit(point + Vector2.up * 8f)); beamRenderer.SetPosition(1, Vector2.op_Implicit(point)); } private void Update() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_0070: Unknown result type (might be due to invalid IL or missing references) elapsed += TimeHandler.deltaTime; if (beamRenderer != null) { float a = Mathf.Clamp01(1f - elapsed / 0.12f); Color startColor = beamRenderer.startColor; startColor.a = a; Color endColor = beamRenderer.endColor; endColor.a = 0f; beamRenderer.startColor = startColor; beamRenderer.endColor = endColor; } if (elapsed >= 0.12f) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void OnDestroy() { if (beamMaterial != null) { Object.Destroy((Object)(object)beamMaterial); } } } internal static class HelldiverToxicCloudPresentation { internal static void Spawn(Transform parent, float radius, float duration, float initialElapsedSeconds = 0f) { //IL_0005: 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("DOLY_GasCloudCircleVisual"); val.transform.SetParent(parent, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.AddComponent().Configure(radius, duration, initialElapsedSeconds); } } internal sealed class HelldiverGasCloudCircleVisual : MonoBehaviour { private const int SegmentCount = 48; private static readonly Color OutlineColor = new Color(0.48f, 0.95f, 0.46f, 0.85f); private static readonly Color FillColor = new Color(0.36f, 0.86f, 0.3f, 0.11f); private static Mesh? sharedDiscMesh; private readonly Vector3[] outerPoints = (Vector3[])(object)new Vector3[48]; private float radius; private float duration; private float elapsed; private LineRenderer? outlineRenderer; private Material? outlineMaterial; private MeshRenderer? fillRenderer; private Material? fillMaterial; internal void Configure(float radius, float duration, float initialElapsedSeconds) { this.radius = Mathf.Max(0.25f, radius); this.duration = Mathf.Max(0.1f, duration); elapsed = Mathf.Clamp(initialElapsedSeconds, 0f, this.duration); outlineRenderer = CreateRenderer("Outline", ref outlineMaterial, 1404); fillRenderer = CreateFillRenderer(ref fillMaterial, 1403); Render(Mathf.Clamp01(elapsed / this.duration)); } private void Update() { elapsed += TimeHandler.deltaTime; Render(Mathf.Clamp01(elapsed / duration)); if (elapsed >= duration) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void OnDestroy() { if (outlineMaterial != null) { Object.Destroy((Object)(object)outlineMaterial); } if (fillMaterial != null) { Object.Destroy((Object)(object)fillMaterial); } } private void Render(float lifetimeProgress) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_012d: 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 (outlineRenderer != null && fillRenderer != null && fillMaterial != null) { float num = 0.5f + 0.5f * Mathf.Sin(Time.time * 3.5f); float num2 = Mathf.Lerp(1f, 0.52f, lifetimeProgress); float num3 = radius * (0.92f + 0.04f * num); Vector3 val = default(Vector3); for (int i = 0; i < 48; i++) { float num4 = (float)i / 48f * MathF.PI * 2f; ((Vector3)(ref val))..ctor(Mathf.Cos(num4), Mathf.Sin(num4), 0f); outerPoints[i] = val * num3; } Color outlineColor = OutlineColor; outlineColor.a *= num2; outlineRenderer.widthMultiplier = Mathf.Clamp(radius * 0.08f, 0.08f, 0.32f); outlineRenderer.startColor = outlineColor; outlineRenderer.endColor = outlineColor; outlineRenderer.SetPositions(outerPoints); Color fillColor = FillColor; fillColor.a *= num2; fillMaterial.color = fillColor; float num5 = radius * (0.9f + 0.03f * num); ((Component)fillRenderer).transform.localScale = new Vector3(num5, num5, 1f); } } private LineRenderer CreateRenderer(string childName, ref Material? material, int sortingOrder) { //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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown GameObject val = new GameObject(childName); val.transform.SetParent(((Component)this).transform, false); material = new Material(Shader.Find("Sprites/Default")); LineRenderer obj = val.AddComponent(); ((Renderer)obj).material = material; obj.useWorldSpace = false; obj.loop = true; obj.positionCount = 48; obj.numCapVertices = 8; obj.numCornerVertices = 8; obj.alignment = (LineAlignment)0; obj.textureMode = (LineTextureMode)0; ((Renderer)obj).sortingOrder = sortingOrder; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; return obj; } private MeshRenderer CreateFillRenderer(ref Material? material, int sortingOrder) { //IL_0005: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Fill"); val.transform.SetParent(((Component)this).transform, false); material = new Material(Shader.Find("Sprites/Default")); val.AddComponent().sharedMesh = GetOrCreateDiscMesh(); MeshRenderer obj = val.AddComponent(); ((Renderer)obj).material = material; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; ((Renderer)obj).sortingOrder = sortingOrder; return obj; } private static Mesh GetOrCreateDiscMesh() { if (sharedDiscMesh == null) { sharedDiscMesh = CreateDiscMesh(); } return sharedDiscMesh; } private static Mesh CreateDiscMesh() { //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_0011: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) Mesh val = new Mesh { name = "DOLY_GasDisc" }; Vector3[] array = (Vector3[])(object)new Vector3[49]; int[] array2 = new int[144]; array[0] = Vector3.zero; for (int i = 0; i < 48; i++) { float num = (float)i / 48f * MathF.PI * 2f; array[i + 1] = new Vector3(Mathf.Cos(num), Mathf.Sin(num), 0f); int num2 = i * 3; array2[num2] = 0; array2[num2 + 1] = i + 1; array2[num2 + 2] = ((i == 47) ? 1 : (i + 2)); } val.vertices = array; val.triangles = array2; val.RecalculateBounds(); val.RecalculateNormals(); return val; } } internal sealed class HelldiverToxicCloudSanitizer : MonoBehaviour { private float duration; private float elapsed; private float scanCooldown; internal void Configure(float duration) { this.duration = duration; ScrubChildren(); } private void Update() { elapsed += TimeHandler.deltaTime; scanCooldown -= TimeHandler.deltaTime; if (scanCooldown <= 0f) { scanCooldown = 0.15f; ScrubChildren(); } if (elapsed >= duration) { Object.Destroy((Object)(object)this); } } private void ScrubChildren() { Collider2D[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Behaviour)componentsInChildren[i]).enabled = false; } Collider[] componentsInChildren2 = ((Component)this).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].enabled = false; } Rigidbody2D[] componentsInChildren3 = ((Component)this).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren3.Length; i++) { componentsInChildren3[i].simulated = false; } Rigidbody[] componentsInChildren4 = ((Component)this).GetComponentsInChildren(true); foreach (Rigidbody obj in componentsInChildren4) { obj.isKinematic = true; obj.detectCollisions = false; } RemoveAfterSeconds[] componentsInChildren5 = ((Component)this).GetComponentsInChildren(true); foreach (RemoveAfterSeconds obj2 in componentsInChildren5) { obj2.seconds = Mathf.Max(obj2.seconds, duration); obj2.ResetCounter(); } } } internal static class HelldiverVanillaPrefabResolver { private static readonly Dictionary PrefabCache = new Dictionary(StringComparer.Ordinal); private static readonly List LoadedGameObjects = new List(); private static bool loadedGameObjectPoolBuilt; internal static GameObject? GetLoadedPrefab(string prefabName) { if (PrefabCache.TryGetValue(prefabName, out GameObject value)) { return value; } EnsureLoadedGameObjectPool(); GameObject val = null; foreach (GameObject loadedGameObject in LoadedGameObjects) { if (Object.op_Implicit((Object)(object)loadedGameObject) && string.Equals(((Object)loadedGameObject).name, prefabName, StringComparison.Ordinal)) { val = loadedGameObject; break; } } PrefabCache[prefabName] = val; return val; } private static void EnsureLoadedGameObjectPool() { if (loadedGameObjectPoolBuilt) { return; } loadedGameObjectPoolBuilt = true; LoadedGameObjects.Clear(); try { LoadedGameObjects.AddRange(Resources.FindObjectsOfTypeAll()); } catch (Exception arg) { Debug.LogWarning($"[DOLY] Failed to enumerate loaded vanilla prefabs: {arg}"); } } } internal struct HelldiverVectorPart { internal string Name { get; } internal Color Color { get; } internal int SortingOrder { get; } internal Vector2[] Points { get; } internal HelldiverVectorPart(string name, Color color, int sortingOrder, Vector2[] points) { //IL_0008: 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) Name = name; Color = color; SortingOrder = sortingOrder; Points = points; } } internal static class HelldiverVectorArt { private const float SvgUnitScale = 0.0125f; private const int SentryGreenHex = 6788178; internal const float HellpodWidth = 1.4f; internal const float HellpodHeight = 2.2f; internal const float SentryWidth = 1.35f; internal const float SentryBodyHeight = 1.775f; internal static readonly Vector2 SentryBallPivot = new Vector2(0f, 1.23f); private static readonly HelldiverVectorPart[] Hellpod = new HelldiverVectorPart[9] { new HelldiverVectorPart("TopBand", ColorFromHex(6184542), 1460, Rect(0f, 0f, 112f, 8f, 112f, 176f)), new HelldiverVectorPart("UpperShoulder", ColorFromHex(3289650), 1459, Polygon(112f, 176f, (8f, 8f), (104f, 8f), (106f, 40f), (6f, 40f))), new HelldiverVectorPart("MidBody", ColorFromHex(3947580), 1458, Polygon(112f, 176f, (4f, 40f), (108f, 40f), (108f, 72f), (4f, 72f))), new HelldiverVectorPart("LowerBody", ColorFromHex(3289650), 1457, Polygon(112f, 176f, (6f, 72f), (106f, 72f), (94f, 132f), (18f, 132f))), new HelldiverVectorPart("Nose", ColorFromHex(3947580), 1456, Polygon(112f, 176f, (18f, 132f), (94f, 132f), (68f, 172f), (44f, 172f))), new HelldiverVectorPart("Tip", ColorFromHex(16770832), 1461, Polygon(112f, 176f, (44f, 172f), (68f, 172f), (60f, 176f), (52f, 176f))), new HelldiverVectorPart("Emblem", ColorFromHex(16770832), 1462, Polygon(112f, 176f, (44f, 92f), (68f, 92f), (56f, 116f))), new HelldiverVectorPart("EmblemCore", ColorFromHex(3289650), 1463, Circle(112f, 176f, 56f, 99.5f, 5.5f, 18)), new HelldiverVectorPart("EmblemCap", ColorFromHex(16770832), 1464, Rect(44f, 90f, 24f, 1f, 112f, 176f)) }; private static readonly HelldiverVectorPart[] SentryBase = new HelldiverVectorPart[2] { new HelldiverVectorPart("Base", ColorFromHex(6788178), 1470, Polygon(108f, 184f, (8f, 153f), (100f, 153f), (108f, 184f), (0f, 184f))), new HelldiverVectorPart("Neck", ColorFromHex(6788178), 1471, Rect(12f, 135f, 84f, 15f, 108f, 184f)) }; private static readonly HelldiverVectorPart[] SentryBall = new HelldiverVectorPart[1] { new HelldiverVectorPart("Head", ColorFromHex(6788178), 1473, SentryHead()) }; private static readonly Dictionary MaterialsByColor = new Dictionary(); internal static GameObject BuildHellpodVisual(Transform parent) { //IL_0005: 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown GameObject val = new GameObject("HellpodVisual"); val.transform.SetParent(parent, false); BuildParts(val.transform, Hellpod); return val; } internal static HelldiverSentryVisual BuildSentryVisual(Transform parent, HelldiverStratagemType type) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0158: 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) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject($"{type}Visual"); val.transform.SetParent(parent, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; BuildParts(val.transform, SentryBase); GameObject val2 = new GameObject("BallCenter"); val2.transform.SetParent(val.transform, false); val2.transform.localPosition = Vector2.op_Implicit(SentryBallPivot); val2.transform.localRotation = Quaternion.identity; GameObject val3 = new GameObject("TurretBall"); val3.transform.SetParent(val.transform, false); val3.transform.localPosition = Vector3.zero; val3.transform.localRotation = Quaternion.identity; BuildParts(val3.transform, SentryBall); GameObject val4 = new GameObject("GunPivot"); val4.transform.SetParent(val.transform, false); val4.transform.localPosition = Vector2.op_Implicit(SentryBallPivot); val4.transform.localRotation = Quaternion.identity; GameObject val5 = new GameObject("TurretGun"); val5.transform.SetParent(val4.transform, false); val5.transform.localPosition = Vector2.op_Implicit(-SentryBallPivot); val5.transform.localRotation = Quaternion.identity; BuildParts(val5.transform, GetSentryGun(type)); Vector2 val6 = default(Vector2); ((Vector2)(ref val6))..ctor(0f, GetSentryMuzzleWorldY(type)); return new HelldiverSentryVisual(val.transform, val2.transform, val4.transform, val6 - SentryBallPivot); } private static HelldiverVectorPart[] GetSentryGun(HelldiverStratagemType type) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_07ff: Unknown result type (might be due to invalid IL or missing references) return type switch { HelldiverStratagemType.RocketSentry => new HelldiverVectorPart[1] { new HelldiverVectorPart("RocketBarrel", ColorFromHex(6788178), 1474, Polygon(108f, 172f, (34f, 0f), (42f, 0f), (42f, 8f), (50f, 8f), (50f, 0f), (58f, 0f), (58f, 8f), (66f, 8f), (66f, 0f), (74f, 0f), (74f, 128f), (34f, 128f))) }, HelldiverStratagemType.AutocannonSentry => new HelldiverVectorPart[1] { new HelldiverVectorPart("AutocannonBarrel", ColorFromHex(6788178), 1474, Polygon(108f, 230f, (42f, 60f), (48f, 38f), (48f, 0f), (60f, 0f), (60f, 38f), (66f, 60f), (66f, 190f), (42f, 190f))) }, HelldiverStratagemType.GatlingSentry => new HelldiverVectorPart[1] { new HelldiverVectorPart("GatlingBarrel", ColorFromHex(6788178), 1474, Polygon(108f, 201f, (47f, 0f), (49f, 31f), (52f, 31f), (52f, 0f), (56f, 0f), (56f, 31f), (59f, 31f), (61f, 0f), (64f, 0f), (64f, 36f), (68f, 49f), (68f, 109f), (40f, 109f), (40f, 49f), (44f, 36f), (44f, 0f))) }, HelldiverStratagemType.LaserSentry => new HelldiverVectorPart[1] { new HelldiverVectorPart("LaserBarrel", ColorFromHex(6788178), 1474, Polygon(108f, 210f, (50f, 0f), (58f, 0f), (58f, 6f), (66f, 6f), (66f, 12f), (58f, 12f), (58f, 18f), (60f, 18f), (66f, 18f), (66f, 24f), (58f, 24f), (58f, 30f), (66f, 30f), (66f, 36f), (58f, 36f), (58f, 42f), (68f, 42f), (68f, 48f), (58f, 48f), (58f, 56f), (64f, 56f), (64f, 118f), (44f, 118f), (44f, 56f), (50f, 56f), (50f, 48f), (40f, 48f), (40f, 42f), (50f, 42f), (50f, 36f), (42f, 36f), (42f, 30f), (50f, 30f), (50f, 24f), (42f, 24f), (42f, 18f), (50f, 18f), (50f, 12f), (42f, 12f), (42f, 6f), (50f, 6f))) }, _ => new HelldiverVectorPart[1] { new HelldiverVectorPart("MachineGunBarrel", ColorFromHex(6788178), 1474, Polygon(108f, 193f, (50f, 0f), (50f, 9f), (58f, 9f), (58f, 0f), (64f, 0f), (64f, 101f), (44f, 101f), (44f, 9f), (44f, 0f))) }, }; } private static float GetSentryMuzzleWorldY(HelldiverStratagemType type) { return type switch { HelldiverStratagemType.RocketSentry => 2.15f, HelldiverStratagemType.AutocannonSentry => 2.875f, HelldiverStratagemType.GatlingSentry => 2.5125f, HelldiverStratagemType.LaserSentry => 2.625f, _ => 2.4125001f, }; } private static void BuildParts(Transform parent, IReadOnlyList parts) { for (int i = 0; i < parts.Count; i++) { BuildPart(parent, parts[i]); } } private static void BuildPart(Transform parent, HelldiverVectorPart part) { //IL_0007: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(part.Name); val.transform.SetParent(parent, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.AddComponent().sharedMesh = CreateMesh(part.Name, part.Points); MeshRenderer obj = val.AddComponent(); ((Renderer)obj).sharedMaterial = GetMaterial(part.Color); ((Renderer)obj).sortingOrder = part.SortingOrder; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; } private static Mesh CreateMesh(string name, IReadOnlyList points) { //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_0017: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) Mesh val = new Mesh { name = "DOLY_" + name }; Vector3[] array = (Vector3[])(object)new Vector3[points.Count]; for (int i = 0; i < points.Count; i++) { array[i] = Vector2.op_Implicit(points[i]); } int[] triangles = Triangulate(points); val.vertices = array; val.triangles = triangles; val.RecalculateBounds(); val.RecalculateNormals(); return val; } private static int[] Triangulate(IReadOnlyList points) { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) if (points.Count < 3) { return Array.Empty(); } List list = new List(points.Count); for (int i = 0; i < points.Count; i++) { list.Add(i); } List list2 = new List((points.Count - 2) * 3); bool clockwise = SignedArea(points) < 0f; int num = points.Count * points.Count; while (list.Count > 3 && num-- > 0) { bool flag = false; for (int j = 0; j < list.Count; j++) { int num2 = list[(j + list.Count - 1) % list.Count]; int num3 = list[j]; int num4 = list[(j + 1) % list.Count]; if (IsConvex(points[num2], points[num3], points[num4], clockwise) && !ContainsPointInTriangle(points, list, num2, num3, num4)) { AddTriangle(list2, num2, num3, num4, clockwise); list.RemoveAt(j); flag = true; break; } } if (!flag) { return FanTriangulate(points.Count); } } if (list.Count == 3) { AddTriangle(list2, list[0], list[1], list[2], clockwise); } return list2.ToArray(); } private static int[] FanTriangulate(int pointCount) { int[] array = new int[(pointCount - 2) * 3]; for (int i = 0; i < pointCount - 2; i++) { int num = i * 3; array[num] = 0; array[num + 1] = i + 1; array[num + 2] = i + 2; } return array; } private static void AddTriangle(List triangles, int a, int b, int c, bool clockwise) { if (clockwise) { triangles.Add(a); triangles.Add(b); triangles.Add(c); } else { triangles.Add(a); triangles.Add(c); triangles.Add(b); } } private static float SignedArea(IReadOnlyList points) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_003d: Unknown result type (might be due to invalid IL or missing references) float num = 0f; for (int i = 0; i < points.Count; i++) { int index = (i + 1) % points.Count; num += points[i].x * points[index].y - points[index].x * points[i].y; } return num * 0.5f; } private static bool IsConvex(Vector2 a, Vector2 b, Vector2 c, bool clockwise) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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_0007: 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_0009: Unknown result type (might be due to invalid IL or missing references) float num = Cross(b - a, c - b); if (!clockwise) { return num > 1E-05f; } return num < -1E-05f; } private static bool ContainsPointInTriangle(IReadOnlyList points, IReadOnlyList indices, int a, int b, int c) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_0031: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < indices.Count; i++) { int num = indices[i]; if (num != a && num != b && num != c && IsPointInTriangle(points[num], points[a], points[b], points[c])) { return true; } } return false; } private static bool IsPointInTriangle(Vector2 point, Vector2 a, Vector2 b, Vector2 c) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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_0007: 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_0009: 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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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_0027: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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) //IL_0030: Unknown result type (might be due to invalid IL or missing references) float num = Cross(point - a, b - a); float num2 = Cross(point - b, c - b); float num3 = Cross(point - c, a - c); bool flag = num < -1E-05f || num2 < -1E-05f || num3 < -1E-05f; bool flag2 = num > 1E-05f || num2 > 1E-05f || num3 > 1E-05f; return !(flag && flag2); } private static float Cross(Vector2 a, Vector2 b) { //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_000d: 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) return a.x * b.y - a.y * b.x; } private static Material GetMaterial(Color color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown int hashCode = ColorUtility.ToHtmlStringRGBA(color).GetHashCode(); if (MaterialsByColor.TryGetValue(hashCode, out Material value) && (Object)(object)value != (Object)null) { return value; } value = new Material(Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color")) { color = color, hideFlags = (HideFlags)61 }; MaterialsByColor[hashCode] = value; return value; } private static Vector2[] Rect(float x, float y, float width, float height, float sourceWidth, float sourceHeight) { return Polygon(sourceWidth, sourceHeight, (x, y), (x + width, y), (x + width, y + height), (x, y + height)); } private static Vector2[] Polygon(float sourceWidth, float sourceHeight, params (float X, float Y)[] points) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) Vector2[] array = (Vector2[])(object)new Vector2[points.Length]; for (int i = 0; i < points.Length; i++) { array[i] = ConvertPoint(points[i].X, points[i].Y, sourceWidth, sourceHeight); } return array; } private static Vector2[] Circle(float sourceWidth, float sourceHeight, float centerX, float centerY, float radius, int segments) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) Vector2[] array = (Vector2[])(object)new Vector2[segments]; for (int i = 0; i < segments; i++) { float num = (float)i / (float)segments * MathF.PI * 2f; array[i] = ConvertPoint(centerX + Mathf.Cos(num) * radius, centerY + Mathf.Sin(num) * radius, sourceWidth, sourceHeight); } return array; } private static Vector2[] SentryHead() { //IL_001c: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) List list = new List(22) { ConvertPoint(6f, 132f, 108f, 184f), ConvertPoint(6f, 114f, 108f, 184f) }; float num = 54f; float num2 = 92f; float num3 = 50f; for (int i = 0; i <= 18; i++) { float num4 = (float)i / 18f; float num5 = Mathf.Lerp(MathF.PI, 0f, num4); list.Add(ConvertPoint(num + Mathf.Cos(num5) * num3, num2 - Mathf.Sin(num5) * num3, 108f, 184f)); } list.Add(ConvertPoint(102f, 132f, 108f, 184f)); return list.ToArray(); } private static Vector2 ConvertPoint(float x, float y, float sourceWidth, float sourceHeight) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) return new Vector2((x - sourceWidth * 0.5f) * 0.0125f, (sourceHeight - y) * 0.0125f); } private static Color ColorFromHex(int hex) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) return new Color((float)((hex >> 16) & 0xFF) / 255f, (float)((hex >> 8) & 0xFF) / 255f, (float)(hex & 0xFF) / 255f, 1f); } } internal struct HelldiverSentryVisual { internal Transform Root { get; } internal Transform BallCenter { get; } internal Transform GunPivot { get; } internal Vector2 MuzzleOffsetFromPivot { get; } internal HelldiverSentryVisual(Transform root, Transform ballCenter, Transform gunPivot, Vector2 muzzleOffsetFromPivot) { //IL_0016: 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) Root = root; BallCenter = ballCenter; GunPivot = gunPivot; MuzzleOffsetFromPivot = muzzleOffsetFromPivot; } } internal static class HelldiverWorldCleanup { private static int lastCleanupFrame = -1; internal static void CleanupPointObjects() { if (lastCleanupFrame != Time.frameCount) { lastCleanupFrame = Time.frameCount; DestroyAll(); DestroyAll(); DestroyAll(); DestroyAll(); DestroyAll(); DestroyAll(); DestroyAll(); DestroyAll(); DestroyAll(); DestroyAll(); DestroyAll(); DestroyAll(); DestroyAll(); DestroyAll(); DestroyAll(); DestroyAll(); HelldiverHellpodDamageable.ClearPendingSyncedDamage(); HelldiverSentryDamageable.ClearPendingSyncedDamage(); } } private static void DestroyAll() where T : Component { T[] array = Object.FindObjectsOfType(); foreach (T val in array) { if (val != null) { DestroyObject(((Component)val).gameObject); } } } private static void DestroyObject(GameObject target) { if (target != null) { PhotonView component = target.GetComponent(); if (!PhotonNetwork.OfflineMode && PhotonNetwork.InRoom && component != null && component.IsMine) { PhotonNetwork.Destroy(target); } else { Object.Destroy((Object)(object)target); } } } } internal static class HolySmiteAudio { private const string ProcPrefix = "SFX_Passive_Radiance_Activate_"; private const string HitPrefix = "SFX_Impact_Environment_Basic_"; private const float VolumeBoostMultiplier = 1.25f; private static readonly Dictionary ClipCache = new Dictionary(); private static readonly HashSet MissingPrefixes = new HashSet(); private static readonly List LoadedClips = new List(); private static bool loadedClipPoolBuilt; private static bool resourceFallbackBuilt; internal static void PlayProc(Vector2 position) { PlayRandomClip("SFX_Passive_Radiance_Activate_", 0.9f); } internal static void PlayHit(Vector2 position) { PlayRandomClip("SFX_Impact_Environment_Basic_", 0.75f); } private static void PlayRandomClip(string prefix, float volume) { AudioClip[] clips = GetClips(prefix); if (clips.Length == 0) { if (MissingPrefixes.Add(prefix)) { Debug.LogWarning("[DOLY] Holy Smite audio could not resolve any AudioClips with prefix '" + prefix + "'."); } } else { PlayAsUiLike2DAudio(clips[Random.Range(0, clips.Length)], volume); } } private static AudioClip[] GetClips(string prefix) { if (ClipCache.TryGetValue(prefix, out AudioClip[] value)) { return value; } EnsureLoadedClipPool(); value = MatchClips(prefix); if (value.Length == 0) { EnsureResourceFallbackPool(); value = MatchClips(prefix); } ClipCache[prefix] = value; return value; } private static AudioClip[] MatchClips(string prefix) { string prefix2 = prefix; return LoadedClips.Where((AudioClip clip) => clip != null && ((Object)clip).name.StartsWith(prefix2, StringComparison.Ordinal)).OrderBy((AudioClip clip) => ((Object)clip).name, StringComparer.Ordinal).ToArray(); } private static void EnsureLoadedClipPool() { if (!loadedClipPoolBuilt) { loadedClipPoolBuilt = true; HashSet knownIds = new HashSet(); AddClips(Resources.FindObjectsOfTypeAll(), knownIds); } } private static void EnsureResourceFallbackPool() { if (!resourceFallbackBuilt) { resourceFallbackBuilt = true; HashSet knownIds = new HashSet(LoadedClips.Select((AudioClip clip) => ((Object)clip).GetInstanceID())); AddClips(Resources.LoadAll(string.Empty), knownIds); } } private static void AddClips(IEnumerable clips, HashSet knownIds) { foreach (AudioClip clip in clips) { if (clip != null) { int instanceID = ((Object)clip).GetInstanceID(); if (knownIds.Add(instanceID)) { LoadedClips.Add(clip); } } } } private static void PlayAsUiLike2DAudio(AudioClip clip, float volume) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown if (clip != null) { GameObject val = new GameObject("DOLY_HolySmiteAudio"); AudioSource obj = val.AddComponent(); obj.spatialBlend = 0f; obj.playOnAwake = false; obj.loop = false; obj.volume = 1f; obj.clip = clip; obj.priority = 64; obj.PlayOneShot(clip, volume * 1.25f); Object.Destroy((Object)val, clip.length + 0.2f); } } } internal sealed class HolySmiteBurnEffect : MonoBehaviour { private const float TickIntervalSeconds = 0.25f; private static readonly Color BurnColor = new Color(1f, 0.42f, 0.18f, 1f); private CharacterData? data; private HealthHandler? healthHandler; private Coroutine? burnRoutine; private float burnMaxHealthFractionPerSecond; private float expiresAt; private float lifeStealFraction; private Vector2 burnDirection = Vector2.up; private Player? damagingPlayer; private GameObject? damagingWeapon; private void Awake() { data = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); healthHandler = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); } internal void Apply(Player? sourcePlayer, GameObject? sourceWeapon, float maxHealthFractionPerSecond, float durationSeconds, float sourceLifeStealFraction, Vector2 direction) { //IL_0051: 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_0056: Unknown result type (might be due to invalid IL or missing references) if (!(maxHealthFractionPerSecond <= 0f) && !(durationSeconds <= 0f)) { damagingPlayer = sourcePlayer; damagingWeapon = sourceWeapon; burnMaxHealthFractionPerSecond = maxHealthFractionPerSecond; lifeStealFraction = Mathf.Max(0f, sourceLifeStealFraction); burnDirection = ((((Vector2)(ref direction)).sqrMagnitude > 0.0001f) ? ((Vector2)(ref direction)).normalized : Vector2.up); expiresAt = Time.time + durationSeconds; if (burnRoutine == null) { burnRoutine = ((MonoBehaviour)this).StartCoroutine(RunBurn()); } } } private IEnumerator RunBurn() { while (true) { if (data == null || healthHandler == null || !data.isPlaying || data.dead) { burnRoutine = null; yield break; } if (Time.time >= expiresAt) { break; } float num = data.maxHealth * burnMaxHealthFractionPerSecond * 0.25f; HolySmiteResistanceEffect holySmiteResistanceEffect = ((Component)this).gameObject.GetComponent() ?? ((Component)this).GetComponentInParent(); if (holySmiteResistanceEffect != null) { num *= holySmiteResistanceEffect.DamageTakenMultiplier; } if (num > 0f) { float health = data.health; healthHandler.DoDamage(burnDirection * num, Vector2.op_Implicit(((Component)this).transform.position), BurnColor, damagingWeapon, damagingPlayer, true, true, true); if (lifeStealFraction > 0f && damagingPlayer?.data?.healthHandler != null) { float num2 = Mathf.Min(num, Mathf.Max(0f, health)); if (num2 > 0f) { damagingPlayer.data.healthHandler.Heal(num2 * lifeStealFraction); } } } yield return (object)new WaitForSeconds(0.25f / Mathf.Max(TimeHandler.timeScale, 0.01f)); } burnRoutine = null; Object.Destroy((Object)(object)this); } } internal sealed class HolySmiteEffect : ProjectileEffectBase { private sealed class DiscoSmiteSequence { private readonly Random random; internal DiscoSmiteSequence(int seed) { random = new Random(seed); } internal Vector2 NextDirection() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) float num = NextFloat(0f, MathF.PI * 2f); Vector2 val = new Vector2(Mathf.Cos(num), Mathf.Sin(num)); return ((Vector2)(ref val)).normalized; } internal Color NextColor() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) Color result = Color.HSVToRGB(NextFloat(0f, 1f), NextFloat(0.75f, 1f), NextFloat(0.85f, 1f)); result.a = 0.4f; return result; } private float NextFloat(float min, float max) { return min + (float)random.NextDouble() * (max - min); } } internal const float BaseDamageRatio = 0.8f; internal const float BaseFlatDamage = 20f; internal const float BaseCooldownSeconds = 5f; internal const float BaseDelaySeconds = 1.2f; internal const float BaseSize = 3.5f; internal const float RejuvenatingBaseHealRatio = 0.5f; private const float BeamDurationSeconds = 0.15f; private const float BeamLengthMultiplier = 3f; private const float FallbackBeamLength = 200f; private const float RevelationDamageMultiplier = 0.7f; private const float RevelationSizeMultiplier = 0.7f; private const float RevelationDelayMultiplier = 0.7f; private HolySmiteStyle currentStyle; private double cooldownReadyTime; private int discoCardCount; private HolySmiteReadyGlow? readyGlow; internal int EntryCount { get; set; } internal float DamageMultiplier { get; set; } = 1f; internal float SizeMultiplier { get; set; } = 1f; internal float CooldownMultiplier { get; set; } = 1f; internal float DelayMultiplier { get; set; } = 1f; internal float AdditionalDelaySeconds { get; set; } internal float QuakingBounceChance { get; set; } internal float StunDuration { get; set; } internal float BurnMaxHealthFractionPerSecond { get; set; } internal float BurnDurationSeconds { get; set; } internal float LifeStealFraction { get; set; } internal float CooldownReductionPerHit { get; set; } internal int AdditionalSmites { get; set; } internal float DamageTakenMultiplierWhenNotReady { get; set; } = 1f; internal float MarkDamageMultiplier { get; set; } = 1f; internal float AdditionalCooldownSeconds { get; set; } internal int RejuvenatingStackCount { get; set; } internal float ShrinkSizeMultiplier { get; set; } = 1f; internal float CooldownRemaining => Mathf.Max(0f, (float)(cooldownReadyTime - PhotonNetwork.Time)); internal bool IsSmiteReady { get { if (EntryCount > 0) { return CooldownRemaining <= 0.0001f; } return false; } } internal float ResolvedDamageRatio => 0.8f * DamageMultiplier; internal float ResolvedFlatDamage => 20f; internal float ResolvedSize => 3.5f * SizeMultiplier; internal float ResolvedCooldown => ResolveCooldownFromCardOrder(base.OwnerData?.currentCards); internal float ResolvedDelay => ResolveDelayFromCardOrder(base.OwnerData?.currentCards); internal int ResolvedAdditionalSmites => Mathf.Max(0, AdditionalSmites); internal float ResolvedFriendlyHealRatio { get { if (RejuvenatingStackCount > 0) { return 0.5f * (float)RejuvenatingStackCount; } return 0f; } } internal float CooldownProgress { get { float resolvedCooldown = ResolvedCooldown; if (resolvedCooldown <= 0.0001f) { return 1f; } return Mathf.Clamp01(1f - CooldownRemaining / resolvedCooldown); } } internal bool IsEmpty { get { if (EntryCount <= 0 && Mathf.Approximately(DamageMultiplier, 1f) && Mathf.Approximately(SizeMultiplier, 1f) && Mathf.Approximately(CooldownMultiplier, 1f) && Mathf.Approximately(DelayMultiplier, 1f) && AdditionalDelaySeconds <= 0f && QuakingBounceChance <= 0f && StunDuration <= 0f && BurnMaxHealthFractionPerSecond <= 0f && BurnDurationSeconds <= 0f && LifeStealFraction <= 0f && CooldownReductionPerHit <= 0f && AdditionalSmites <= 0 && AdditionalCooldownSeconds <= 0f && RejuvenatingStackCount <= 0 && Mathf.Approximately(ShrinkSizeMultiplier, 1f) && Mathf.Approximately(DamageTakenMultiplierWhenNotReady, 1f)) { return Mathf.Approximately(MarkDamageMultiplier, 1f); } return false; } } protected override void Start() { base.Start(); RefreshStyle(base.OwnerData?.currentCards); UpdateReadyGlow(); } protected override void Update() { base.Update(); RefreshStyle(base.OwnerData?.currentCards); UpdateReadyGlow(); } protected override void OnDestroy() { if (readyGlow != null) { Object.Destroy((Object)(object)readyGlow); } base.OnDestroy(); } internal void ResetTransientState() { ((MonoBehaviour)this).StopAllCoroutines(); cooldownReadyTime = 0.0; UpdateReadyGlow(); } internal static void ResetAllTransientState() { HolySmiteEffect[] array = Object.FindObjectsOfType(); for (int i = 0; i < array.Length; i++) { array[i]?.ResetTransientState(); } HolySmiteProjectileTracker.ResetAll(); HolySmiteVisual.ResetAll(); } protected override void AttachToProjectile(GameObject projectile, ProjectileHit projectileHit) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) if (EntryCount <= 0 || base.OwnerPlayer == null || base.OwnerData == null) { return; } RefreshStyle(base.OwnerData.currentCards); PhotonView component = projectile.GetComponent(); if (component != null && component.IsMine) { if (CooldownReductionPerHit > 0f) { projectileHit.AddHitActionWithData((Action)TryReduceCooldownFromBulletHit); } if (IsSmiteReady) { Color val = ((currentStyle == HolySmiteStyle.Disco) ? HolySmiteProjectileTracker.RollDiscoColor() : HolySmiteProjectileTracker.GetStyleColor(currentStyle)); int num = ((currentStyle == HolySmiteStyle.Disco) ? Mathf.Max(0, discoCardCount - 1) : 0); float resolvedCooldown = GetResolvedCooldown(); cooldownReadyTime = PhotonNetwork.Time + (double)resolvedCooldown; projectile.GetOrAddComponent().Configure(projectileHit.damage, projectileHit.percentageDamage, GetResolvedDamageRatio(), 20f, GetResolvedSize(), GetResolvedDelay(), QuakingBounceChance, StunDuration, BurnMaxHealthFractionPerSecond, BurnDurationSeconds, LifeStealFraction, ResolvedFriendlyHealRatio, ResolvedAdditionalSmites, num, currentStyle, val, base.OwnerPlayer.playerID, base.OwnerPlayer.playerID); base.OwnerData.view.RPC("RPCA_SyncHolySmiteCooldown", (RpcTarget)1, new object[1] { cooldownReadyTime }); base.OwnerData.view.RPC("RPCA_ArmHolySmiteProjectile", (RpcTarget)1, new object[22] { component.ViewID, projectileHit.damage, projectileHit.percentageDamage, GetResolvedDamageRatio(), 20f, GetResolvedSize(), GetResolvedDelay(), QuakingBounceChance, StunDuration, BurnMaxHealthFractionPerSecond, BurnDurationSeconds, LifeStealFraction, ResolvedFriendlyHealRatio, ResolvedAdditionalSmites, num, (int)currentStyle, val.r, val.g, val.b, val.a, base.OwnerPlayer.playerID, base.OwnerPlayer.playerID }); } } } internal void RefreshStyle(IList? currentCards) { currentStyle = ResolveStyle(currentCards, out discoCardCount); } [PunRPC] private void RPCA_SyncHolySmiteCooldown(double syncedCooldownReadyTime) { cooldownReadyTime = syncedCooldownReadyTime; } internal void BroadcastSmite(int currentOwnerPlayerId, int originalOwnerPlayerId, Vector2 point, float baseDamage, float basePercentageDamage, float damageRatio, float flatDamage, float size, float delay, float stunDuration, float burnMaxHealthFractionPerSecond, float burnDurationSeconds, float lifeStealFraction, float friendlyHealRatio, int additionalSmites, int extraDiscoBeams, HolySmiteStyle style, Color storedBulletColor, bool useStoredBulletColor) { //IL_000c: 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_0011: 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) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) Vector2 val = ((style == HolySmiteStyle.Disco) ? HolySmiteProjectileTracker.RollDiscoDirection() : Vector2.down); Color val2 = ((style != HolySmiteStyle.Disco) ? storedBulletColor : (useStoredBulletColor ? storedBulletColor : HolySmiteProjectileTracker.RollDiscoColor())); int num = ((style == HolySmiteStyle.Disco) ? Random.Range(0, int.MaxValue) : 0); double num2 = PhotonNetwork.Time + (double)delay; CharacterData? ownerData = base.OwnerData; if (ownerData != null) { ownerData.view.RPC("RPCA_TriggerHolySmite", (RpcTarget)0, new object[26] { currentOwnerPlayerId, originalOwnerPlayerId, point.x, point.y, baseDamage, basePercentageDamage, damageRatio, flatDamage, size, delay, stunDuration, burnMaxHealthFractionPerSecond, burnDurationSeconds, lifeStealFraction, friendlyHealRatio, additionalSmites, extraDiscoBeams, (int)style, val.x, val.y, val2.r, val2.g, val2.b, val2.a, num, num2 }); } } [PunRPC] private void RPCA_ArmHolySmiteProjectile(int projectileViewId, float baseDamage, float basePercentageDamage, float damageRatio, float flatDamage, float size, float delay, float quakingBounceChance, float stunDuration, float burnMaxHealthFractionPerSecond, float burnDurationSeconds, float lifeStealFraction, float friendlyHealRatio, int additionalSmites, int extraDiscoBeams, int styleIndex, float colorR, float colorG, float colorB, float colorA, int originalOwnerPlayerId, int currentOwnerPlayerId) { ((MonoBehaviour)this).StartCoroutine(ArmHolySmiteProjectileWhenReady(projectileViewId, baseDamage, basePercentageDamage, damageRatio, flatDamage, size, delay, quakingBounceChance, stunDuration, burnMaxHealthFractionPerSecond, burnDurationSeconds, lifeStealFraction, friendlyHealRatio, additionalSmites, extraDiscoBeams, styleIndex, colorR, colorG, colorB, colorA, originalOwnerPlayerId, currentOwnerPlayerId)); } [PunRPC] private void RPCA_TriggerHolySmite(int currentOwnerPlayerId, int originalOwnerPlayerId, float pointX, float pointY, float baseDamage, float basePercentageDamage, float damageRatio, float flatDamage, float size, float delay, float stunDuration, float burnMaxHealthFractionPerSecond, float burnDurationSeconds, float lifeStealFraction, float friendlyHealRatio, int additionalSmites, int extraDiscoBeams, int styleIndex, float directionX, float directionY, float colorR, float colorG, float colorB, float colorA, int discoSequenceSeed, double fireTime) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) ((MonoBehaviour)this).StartCoroutine(DoHolySmite(currentOwnerPlayerId, originalOwnerPlayerId, new Vector2(pointX, pointY), baseDamage, basePercentageDamage, damageRatio, flatDamage, size, delay, stunDuration, burnMaxHealthFractionPerSecond, burnDurationSeconds, lifeStealFraction, friendlyHealRatio, additionalSmites, extraDiscoBeams, (HolySmiteStyle)styleIndex, new Vector2(directionX, directionY), new Color(colorR, colorG, colorB, colorA), discoSequenceSeed, fireTime)); } private IEnumerator ArmHolySmiteProjectileWhenReady(int projectileViewId, float baseDamage, float basePercentageDamage, float damageRatio, float flatDamage, float size, float delay, float quakingBounceChance, float stunDuration, float burnMaxHealthFractionPerSecond, float burnDurationSeconds, float lifeStealFraction, float friendlyHealRatio, int additionalSmites, int extraDiscoBeams, int styleIndex, float colorR, float colorG, float colorB, float colorA, int originalOwnerPlayerId, int currentOwnerPlayerId) { float timeout = Time.unscaledTime + 2f; while (Time.unscaledTime < timeout) { PhotonView val = PhotonView.Find(projectileViewId); if (((val != null) ? ((Component)val).gameObject : null) != null) { ((Component)val).gameObject.GetOrAddComponent().Configure(baseDamage, basePercentageDamage, damageRatio, flatDamage, size, delay, quakingBounceChance, stunDuration, burnMaxHealthFractionPerSecond, burnDurationSeconds, lifeStealFraction, friendlyHealRatio, additionalSmites, extraDiscoBeams, (HolySmiteStyle)styleIndex, new Color(colorR, colorG, colorB, colorA), originalOwnerPlayerId, currentOwnerPlayerId); yield break; } yield return null; } Debug.LogWarning($"[DOLY] Holy Smite could not resolve projectile view {projectileViewId} for arming."); } private IEnumerator DoHolySmite(int currentOwnerPlayerId, int originalOwnerPlayerId, Vector2 point, float baseDamage, float basePercentageDamage, float damageRatio, float flatDamage, float size, float delay, float stunDuration, float burnMaxHealthFractionPerSecond, float burnDurationSeconds, float lifeStealFraction, float friendlyHealRatio, int additionalSmites, int extraDiscoBeams, HolySmiteStyle style, Vector2 direction, Color color, int discoSequenceSeed, double fireTime) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_009d: Unknown result type (might be due to invalid IL or missing references) if (((Vector2)(ref direction)).sqrMagnitude <= 0.0001f) { direction = Vector2.down; } if (!AreSmiteOwnersAlive(currentOwnerPlayerId, originalOwnerPlayerId)) { yield break; } ((Vector2)(ref direction)).Normalize(); float beamLength = GetBeamLength(); double currentFireTime = fireTime; Vector2 val = direction; Color color2 = color; float currentDamageRatio = damageRatio; float currentFlatDamage = flatDamage; float currentSize = size; bool isFriendlyToViewer = IsFriendlySmiteToLocalViewer(currentOwnerPlayerId); DiscoSmiteSequence discoSequence = ((style == HolySmiteStyle.Disco) ? new DiscoSmiteSequence(discoSequenceSeed) : null); for (int smiteIndex = 0; smiteIndex <= additionalSmites; smiteIndex++) { if (!AreSmiteOwnersAlive(currentOwnerPlayerId, originalOwnerPlayerId)) { break; } int beamCount = ((style != HolySmiteStyle.Disco) ? 1 : (1 + Mathf.Max(0, extraDiscoBeams))); Vector2[] beamDirections = (Vector2[])(object)new Vector2[beamCount]; beamDirections[0] = val; HolySmiteVisual.Spawn(point, val, beamLength, currentSize, color2, currentFireTime, 0.15f, isFriendlyToViewer, currentOwnerPlayerId, originalOwnerPlayerId); for (int i = 1; i < beamCount; i++) { HolySmiteVisual.Spawn(point, beamDirections[i] = discoSequence?.NextDirection() ?? HolySmiteProjectileTracker.RollDiscoDirection(), beamLength, currentSize, discoSequence?.NextColor() ?? HolySmiteProjectileTracker.RollDiscoColor(), currentFireTime, 0.15f, isFriendlyToViewer, currentOwnerPlayerId, originalOwnerPlayerId); } while (PhotonNetwork.Time < currentFireTime) { if (!AreSmiteOwnersAlive(currentOwnerPlayerId, originalOwnerPlayerId)) { yield break; } yield return null; } if (!AreSmiteOwnersAlive(currentOwnerPlayerId, originalOwnerPlayerId)) { break; } HolySmiteAudio.PlayProc(point); for (int j = 0; j < beamCount; j++) { ApplyHolySmiteDamage(currentOwnerPlayerId, originalOwnerPlayerId, point, baseDamage, basePercentageDamage, currentDamageRatio, currentFlatDamage, currentSize, stunDuration, burnMaxHealthFractionPerSecond, burnDurationSeconds, lifeStealFraction, friendlyHealRatio, beamDirections[j], beamLength); } if (smiteIndex >= additionalSmites) { break; } double nextWarningStartTime = currentFireTime + 0.15000000596046448; while (PhotonNetwork.Time < nextWarningStartTime) { if (!AreSmiteOwnersAlive(currentOwnerPlayerId, originalOwnerPlayerId)) { yield break; } yield return null; } currentFireTime = nextWarningStartTime + (double)(delay * 0.7f); currentDamageRatio = damageRatio * 0.7f; currentFlatDamage = flatDamage * 0.7f; currentSize = size * 0.7f; val = ((style == HolySmiteStyle.Disco) ? (discoSequence?.NextDirection() ?? HolySmiteProjectileTracker.RollDiscoDirection()) : Vector2.down); color2 = ((style == HolySmiteStyle.Disco) ? (discoSequence?.NextColor() ?? HolySmiteProjectileTracker.RollDiscoColor()) : HolySmiteProjectileTracker.GetStyleColor(style)); } } private void ApplyHolySmiteDamage(int currentOwnerPlayerId, int originalOwnerPlayerId, Vector2 point, float baseDamage, float basePercentageDamage, float damageRatio, float flatDamage, float size, float stunDuration, float burnMaxHealthFractionPerSecond, float burnDurationSeconds, float lifeStealFraction, float friendlyHealRatio, Vector2 direction, float beamLength) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) if (!AreSmiteOwnersAlive(currentOwnerPlayerId, originalOwnerPlayerId)) { return; } Player val = ResolvePlayerById(currentOwnerPlayerId) ?? ResolvePlayerById(originalOwnerPlayerId); if (val == null) { return; } List list = PlayerManager.instance?.players; if (list == null) { return; } bool flag = false; foreach (Player item in list) { if (item == null || item.data == null || item.data.dead || !PlayerIntersectsBeam(item, point, direction, beamLength, size)) { continue; } if (item.playerID == currentOwnerPlayerId || item.teamID == val.teamID) { float resolvedFriendlyHealAmount = GetResolvedFriendlyHealAmount(item, baseDamage, basePercentageDamage, damageRatio, flatDamage, friendlyHealRatio); if (resolvedFriendlyHealAmount > 0f && item.data.healthHandler != null) { item.data.healthHandler.Heal(resolvedFriendlyHealAmount); } ApplyShrink(item); } else { if (item.data.block != null && item.data.block.IsBlocking()) { continue; } float num = GetResolvedSmiteDamageAmount(item, baseDamage, basePercentageDamage, damageRatio, flatDamage); HolySmiteResistanceEffect component = ((Component)item).gameObject.GetComponent(); if (component != null) { num *= component.DamageTakenMultiplier; } if (num <= 0f || item.data.healthHandler == null) { continue; } float health = item.data.health; HealthHandler healthHandler = item.data.healthHandler; Vector2 val2 = direction * num; WeaponHandler weaponHandler = val.data.weaponHandler; object obj; if (weaponHandler == null) { obj = null; } else { Gun gun = weaponHandler.gun; obj = ((gun != null) ? ((Component)gun).gameObject : null); } ((Damagable)healthHandler).TakeDamage(val2, point, (GameObject)obj, val, true, false); if (!flag) { HolySmiteAudio.PlayHit(Vector2.op_Implicit(((Component)item).transform.position)); flag = true; } ApplyShrink(item); if (lifeStealFraction > 0f && val.data.healthHandler != null) { float num2 = Mathf.Min(num, Mathf.Max(0f, health)); if (num2 > 0f) { val.data.healthHandler.Heal(num2 * lifeStealFraction); } } if (burnMaxHealthFractionPerSecond > 0f && burnDurationSeconds > 0f) { HolySmiteBurnEffect orAddComponent = ((Component)item).gameObject.GetOrAddComponent(); WeaponHandler weaponHandler2 = val.data.weaponHandler; object sourceWeapon; if (weaponHandler2 == null) { sourceWeapon = null; } else { Gun gun2 = weaponHandler2.gun; sourceWeapon = ((gun2 != null) ? ((Component)gun2).gameObject : null); } orAddComponent.Apply(val, (GameObject?)sourceWeapon, burnMaxHealthFractionPerSecond, burnDurationSeconds, lifeStealFraction, direction); } if (stunDuration > 0f) { item.data.stunHandler.AddStun(stunDuration); } if (MarkDamageMultiplier > 1f) { ((Component)item).gameObject.GetOrAddComponent().ApplyMark(val.playerID, MarkDamageMultiplier); } } } } private float GetResolvedDamageRatio() { return ResolvedDamageRatio; } private float GetResolvedSize() { return ResolvedSize; } private float GetResolvedCooldown() { return ResolvedCooldown; } private float GetResolvedDelay() { return ResolvedDelay; } private float ResolveCooldownFromCardOrder(IList? currentCards) { if (currentCards == null || currentCards.Count <= 0) { return Mathf.Max(0f, (5f + AdditionalCooldownSeconds) * CooldownMultiplier); } float cooldown = 5f; foreach (CardInfo currentCard in currentCards) { ApplyCooldownTimingCard(currentCard?.cardName, ref cooldown); } return Mathf.Max(0f, cooldown); } private float ResolveDelayFromCardOrder(IList? currentCards) { if (currentCards == null || currentCards.Count <= 0) { return Mathf.Max(0f, (1.2f + AdditionalDelaySeconds) * DelayMultiplier); } float delay = 1.2f; foreach (CardInfo currentCard in currentCards) { ApplyDelayTimingCard(currentCard?.cardName, ref delay); } return Mathf.Max(0f, delay); } private static void ApplyCooldownTimingCard(string? cardName, ref float cooldown) { if (cardName == null) { return; } switch (cardName.Length) { case 11: switch (cardName[0]) { case 'D': if (cardName == "Disco Smite") { cooldown *= 0.8f; } break; case 'A': if (cardName == "Aegis Smite") { cooldown += 4f; } break; } break; case 18: switch (cardName[0]) { case 'R': if (cardName == "Rejuvenating Smite") { cooldown *= 0.7f; } break; case 'S': if (cardName == "Speak of the Devil") { cooldown += 6f; } break; } break; case 13: switch (cardName[0]) { case 'Q': if (cardName == "Quaking Smite") { cooldown += 1f; } break; case 'F': if (cardName == "Flaming Smite") { cooldown += 1f; } break; case 'O': if (cardName == "Orbital Laser") { cooldown += 20f; } break; } break; case 14: if (cardName == "Stunning Smite") { cooldown += 2f; } break; case 16: if (cardName == "Revelation Smite") { cooldown += 2f; } break; case 12: case 15: case 17: break; } } private static void ApplyDelayTimingCard(string? cardName, ref float delay) { if (cardName == null) { return; } switch (cardName.Length) { case 16: switch (cardName[0]) { case 'T': if (cardName == "Thundering Smite") { delay *= 0.67f; } break; case 'R': if (cardName == "Revelation Smite") { delay += 0.25f; } break; } break; case 13: switch (cardName[0]) { case 'Q': if (cardName == "Quaking Smite") { delay += 0.75f; } break; case 'F': if (cardName == "Flaming Smite") { delay += 0.5f; } break; case 'O': if (cardName == "Orbital Laser") { delay += 6f; } break; } break; case 11: switch (cardName[0]) { case 'G': if (cardName == "Godly Smite") { delay += 0.25f; } break; case 'D': if (cardName == "Disco Smite") { delay += 0.25f; } break; case 'A': if (cardName == "Aegis Smite") { delay *= 0.8f; } break; } break; case 14: switch (cardName[0]) { case 'S': if (cardName == "Stunning Smite") { delay *= 0.9f; } break; case 'V': if (cardName == "Vampiric Smite") { delay += 0.25f; } break; } break; case 10: switch (cardName[0]) { case 'C': if (cardName == "Confession") { delay *= 0.2f; } break; case 'S': if (cardName == "Shrink Ray") { delay *= 0.7f; } break; } break; case 18: switch (cardName[0]) { case 'S': if (cardName == "Speak of the Devil") { delay += 0.66f; } break; case 'R': if (cardName == "Rejuvenating Smite") { delay += 0.25f; } break; } break; case 12: if (cardName == "Mighty Smite") { delay += 0.4f; } break; case 15: if (cardName == "Divine Judgment") { delay *= 0.8f; } break; case 17: break; } } private static float GetResolvedSmiteDamageAmount(Player player, float baseDamage, float basePercentageDamage, float damageRatio, float flatDamage) { return (baseDamage + basePercentageDamage * player.data.maxHealth) * damageRatio + flatDamage; } private static float GetResolvedFriendlyHealAmount(Player player, float baseDamage, float basePercentageDamage, float damageRatio, float flatDamage, float selfHealRatio) { if (selfHealRatio <= 0f) { return 0f; } float resolvedSmiteDamageAmount = GetResolvedSmiteDamageAmount(player, baseDamage, basePercentageDamage, damageRatio, flatDamage); if (resolvedSmiteDamageAmount <= 0f) { return 0f; } return resolvedSmiteDamageAmount * selfHealRatio; } private void TryReduceCooldownFromBulletHit(HitInfo hit) { if (CooldownReductionPerHit <= 0f || base.OwnerData == null || ProjectileEffectBase.GetHitHealth(hit) == null) { return; } double time = PhotonNetwork.Time; if (!(cooldownReadyTime <= time)) { double num = Math.Max(time, cooldownReadyTime - (double)CooldownReductionPerHit); if (!(num >= cooldownReadyTime)) { cooldownReadyTime = num; base.OwnerData.view.RPC("RPCA_SyncHolySmiteCooldown", (RpcTarget)1, new object[1] { cooldownReadyTime }); } } } private void UpdateReadyGlow() { if (base.OwnerData == null || EntryCount <= 0) { if (readyGlow != null) { readyGlow.SetState(isReady: false, 0f); } return; } if (readyGlow == null) { readyGlow = ((Component)this).gameObject.GetOrAddComponent(); } readyGlow.Bind(base.OwnerData); readyGlow.SetState(IsSmiteReady, CooldownProgress); } private static float GetBeamLength() { Camera val = MainCam.instance?.cam; if (val == null || !val.orthographic) { return 200f; } float num = val.orthographicSize * 2f; float num2 = num * val.aspect; return Mathf.Sqrt(num * num + num2 * num2) * 3f; } internal static Player? ResolvePlayerById(int playerId) { List list = PlayerManager.instance?.players; if (list == null) { return null; } foreach (Player item in list) { if (item != null && item.playerID == playerId) { return item; } } return null; } internal static bool AreSmiteOwnersAlive(int currentOwnerPlayerId, int originalOwnerPlayerId) { Player val = ResolvePlayerById(originalOwnerPlayerId); if (val?.data == null || val.data.dead) { return false; } if (currentOwnerPlayerId == originalOwnerPlayerId) { return true; } Player val2 = ResolvePlayerById(currentOwnerPlayerId); if (val2?.data != null) { return !val2.data.dead; } return false; } private static Player? ResolveLocalPlayer() { List list = PlayerManager.instance?.players; if (list == null) { return null; } foreach (Player item in list) { if (item?.data?.view != null && item.data.view.IsMine) { return item; } } return null; } private static bool IsFriendlySmiteToLocalViewer(int ownerPlayerId) { Player val = ResolveLocalPlayer(); Player val2 = ResolvePlayerById(ownerPlayerId); if (val == null || val2 == null) { return false; } if (val.playerID != val2.playerID) { return val.teamID == val2.teamID; } return true; } private void ApplyShrink(Player player) { if (!(ShrinkSizeMultiplier >= 0.9999f) && player.data?.stats != null) { ((Component)player).gameObject.GetOrAddComponent().Apply(ShrinkSizeMultiplier); } } private static bool PlayerIntersectsBeam(Player player, Vector2 beamCenter, Vector2 beamDirection, float beamLength, float beamWidth) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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_009d: 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) //IL_00a9: 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) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) Collider2D mainCol = player.data.mainCol; Bounds val = (Bounds)((mainCol != null) ? mainCol.bounds : new Bounds(((Component)player).transform.position, Vector3.one)); Vector2 val2 = ((Vector2)(ref beamDirection)).normalized; if (((Vector2)(ref val2)).sqrMagnitude <= 0.0001f) { val2 = Vector2.down; } Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0f - val2.y, val2.x); Vector2 beamExtents = default(Vector2); ((Vector2)(ref beamExtents))..ctor(beamLength * 0.5f, beamWidth * 0.5f); Vector2 val4 = Vector2.op_Implicit(((Bounds)(ref val)).center); Vector2 targetExtents = Vector2.op_Implicit(((Bounds)(ref val)).extents); Vector2 delta = val4 - beamCenter; if (OverlapsOnAxis(delta, targetExtents, val2, val3, beamExtents, Vector2.right) && OverlapsOnAxis(delta, targetExtents, val2, val3, beamExtents, Vector2.up) && OverlapsOnAxis(delta, targetExtents, val2, val3, beamExtents, val2)) { return OverlapsOnAxis(delta, targetExtents, val2, val3, beamExtents, val3); } return false; } private static bool OverlapsOnAxis(Vector2 delta, Vector2 targetExtents, Vector2 beamAxis, Vector2 beamNormal, Vector2 beamExtents, Vector2 axis) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) Vector2 normalized = ((Vector2)(ref axis)).normalized; float num = Mathf.Abs(Vector2.Dot(delta, normalized)); float num2 = targetExtents.x * Mathf.Abs(Vector2.Dot(Vector2.right, normalized)) + targetExtents.y * Mathf.Abs(Vector2.Dot(Vector2.up, normalized)); float num3 = beamExtents.x * Mathf.Abs(Vector2.Dot(beamAxis, normalized)) + beamExtents.y * Mathf.Abs(Vector2.Dot(beamNormal, normalized)); return num <= num2 + num3; } private static HolySmiteStyle ResolveStyle(IList? currentCards, out int discoCards) { discoCards = 0; if (currentCards == null) { return HolySmiteStyle.White; } for (int i = 0; i < currentCards.Count; i++) { if (currentCards[i]?.cardName == "Disco Smite") { discoCards++; } } if (discoCards > 0) { return HolySmiteStyle.Disco; } for (int num = currentCards.Count - 1; num >= 0; num--) { switch (currentCards[num]?.cardName) { case "Divine Judgment": return HolySmiteStyle.Gold; case "Aegis Smite": return HolySmiteStyle.Teal; case "Orbital Laser": return HolySmiteStyle.LightBlueWhite; case "Shrink Ray": return HolySmiteStyle.Pink; case "Devil's Mark": return HolySmiteStyle.Red; case "Speak of the Devil": return HolySmiteStyle.Crimson; case "Confession": return HolySmiteStyle.PaleCyan; case "Zealot's Bargain": return HolySmiteStyle.Emerald; case "Rejuvenating Smite": return HolySmiteStyle.Emerald; case "Vampiric Smite": return HolySmiteStyle.DarkRed; case "Revelation Smite": return HolySmiteStyle.WhiteGray; case "Flaming Smite": return HolySmiteStyle.LightRed; case "Stunning Smite": return HolySmiteStyle.Blue; case "Godly Smite": return HolySmiteStyle.Yellow; case "Greater Smite": return HolySmiteStyle.Silver; case "Quaking Smite": return HolySmiteStyle.WhiteBrown; case "Mighty Smite": return HolySmiteStyle.Orange; case "Thundering Smite": return HolySmiteStyle.Purple; case "Holy Smite": return HolySmiteStyle.White; } } return HolySmiteStyle.White; } } internal sealed class HolySmiteMarkEffect : MonoBehaviour { private const int SegmentCount = 32; private const float RingPadding = 0.34f; private const float BaseWidth = 0.085f; private const float PulseWidth = 0.035f; private static readonly Color MarkColor = new Color(1f, 0.18f, 0.18f, 1f); private readonly Dictionary markDamageMultipliers = new Dictionary(); private readonly Vector3[] positions = (Vector3[])(object)new Vector3[33]; private CharacterData? ownerData; private LineRenderer? lineRenderer; private Material? lineMaterial; internal void ApplyMark(int ownerPlayerId, float damageMultiplier) { if (ownerPlayerId >= 0 && !(damageMultiplier <= 1f)) { markDamageMultipliers[ownerPlayerId] = damageMultiplier; EnsureRenderer(); } } internal bool TryGetDamageMultiplier(int ownerPlayerId, out float damageMultiplier) { return markDamageMultipliers.TryGetValue(ownerPlayerId, out damageMultiplier); } internal void ConsumeMark(int ownerPlayerId) { if (markDamageMultipliers.Remove(ownerPlayerId) && markDamageMultipliers.Count <= 0) { Object.Destroy((Object)(object)this); } } private void LateUpdate() { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) if (ownerData == null) { ownerData = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); } if (ownerData == null || ownerData.dead || !ownerData.isPlaying || markDamageMultipliers.Count <= 0) { Object.Destroy((Object)(object)this); return; } EnsureRenderer(); if (lineRenderer != null) { Bounds val = (Bounds)((ownerData.mainCol != null) ? ownerData.mainCol.bounds : new Bounds(((Component)this).transform.position, Vector3.one)); Vector3 center = ((Bounds)(ref val)).center; float num = ((Bounds)(ref val)).extents.x + 0.34f; float num2 = ((Bounds)(ref val)).extents.y + 0.34f; float num3 = 0.5f + 0.5f * Mathf.Sin(Time.time * 8f); float num4 = 0.085f + 0.035f * num3; Color val2 = default(Color); ((Color)(ref val2))..ctor(MarkColor.r, MarkColor.g, MarkColor.b, Mathf.Lerp(0.18f, 0.35f, num3)); for (int i = 0; i <= 32; i++) { float num5 = (float)i / 32f * MathF.PI * 2f; positions[i] = center + new Vector3(Mathf.Cos(num5) * num, Mathf.Sin(num5) * num2, 0f); } ((Renderer)lineRenderer).enabled = true; lineRenderer.positionCount = positions.Length; lineRenderer.SetPositions(positions); lineRenderer.startWidth = num4; lineRenderer.endWidth = num4; lineRenderer.startColor = val2; lineRenderer.endColor = val2; } } private void OnDestroy() { if (lineRenderer != null) { ((Renderer)lineRenderer).enabled = false; Object.Destroy((Object)(object)lineRenderer); } if (lineMaterial != null) { Object.Destroy((Object)(object)lineMaterial); } } private void EnsureRenderer() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown if (lineRenderer == null) { lineRenderer = ((Component)this).gameObject.AddComponent(); lineMaterial = new Material(Shader.Find("Sprites/Default")); ((Renderer)lineRenderer).material = lineMaterial; lineRenderer.useWorldSpace = true; lineRenderer.positionCount = positions.Length; lineRenderer.numCapVertices = 6; ((Renderer)lineRenderer).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)lineRenderer).receiveShadows = false; ((Renderer)lineRenderer).sortingOrder = 1201; } } } internal sealed class HolySmiteProjectileTracker : MonoBehaviour { private const float SmiteColorAlpha = 0.4f; private bool configured; private bool hooksBound; private bool baseSmiteTriggered; private bool suppressNextBounceSmite; private float baseDamage; private float basePercentageDamage; private float damageRatio; private float flatDamage; private float size; private float delay; private float quakingChance; private float stunDuration; private float burnMaxHealthFractionPerSecond; private float burnDurationSeconds; private float lifeStealFraction; private float friendlyHealRatio; private int additionalSmites; private int extraDiscoBeams; private int originalOwnerPlayerId; private int currentOwnerPlayerId; private HolySmiteStyle style; private Color bulletColor; private PhotonView? projectileView; private ProjectileHit? projectileHit; private RayHitReflect? rayHitReflect; private SpawnedAttack? spawnedAttack; private RayCastTrail? rayCastTrail; internal void Configure(float baseDamage, float basePercentageDamage, float damageRatio, float flatDamage, float size, float delay, float quakingChance, float stunDuration, float burnMaxHealthFractionPerSecond, float burnDurationSeconds, float lifeStealFraction, float friendlyHealRatio, int additionalSmites, int extraDiscoBeams, HolySmiteStyle style, Color bulletColor, int originalOwnerPlayerId, int currentOwnerPlayerId) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) this.baseDamage = baseDamage; this.basePercentageDamage = basePercentageDamage; this.damageRatio = damageRatio; this.flatDamage = flatDamage; this.size = size; this.delay = delay; this.quakingChance = quakingChance; this.stunDuration = stunDuration; this.burnMaxHealthFractionPerSecond = burnMaxHealthFractionPerSecond; this.burnDurationSeconds = burnDurationSeconds; this.lifeStealFraction = lifeStealFraction; this.friendlyHealRatio = friendlyHealRatio; this.additionalSmites = additionalSmites; this.extraDiscoBeams = extraDiscoBeams; this.style = style; this.bulletColor = bulletColor; this.originalOwnerPlayerId = originalOwnerPlayerId; this.currentOwnerPlayerId = currentOwnerPlayerId; configured = true; CacheComponents(); EnsureHooks(); ApplyProjectileColor(((Component)this).gameObject, projectileHit, bulletColor); } internal void HandleBlocked(Player blocker) { if (!configured) { return; } CacheComponents(); currentOwnerPlayerId = blocker.playerID; suppressNextBounceSmite = true; if (projectileHit != null) { projectileHit.ownPlayer = blocker; if (blocker.data.weaponHandler?.gun != null) { projectileHit.ownWeapon = ((Component)blocker.data.weaponHandler.gun).gameObject; } } if (spawnedAttack != null) { spawnedAttack.spawner = blocker; } if (rayCastTrail != null) { rayCastTrail.teamID = blocker.teamID; } } internal static Color GetStyleColor(HolySmiteStyle style) { //IL_0069: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) return (Color)(style switch { HolySmiteStyle.Purple => new Color(0.72f, 0.4f, 1f, 0.4f), HolySmiteStyle.Orange => new Color(1f, 0.55f, 0.2f, 0.4f), HolySmiteStyle.WhiteBrown => new Color(0.86f, 0.77f, 0.63f, 0.4f), HolySmiteStyle.Yellow => new Color(1f, 0.9f, 0.25f, 0.4f), HolySmiteStyle.Blue => new Color(0.35f, 0.75f, 1f, 0.4f), HolySmiteStyle.Gold => new Color(1f, 0.82f, 0.2f, 0.4f), HolySmiteStyle.WhiteGray => new Color(0.9f, 0.9f, 0.95f, 0.4f), HolySmiteStyle.LightRed => new Color(1f, 0.52f, 0.46f, 0.4f), HolySmiteStyle.Silver => new Color(0.84f, 0.87f, 0.93f, 0.4f), HolySmiteStyle.DarkRed => new Color(0.62f, 0.12f, 0.12f, 0.4f), HolySmiteStyle.Emerald => new Color(0.22f, 0.84f, 0.46f, 0.4f), HolySmiteStyle.PaleCyan => new Color(0.72f, 0.95f, 1f, 0.4f), HolySmiteStyle.Crimson => new Color(0.86f, 0.1f, 0.22f, 0.4f), HolySmiteStyle.Red => new Color(1f, 0.2f, 0.2f, 0.4f), HolySmiteStyle.Teal => new Color(0.18f, 0.82f, 0.82f, 0.4f), HolySmiteStyle.Pink => new Color(1f, 0.42f, 0.86f, 0.4f), HolySmiteStyle.LightBlueWhite => new Color(0.84f, 0.97f, 1f, 0.4f), _ => new Color(1f, 1f, 1f, 0.4f), }); } internal static Color RollDiscoColor() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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) Color result = Random.ColorHSV(0f, 1f, 0.75f, 1f, 0.85f, 1f, 1f, 1f); result.a = 0.4f; return result; } internal static Vector2 RollDiscoDirection() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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) float num = Random.Range(0f, 360f) * (MathF.PI / 180f); Vector2 val = new Vector2(Mathf.Cos(num), Mathf.Sin(num)); return ((Vector2)(ref val)).normalized; } private void OnDestroy() { if (rayHitReflect != null) { RayHitReflect? obj = rayHitReflect; obj.reflectAction = (Action)Delegate.Remove(obj.reflectAction, new Action(OnBounceImpact)); } } internal static void ResetAll() { HolySmiteProjectileTracker[] array = Object.FindObjectsOfType(); foreach (HolySmiteProjectileTracker holySmiteProjectileTracker in array) { if (holySmiteProjectileTracker != null) { Object.Destroy((Object)(object)holySmiteProjectileTracker); } } } private void CacheComponents() { if (projectileView == null) { projectileView = ((Component)this).GetComponent(); } if (projectileHit == null) { projectileHit = ((Component)this).GetComponent(); } if (rayHitReflect == null) { rayHitReflect = ((Component)this).GetComponent(); } if (spawnedAttack == null) { spawnedAttack = ((Component)this).GetComponent(); } if (rayCastTrail == null) { rayCastTrail = ((Component)this).GetComponent(); } } private void EnsureHooks() { if (!hooksBound && projectileHit != null) { projectileHit.AddHitActionWithData((Action)OnFinalImpact); if (rayHitReflect != null) { RayHitReflect? obj = rayHitReflect; obj.reflectAction = (Action)Delegate.Combine(obj.reflectAction, new Action(OnBounceImpact)); } hooksBound = true; } } private void OnBounceImpact(HitInfo hit) { //IL_002a: 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) if (!configured) { return; } if (suppressNextBounceSmite) { suppressNextBounceSmite = false; return; } if (!baseSmiteTriggered) { baseSmiteTriggered = true; ScheduleSmite(hit.point, useStoredBulletColor: true); return; } float num = Mathf.Clamp01(quakingChance); if (!(num <= 0f) && IsAuthoritative() && Random.value <= num) { ScheduleSmite(hit.point, useStoredBulletColor: false, 0.5f, 0.5f); } } private void OnFinalImpact(HitInfo hit) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (configured && !baseSmiteTriggered) { baseSmiteTriggered = true; ScheduleSmite(hit.point, useStoredBulletColor: true); } } private bool IsAuthoritative() { if (projectileView != null) { return projectileView.IsMine; } return true; } private void ScheduleSmite(Vector2 point, bool useStoredBulletColor, float damageScale = 1f, float sizeScale = 1f) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) if (IsAuthoritative()) { Player? obj = HolySmiteEffect.ResolvePlayerById(originalOwnerPlayerId); HolySmiteEffect holySmiteEffect = ((obj != null) ? ((Component)obj).GetComponent() : null); if (holySmiteEffect == null) { Debug.LogWarning("[DOLY] Holy Smite could not resolve the original owner's smite effect."); } else { holySmiteEffect.BroadcastSmite(currentOwnerPlayerId, originalOwnerPlayerId, point, baseDamage, basePercentageDamage, damageRatio * damageScale, flatDamage * damageScale, size * sizeScale, delay, stunDuration, burnMaxHealthFractionPerSecond, burnDurationSeconds, lifeStealFraction, friendlyHealRatio, additionalSmites, extraDiscoBeams, style, bulletColor, useStoredBulletColor); } } } private static void ApplyProjectileColor(GameObject projectile, ProjectileHit? projectileHit, Color color) { //IL_000a: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) StripTeamColorBehavior(projectile); if (projectileHit != null) { projectileHit.projectileColor = color; } SpawnedAttack component = projectile.GetComponent(); if (component != null) { component.SetColor(color); } SpriteRenderer[] componentsInChildren = projectile.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].color = color; } LineRenderer[] componentsInChildren2 = projectile.GetComponentsInChildren(true); foreach (LineRenderer obj in componentsInChildren2) { obj.startColor = color; obj.endColor = color; } TrailRenderer[] componentsInChildren3 = projectile.GetComponentsInChildren(true); foreach (TrailRenderer obj2 in componentsInChildren3) { obj2.startColor = color; obj2.endColor = color; } ParticleSystem[] componentsInChildren4 = projectile.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren4.Length; i++) { MainModule main = componentsInChildren4[i].main; ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(color); } MeshRenderer[] componentsInChildren5 = projectile.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren5.Length; i++) { ((Renderer)componentsInChildren5[i]).material.color = color; } } private static void StripTeamColorBehavior(GameObject projectile) { SetTeamColor[] componentsInChildren = projectile.GetComponentsInChildren(true); foreach (SetTeamColor obj in componentsInChildren) { ((Behaviour)obj).enabled = false; Object.Destroy((Object)(object)obj); } SetTeamColorFromSpawnedAttack[] componentsInChildren2 = projectile.GetComponentsInChildren(true); foreach (SetTeamColorFromSpawnedAttack obj2 in componentsInChildren2) { ((Behaviour)obj2).enabled = false; Object.Destroy((Object)(object)obj2); } SetTeamColorFromParentPlayer[] componentsInChildren3 = projectile.GetComponentsInChildren(true); foreach (SetTeamColorFromParentPlayer obj3 in componentsInChildren3) { ((Behaviour)obj3).enabled = false; Object.Destroy((Object)(object)obj3); } SetTeamColorSpecific[] componentsInChildren4 = projectile.GetComponentsInChildren(true); foreach (SetTeamColorSpecific obj4 in componentsInChildren4) { ((Behaviour)obj4).enabled = false; Object.Destroy((Object)(object)obj4); } } } internal sealed class HolySmiteReadyGlow : MonoBehaviour { private const int SegmentCount = 64; private const float VisibilitySpeed = 8f; private const float RingPadding = 0.28f; private const float CooldownRingWidth = 0.095f; private const float ReadyRingWidth = 0.115f; private const float ReadyPulseWidth = 0.02f; private const float CooldownRingAlpha = 0.1f; private const float ReadyRingAlpha = 0.26f; private readonly Vector3[] ringPositions = (Vector3[])(object)new Vector3[65]; private CharacterData? ownerData; private LineRenderer? ringRenderer; private Material? ringMaterial; private bool targetReady; private float targetProgress; private float readyVisibility; private float displayedProgress; internal void Bind(CharacterData data) { ownerData = data; EnsureRenderer(); } internal void SetState(bool isReady, float cooldownProgress) { targetReady = isReady; targetProgress = Mathf.Clamp01(cooldownProgress); } private void LateUpdate() { //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) if (ownerData == null) { ownerData = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); } if (ownerData == null) { return; } EnsureRenderer(); if (ringRenderer == null) { return; } readyVisibility = Mathf.MoveTowards(readyVisibility, targetReady ? 1f : 0f, TimeHandler.deltaTime * 8f); displayedProgress = Mathf.MoveTowards(displayedProgress, targetProgress, TimeHandler.deltaTime * 8f); if (displayedProgress <= 0.001f && !targetReady) { ((Renderer)ringRenderer).enabled = false; return; } ((Renderer)ringRenderer).enabled = true; Bounds val = (Bounds)((ownerData.mainCol != null) ? ownerData.mainCol.bounds : new Bounds(((Component)this).transform.position, Vector3.one)); Vector3 center = ((Bounds)(ref val)).center; float num = ((Bounds)(ref val)).extents.x + 0.28f; float num2 = ((Bounds)(ref val)).extents.y + 0.28f; float num3 = 0.5f + 0.5f * Mathf.Sin(Time.time * 7f); int num4 = (targetReady ? 64 : Mathf.Clamp(Mathf.CeilToInt(displayedProgress * 64f), 0, 64)); if (num4 <= 0) { ((Renderer)ringRenderer).enabled = false; return; } for (int i = 0; i <= num4; i++) { float num5 = ((num4 == 0) ? 0f : ((float)i / (float)num4)); float num6 = (targetReady ? num5 : (displayedProgress * num5)); float num7 = MathF.PI / 2f - num6 * MathF.PI * 2f; ringPositions[i] = center + new Vector3(Mathf.Cos(num7) * num, Mathf.Sin(num7) * num2, 0f); } float num8 = (targetReady ? (0.26f + readyVisibility * num3 * 0.05f) : Mathf.Lerp(0.03f, 0.1f, displayedProgress)); float num9 = (targetReady ? (0.115f + readyVisibility * 0.02f * num3) : 0.095f); Color val2 = default(Color); ((Color)(ref val2))..ctor(1f, 0.84f, 0.22f, num8); ringRenderer.positionCount = num4 + 1; ringRenderer.SetPositions(ringPositions); ringRenderer.startWidth = num9; ringRenderer.endWidth = num9; ringRenderer.startColor = val2; ringRenderer.endColor = val2; } private void OnDestroy() { if (ringMaterial != null) { Object.Destroy((Object)(object)ringMaterial); } } private void EnsureRenderer() { if (ringRenderer == null) { ringRenderer = CreateRenderer("HolySmiteRing", ref ringMaterial, 1200); } } private LineRenderer CreateRenderer(string childName, ref Material? material, int sortingOrder) { //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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_002e: 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_003e: 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_005e: Expected O, but got Unknown GameObject val = new GameObject(childName); val.transform.SetParent(((Component)this).transform, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; LineRenderer obj = val.AddComponent(); material = new Material(Shader.Find("Sprites/Default")); ((Renderer)obj).material = material; obj.useWorldSpace = true; obj.loop = false; obj.positionCount = 0; obj.numCapVertices = 6; obj.numCornerVertices = 6; obj.textureMode = (LineTextureMode)0; obj.alignment = (LineAlignment)0; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; ((Renderer)obj).sortingOrder = sortingOrder; ((Renderer)obj).enabled = false; return obj; } } internal sealed class HolySmiteResistanceEffect : MonoBehaviour { internal float DamageTakenMultiplier { get; set; } = 1f; internal bool IsNeutral => Mathf.Approximately(DamageTakenMultiplier, 1f); } internal sealed class HolySmiteShrinkEffect : MonoBehaviour { internal const float MinimumAppliedSizeMultiplier = 0.3f; private static readonly HashSet Instances = new HashSet(); private CharacterData? ownerData; private float appliedMultiplier = 1f; private bool wasDead; internal void Apply(float shrinkMultiplier) { if (shrinkMultiplier >= 0.9999f) { return; } ResolveOwner(); CharacterStatModifiers val = ownerData?.stats; if (val != null) { float num = val.sizeMultiplier / Mathf.Max(0.0001f, appliedMultiplier); float num2 = Mathf.Max(0.3f, appliedMultiplier * Mathf.Clamp(shrinkMultiplier, 0.0001f, 1f)); if (!Mathf.Approximately(num2, appliedMultiplier)) { appliedMultiplier = num2; val.sizeMultiplier = num * appliedMultiplier; RefreshPlayerSize(); } } } internal void ResetShrink() { if (!Mathf.Approximately(appliedMultiplier, 1f)) { ResolveOwner(); CharacterStatModifiers val = ownerData?.stats; if (val == null) { appliedMultiplier = 1f; return; } val.sizeMultiplier /= Mathf.Max(0.0001f, appliedMultiplier); appliedMultiplier = 1f; RefreshPlayerSize(); } } internal static void ResetAll() { List list = new List(Instances); for (int i = 0; i < list.Count; i++) { list[i]?.ResetShrink(); } HolySmiteShrinkEffect[] array = Object.FindObjectsOfType(); foreach (HolySmiteShrinkEffect holySmiteShrinkEffect in array) { if (holySmiteShrinkEffect != null && !Instances.Contains(holySmiteShrinkEffect)) { holySmiteShrinkEffect.ResetShrink(); } } } private void OnEnable() { Instances.Add(this); ResolveOwner(); wasDead = ownerData?.dead ?? false; } private void OnDisable() { ResetShrink(); Instances.Remove(this); } private void Update() { ResolveOwner(); bool flag = ownerData?.dead ?? false; if (wasDead && !flag) { ResetShrink(); } wasDead = flag; } private void OnDestroy() { Instances.Remove(this); ResetShrink(); } private void ResolveOwner() { if (ownerData == null) { ownerData = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); } } private void RefreshPlayerSize() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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) ResolveOwner(); CharacterStatModifiers val = ownerData?.stats; if (ownerData != null && val != null) { val.WasUpdated(); float num = Mathf.Max(0.0001f, ownerData.maxHealth / 100f * 1.2f); ((Component)ownerData).transform.localScale = Vector3.one * 1.2f * Mathf.Pow(num, 0.2f) * val.sizeMultiplier; if (ownerData.playerVel != null) { ownerData.playerVel.mass = 100f * Mathf.Pow(num, 0.8f) * val.sizeMultiplier; } } } } internal enum HolySmiteStyle { White, Purple, Orange, WhiteBrown, Yellow, Blue, Gold, Disco, WhiteGray, LightRed, Silver, DarkRed, Emerald, PaleCyan, Crimson, Red, Teal, Pink, LightBlueWhite } internal sealed class HolySmiteVisual : MonoBehaviour { private const float WarningStartAlpha = 0.04f; private const float WarningHoldAlpha = 0.11f; private const float WarningPeakAlpha = 0.82f; private const float WarningStartWidthMultiplier = 0.12f; private const float WarningHoldWidthMultiplier = 0.26f; private const float WarningPeakWidthMultiplier = 0.58f; private const float WarningRampStartProgress = 0.8f; private const float BeamFadeStartProgress = 0.68f; private const float GlowWidthMultiplier = 1.42f; private const float GlowPulseWidth = 0.09f; private const float CoreWidthMultiplier = 0.34f; private const float FriendlyBrightnessMultiplier = 0.7f; private const float FriendlyAlphaMultiplier = 0.7f; private LineRenderer? warningRenderer; private LineRenderer? glowRenderer; private LineRenderer? beamRenderer; private LineRenderer? coreRenderer; private Material? warningMaterial; private Material? glowMaterial; private Material? beamMaterial; private Material? coreMaterial; private int currentOwnerPlayerId; private int originalOwnerPlayerId; internal static void Spawn(Vector2 center, Vector2 direction, float length, float width, Color color, double fireTime, float beamDuration, bool isFriendlyToViewer, int currentOwnerPlayerId, int originalOwnerPlayerId) { //IL_0005: 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_0010: 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) new GameObject("DOLY_HolySmiteVisual").AddComponent().Initialize(center, direction, length, width, color, fireTime, beamDuration, isFriendlyToViewer, currentOwnerPlayerId, originalOwnerPlayerId); } private void Initialize(Vector2 center, Vector2 direction, float length, float width, Color color, double fireTime, float beamDuration, bool isFriendlyToViewer, int currentOwnerPlayerId, int originalOwnerPlayerId) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: 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) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) this.currentOwnerPlayerId = currentOwnerPlayerId; this.originalOwnerPlayerId = originalOwnerPlayerId; if (((Vector2)(ref direction)).sqrMagnitude <= 0.0001f) { direction = Vector2.down; } ((Vector2)(ref direction)).Normalize(); warningRenderer = CreateRenderer(ref warningMaterial, "Warning", 5000); glowRenderer = CreateRenderer(ref glowMaterial, "Glow", 5001); beamRenderer = CreateRenderer(ref beamMaterial, "Beam", 5002); coreRenderer = CreateRenderer(ref coreMaterial, "Core", 5003); Vector2 val = direction * (length * 0.5f); Vector2 val2 = center - val; Vector2 val3 = center + val; SetLinePositions(warningRenderer, Vector2.op_Implicit(val2), Vector2.op_Implicit(val3)); SetLinePositions(glowRenderer, Vector2.op_Implicit(val2), Vector2.op_Implicit(val3)); SetLinePositions(beamRenderer, Vector2.op_Implicit(val2), Vector2.op_Implicit(val3)); SetLinePositions(coreRenderer, Vector2.op_Implicit(val2), Vector2.op_Implicit(val3)); ((MonoBehaviour)this).StartCoroutine(Play(width, color, fireTime, beamDuration, isFriendlyToViewer)); } private IEnumerator Play(float width, Color color, double fireTime, float beamDuration, bool isFriendlyToViewer) { //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) Color resolvedColor = (Color)(isFriendlyToViewer ? new Color(color.r * 0.7f, color.g * 0.7f, color.b * 0.7f, color.a * 0.7f) : color); double warningStartTime = PhotonNetwork.Time; float warningDuration = Mathf.Max(0f, (float)(fireTime - warningStartTime)); while (PhotonNetwork.Time < fireTime) { if (!HolySmiteEffect.AreSmiteOwnersAlive(currentOwnerPlayerId, originalOwnerPlayerId)) { Object.Destroy((Object)(object)((Component)this).gameObject); yield break; } float num = ((warningDuration <= 0.0001f) ? 1f : Mathf.Clamp01((float)((PhotonNetwork.Time - warningStartTime) / (double)warningDuration))); float num2 = Mathf.Clamp01(num / 0.8f); float num3 = ((num < 0.8f) ? 0f : Mathf.Clamp01((num - 0.8f) / 0.19999999f)); float num4 = ((num3 > 0f) ? Mathf.Lerp(0.11f, 0.82f, Mathf.SmoothStep(0f, 1f, num3)) : Mathf.Lerp(0.04f, 0.11f, Mathf.SmoothStep(0f, 1f, num2))); float num5 = ((num3 > 0f) ? Mathf.Lerp(0.26f, 0.58f, Mathf.SmoothStep(0f, 1f, num3)) : Mathf.Lerp(0.12f, 0.26f, Mathf.SmoothStep(0f, 1f, num2))); Color warningColor = Color.Lerp(resolvedColor, Color.white, 0.2f + 0.45f * num3); warningColor.a *= num4; float num6 = 0.82f + 0.18f * Mathf.Sin(Time.unscaledTime * 11f + num * 9f); SetWarningAppearance(width * num5 * num6, width * num5 * (1.42f + 0.09f * num6), warningColor); yield return null; } Color beamColor = Color.Lerp(resolvedColor, Color.white, 0.2f); beamColor.a = Mathf.Clamp01(resolvedColor.a); Color coreColor = Color.Lerp(beamColor, Color.white, 0.75f); coreColor.a = Mathf.Clamp01(0.95f * resolvedColor.a); SetBeamAppearance(width, width * 1.42f, Mathf.Max(0.08f, width * 0.34f), beamColor, coreColor); float elapsed = 0f; while (elapsed < beamDuration) { if (!HolySmiteEffect.AreSmiteOwnersAlive(currentOwnerPlayerId, originalOwnerPlayerId)) { Object.Destroy((Object)(object)((Component)this).gameObject); yield break; } elapsed += TimeHandler.deltaTime; float num7 = ((beamDuration <= 0.0001f) ? 1f : Mathf.Clamp01(elapsed / beamDuration)); float num8 = ((num7 <= 0.68f) ? 0f : Mathf.Clamp01((num7 - 0.68f) / 0.32f)); float num9 = 0.5f + 0.5f * Mathf.Sin(Time.unscaledTime * 16f + num7 * 10f); float glowWidth = width * (1.42f + 0.09f * num9); Color beamColor2 = beamColor; beamColor2.a *= 1f - Mathf.SmoothStep(0f, 1f, num8); Color coreColor2 = coreColor; coreColor2.a *= 1f - Mathf.SmoothStep(0f, 1f, num8 * 0.92f); SetBeamAppearance(width, glowWidth, Mathf.Max(0.08f, width * 0.34f), beamColor2, coreColor2); yield return null; } Object.Destroy((Object)(object)((Component)this).gameObject); } private void OnDestroy() { DestroyMaterial(warningMaterial); DestroyMaterial(glowMaterial); DestroyMaterial(beamMaterial); DestroyMaterial(coreMaterial); } internal static void ResetAll() { HolySmiteVisual[] array = Object.FindObjectsOfType(); foreach (HolySmiteVisual holySmiteVisual in array) { if (holySmiteVisual != null) { Object.Destroy((Object)(object)((Component)holySmiteVisual).gameObject); } } } private LineRenderer CreateRenderer(ref Material? material, string childName, int sortingOrder) { //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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_002e: 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_003e: 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_005e: Expected O, but got Unknown GameObject val = new GameObject(childName); val.transform.SetParent(((Component)this).transform, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; LineRenderer obj = val.AddComponent(); material = new Material(Shader.Find("Sprites/Default")); ((Renderer)obj).material = material; obj.positionCount = 2; obj.useWorldSpace = true; obj.numCapVertices = 10; obj.numCornerVertices = 10; obj.textureMode = (LineTextureMode)0; obj.alignment = (LineAlignment)0; ((Renderer)obj).sortingOrder = sortingOrder; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; return obj; } private static void SetLinePositions(LineRenderer? renderer, Vector3 start, Vector3 end) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (renderer != null) { renderer.SetPosition(0, start); renderer.SetPosition(1, end); } } private void SetWarningAppearance(float warningWidth, float glowWidth, Color warningColor) { //IL_0008: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) SetRendererState(warningRenderer, enabled: true, warningWidth, warningColor); SetRendererState(glowRenderer, enabled: true, glowWidth, new Color(warningColor.r, warningColor.g, warningColor.b, warningColor.a * 0.42f)); SetRendererState(beamRenderer, enabled: false, 0f, Color.clear); SetRendererState(coreRenderer, enabled: false, 0f, Color.clear); } private void SetBeamAppearance(float beamWidth, float glowWidth, float coreWidth, Color beamColor, Color coreColor) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) SetRendererState(warningRenderer, enabled: false, 0f, Color.clear); SetRendererState(glowRenderer, enabled: true, glowWidth, new Color(beamColor.r, beamColor.g, beamColor.b, beamColor.a * 0.24f)); SetRendererState(beamRenderer, enabled: true, beamWidth, beamColor); SetRendererState(coreRenderer, enabled: true, coreWidth, coreColor); } private static void SetRendererState(LineRenderer? renderer, bool enabled, float width, Color color) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (renderer != null) { ((Renderer)renderer).enabled = enabled; if (enabled) { renderer.startWidth = width; renderer.endWidth = width; renderer.startColor = color; renderer.endColor = color; } } } private static void DestroyMaterial(Material? material) { if (material != null) { Object.Destroy((Object)(object)material); } } } internal sealed class HydrogenBombEffect : ProjectileEffectBase { private const float BaseSplashRadius = 1.5f; private const float BaseSplashDamageRatio = 0.3f; internal int SplashSourceCount { get; set; } internal float SplashRadiusMultiplier { get; set; } = 1f; internal float SplashDamageMultiplier { get; set; } = 1f; internal bool IsNeutral { get { if (SplashSourceCount <= 0 && Mathf.Approximately(SplashRadiusMultiplier, 1f)) { return Mathf.Approximately(SplashDamageMultiplier, 1f); } return false; } } protected override void AttachToProjectile(GameObject projectile, ProjectileHit projectileHit) { float num = ((SplashSourceCount > 0) ? (1.5f * SplashRadiusMultiplier) : 0f); float num2 = ((SplashSourceCount > 0) ? (0.3f * SplashDamageMultiplier) : 0f); if (!(num <= 0f) && !(num2 <= 0f)) { projectile.GetOrAddComponent().Configure(num, num2, base.OwnerPlayer); } } } internal sealed class HydrogenBombProjectileEffect : MonoBehaviour { private ProjectileHit? projectileHit; private Player? ownerPlayer; private float splashRadius; private float splashDamageRatio; private bool configured; private bool splashTriggered; internal void Configure(float splashRadius, float splashDamageRatio, Player? ownerPlayer) { if (!configured) { configured = true; this.splashRadius = Mathf.Max(0f, splashRadius); this.splashDamageRatio = Mathf.Max(0f, splashDamageRatio); this.ownerPlayer = ownerPlayer; projectileHit = ((Component)this).GetComponent(); ProjectileHit? obj = projectileHit; if (obj != null) { obj.AddHitActionWithData((Action)HandleImpact); } } } private void HandleImpact(HitInfo hit) { //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) if (splashTriggered) { return; } splashTriggered = true; List list = PlayerManager.instance?.players; if (list == null || ownerPlayer == null) { return; } HealthHandler val = ((hit.transform == null) ? null : (((Component)hit.transform).GetComponent() ?? ((Component)hit.transform).GetComponentInParent())); if (splashRadius <= 0f || splashDamageRatio <= 0f) { return; } float num = projectileHit?.damage ?? 0f; float num2 = projectileHit?.percentageDamage ?? 0f; float num3 = num * splashDamageRatio; foreach (Player item in list) { if (item == null || item.data == null || item.data.dead || item.teamID == ownerPlayer.teamID) { continue; } HealthHandler healthHandler = item.data.healthHandler; if (healthHandler == null || (Object)(object)healthHandler == (Object)(object)val) { continue; } Bounds val2 = (Bounds)((item.data.mainCol != null) ? item.data.mainCol.bounds : new Bounds(((Component)item).transform.position, Vector3.one)); if (!(Vector2.Distance(Vector2.op_Implicit(((Bounds)(ref val2)).ClosestPoint(Vector2.op_Implicit(hit.point))), hit.point) > splashRadius)) { float num4 = num3 + num2 * item.data.maxHealth * splashDamageRatio; if (!(num4 <= 0f)) { ((Damagable)healthHandler).TakeDamage(Vector2.up * num4, hit.point, ((Component)this).gameObject, ownerPlayer, true, true); } } } } } internal abstract class ProjectileEffectBase : MonoBehaviour { private Gun? hookedGun; protected Gun? HookedGun => hookedGun; protected CharacterData? OwnerData { get; private set; } protected Player? OwnerPlayer { get; private set; } protected virtual void Start() { ResolveOwner(); TryHookGun(); } protected virtual void Update() { TryHookGun(); } protected virtual void OnDestroy() { UnhookGun(); } protected static HealthHandler? GetHitHealth(HitInfo hit) { if (hit.transform == null) { return null; } return ((Component)hit.transform).GetComponent() ?? ((Component)hit.transform).GetComponentInParent(); } protected static CharacterData? GetHitCharacterData(HitInfo hit) { if (hit.transform == null) { return null; } return ((Component)hit.transform).GetComponent() ?? ((Component)hit.transform).GetComponentInParent(); } protected static void ApplyBonusDamage(HealthHandler target, float amount, Vector2 point, GameObject damagingWeapon, Player? damagingPlayer) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!(amount <= 0f)) { ((Damagable)target).TakeDamage(Vector2.up * amount, point, damagingWeapon, damagingPlayer, true, true); } } protected abstract void AttachToProjectile(GameObject projectile, ProjectileHit projectileHit); private void OnProjectileShot(GameObject projectile) { if (((Behaviour)this).isActiveAndEnabled) { ProjectileHit component = projectile.GetComponent(); if (component != null) { AttachToProjectile(projectile, component); } } } private void ResolveOwner() { if (OwnerPlayer == null) { Player obj = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); Player val = obj; OwnerPlayer = obj; } if (OwnerData == null) { CharacterData obj2 = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); CharacterData val2 = obj2; OwnerData = obj2; } } private void TryHookGun() { ResolveOwner(); Gun val = OwnerData?.weaponHandler?.gun; if (val != null && !((Object)(object)val == (Object)(object)hookedGun)) { UnhookGun(); hookedGun = val; Gun? obj = hookedGun; obj.ShootPojectileAction = (Action)Delegate.Combine(obj.ShootPojectileAction, new Action(OnProjectileShot)); } } private void UnhookGun() { if (hookedGun != null) { Gun? obj = hookedGun; obj.ShootPojectileAction = (Action)Delegate.Remove(obj.ShootPojectileAction, new Action(OnProjectileShot)); hookedGun = null; } } } internal sealed class ProjectileGrowthEffect : ProjectileEffectBase { private const float BaseBulletDamageGrowthPerSecond = 1f; private const float BaseBulletSizeGrowthPerSecond = 1f; internal int DamageGrowthSourceCount { get; set; } internal int SizeGrowthSourceCount { get; set; } internal float BulletDamageGrowthMultiplier { get; set; } = 1f; internal float BulletSizeGrowthMultiplier { get; set; } = 1f; internal bool IsNeutral { get { if (DamageGrowthSourceCount <= 0 && SizeGrowthSourceCount <= 0 && Mathf.Approximately(BulletDamageGrowthMultiplier, 1f)) { return Mathf.Approximately(BulletSizeGrowthMultiplier, 1f); } return false; } } protected override void AttachToProjectile(GameObject projectile, ProjectileHit projectileHit) { float num = ((DamageGrowthSourceCount > 0) ? (1f * BulletDamageGrowthMultiplier) : 0f); float num2 = ((SizeGrowthSourceCount > 0) ? (1f * BulletSizeGrowthMultiplier) : 0f); if (!(num <= 0f) || !(num2 <= 0f)) { projectile.GetOrAddComponent().Configure(projectileHit.damage, projectileHit.percentageDamage, num, num2); } } } internal sealed class ProjectileGrowthProjectileEffect : MonoBehaviour { private sealed class TrailState { internal TrailRenderer Renderer; internal float StartWidth; internal float EndWidth; internal float WidthMultiplier; } private sealed class LineState { internal LineRenderer Renderer; internal float StartWidth; internal float EndWidth; } private sealed class TransformState { internal Transform Transform; internal Vector3 LocalScale; } private ProjectileHit? projectileHit; private RayCastTrail? rayCastTrail; private Vector3 initialScale; private float initialRayCastTrailSize = -1f; private float baseDamage; private float basePercentageDamage; private float damageGrowthPerSecond; private float sizeGrowthPerSecond; private float elapsedSeconds; private bool configured; private TrailState[] trailStates = Array.Empty(); private LineState[] lineStates = Array.Empty(); private TransformState[] childTransformStates = Array.Empty(); internal void Configure(float baseDamage, float basePercentageDamage, float damageGrowthPerSecond, float sizeGrowthPerSecond) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (!configured) { configured = true; this.baseDamage = baseDamage; this.basePercentageDamage = basePercentageDamage; this.damageGrowthPerSecond = Mathf.Max(0f, damageGrowthPerSecond); this.sizeGrowthPerSecond = Mathf.Max(0f, sizeGrowthPerSecond); initialScale = ((Component)this).transform.localScale; projectileHit = ((Component)this).GetComponent(); rayCastTrail = ((Component)this).GetComponent(); CacheRenderAndCollisionState(); } } private void Update() { if (configured) { if (damageGrowthPerSecond > 0f || sizeGrowthPerSecond > 0f) { elapsedSeconds += Time.deltaTime; } if (damageGrowthPerSecond > 0f) { ApplyDamageGrowth(1f + elapsedSeconds * damageGrowthPerSecond); } if (sizeGrowthPerSecond > 0f) { ApplySizeGrowth(1f + elapsedSeconds * sizeGrowthPerSecond); } } } private void ApplyDamageGrowth(float damageMultiplier) { if (projectileHit != null) { projectileHit.damage = baseDamage * damageMultiplier; projectileHit.percentageDamage = basePercentageDamage * damageMultiplier; } } private void CacheRenderAndCollisionState() { //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) TrailRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); trailStates = new TrailState[componentsInChildren.Length]; for (int i = 0; i < componentsInChildren.Length; i++) { trailStates[i] = new TrailState { Renderer = componentsInChildren[i], StartWidth = componentsInChildren[i].startWidth, EndWidth = componentsInChildren[i].endWidth, WidthMultiplier = componentsInChildren[i].widthMultiplier }; } LineRenderer[] componentsInChildren2 = ((Component)this).GetComponentsInChildren(true); lineStates = new LineState[componentsInChildren2.Length]; for (int j = 0; j < componentsInChildren2.Length; j++) { lineStates[j] = new LineState { Renderer = componentsInChildren2[j], StartWidth = componentsInChildren2[j].startWidth, EndWidth = componentsInChildren2[j].endWidth }; } Transform[] componentsInChildren3 = ((Component)this).GetComponentsInChildren(true); List list = new List(componentsInChildren3.Length); foreach (Transform val in componentsInChildren3) { if (!((Object)(object)val == (Object)(object)((Component)this).transform) && ((Component)val).GetComponent() == null && ((Component)val).GetComponent() == null && (((Component)val).GetComponent() != null || ((Component)val).GetComponent() != null)) { list.Add(new TransformState { Transform = val, LocalScale = val.localScale }); } } childTransformStates = list.ToArray(); } private void ApplySizeGrowth(float sizeMultiplier) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) ((Component)this).transform.localScale = initialScale * sizeMultiplier; if (rayCastTrail != null) { if (initialRayCastTrailSize < 0f && rayCastTrail.size > 0f) { initialRayCastTrailSize = rayCastTrail.size; } if (initialRayCastTrailSize > 0f) { float num = Mathf.Lerp(1f, sizeMultiplier, 0.5f); rayCastTrail.size = initialRayCastTrailSize * num; } } for (int i = 0; i < trailStates.Length; i++) { TrailRenderer renderer = trailStates[i].Renderer; if (renderer != null) { renderer.startWidth = trailStates[i].StartWidth * sizeMultiplier; renderer.endWidth = trailStates[i].EndWidth * sizeMultiplier; renderer.widthMultiplier = trailStates[i].WidthMultiplier * sizeMultiplier; } } for (int j = 0; j < lineStates.Length; j++) { LineRenderer renderer2 = lineStates[j].Renderer; if (renderer2 != null) { renderer2.startWidth = lineStates[j].StartWidth * sizeMultiplier; renderer2.endWidth = lineStates[j].EndWidth * sizeMultiplier; } } for (int k = 0; k < childTransformStates.Length; k++) { Transform transform = childTransformStates[k].Transform; if (transform != null) { transform.localScale = childTransformStates[k].LocalScale * sizeMultiplier; } } } } internal sealed class RingOfFireWave : MonoBehaviour { private const int SegmentCount = 64; private const float RingWidth = 0.9f; private const float RadiusPadding = 0.8f; private static Material? sharedMaterial; private readonly HashSet hitPlayers = new HashSet(); private LineRenderer? lineRenderer; private Vector2 center; private float finalRadius; private float duration; private float flatDamage; private float percentageDamage; private int ownerPlayerId; private int ownerTeamId; private bool ignoreBlock; private float blockPierceDamageMultiplier = 1f; private Color color = new Color(1f, 0.45f, 0.12f, 1f); private float elapsed; private float currentRadius; private bool configured; internal void Configure(Vector2 center, float finalRadius, float duration, float flatDamage, float percentageDamage, int ownerPlayerId, int ownerTeamId, bool ignoreBlock, float blockPierceDamageMultiplier, Color color) { //IL_0011: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_00a6: Unknown result type (might be due to invalid IL or missing references) if (!configured) { configured = true; this.center = center; this.finalRadius = Mathf.Max(0.1f, finalRadius); this.duration = Mathf.Max(0.05f, duration); this.flatDamage = Mathf.Max(0f, flatDamage); this.percentageDamage = Mathf.Max(0f, percentageDamage); this.ownerPlayerId = ownerPlayerId; this.ownerTeamId = ownerTeamId; this.ignoreBlock = ignoreBlock; this.blockPierceDamageMultiplier = Mathf.Max(0f, blockPierceDamageMultiplier); this.color = color; ((Component)this).transform.position = new Vector3(center.x, center.y, 0f); EnsureLineRenderer(); UpdateVisual(0f); } } private void Awake() { EnsureLineRenderer(); } private void Update() { if (configured) { float previousRadius = currentRadius; elapsed += TimeHandler.deltaTime; currentRadius = Mathf.Lerp(0f, finalRadius, Mathf.Clamp01(elapsed / duration)); ApplyDamage(previousRadius, currentRadius); UpdateVisual(currentRadius); if (elapsed >= duration) { Object.Destroy((Object)(object)((Component)this).gameObject); } } } private void ApplyDamage(float previousRadius, float nextRadius) { //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) List list = PlayerManager.instance?.players; if (list == null) { return; } Player val = null; foreach (Player item in list) { if (val == null && item != null && item.playerID == ownerPlayerId) { val = item; } if (item == null || item.playerID == ownerPlayerId || item.teamID == ownerTeamId || hitPlayers.Contains(item.playerID) || item.data == null || item.data.dead || item.data.healthHandler == null) { continue; } bool flag = item.data.block != null && item.data.block.IsBlocking(); if (!ignoreBlock && flag) { continue; } Bounds val2 = (Bounds)((item.data.mainCol != null) ? item.data.mainCol.bounds : new Bounds(((Component)item).transform.position, Vector3.one)); float num = Vector2.Distance(Vector2.op_Implicit(((Bounds)(ref val2)).ClosestPoint(Vector2.op_Implicit(center))), center); if (num < previousRadius - 0.8f || num > nextRadius + 0.8f) { continue; } float num2 = flatDamage + percentageDamage * item.data.maxHealth; if (ignoreBlock && flag) { num2 *= blockPierceDamageMultiplier; } if (num2 <= 0f) { continue; } Vector2 val3 = Vector2.op_Implicit(((Component)item).transform.position) - center; if (((Vector2)(ref val3)).sqrMagnitude <= 0.0001f) { val3 = Vector2.up; } HealthHandler healthHandler = item.data.healthHandler; Vector2 val4 = ((Vector2)(ref val3)).normalized * num2; Vector2 val5 = center; object obj; if (val == null) { obj = null; } else { CharacterData data = val.data; if (data == null) { obj = null; } else { WeaponHandler weaponHandler = data.weaponHandler; if (weaponHandler == null) { obj = null; } else { Gun gun = weaponHandler.gun; obj = ((gun != null) ? ((Component)gun).gameObject : null); } } } ((Damagable)healthHandler).TakeDamage(val4, val5, (GameObject)obj, val, true, ignoreBlock); hitPlayers.Add(item.playerID); } } private void EnsureLineRenderer() { //IL_00aa: 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) if (lineRenderer == null) { lineRenderer = ((Component)this).GetComponent(); if (lineRenderer == null) { lineRenderer = ((Component)this).gameObject.AddComponent(); } if (sharedMaterial == null) { sharedMaterial = CreateSharedMaterial(); } if (sharedMaterial != null) { ((Renderer)lineRenderer).material = sharedMaterial; } lineRenderer.useWorldSpace = true; lineRenderer.loop = true; lineRenderer.positionCount = 64; lineRenderer.widthMultiplier = 0.9f; lineRenderer.numCapVertices = 6; lineRenderer.numCornerVertices = 6; lineRenderer.startColor = color; lineRenderer.endColor = color; ((Renderer)lineRenderer).sortingOrder = 1000; } } private void UpdateVisual(float radius) { //IL_0010: 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_0045: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) if (lineRenderer != null) { lineRenderer.startColor = color; lineRenderer.endColor = color; for (int i = 0; i < 64; i++) { float num = (float)i / 64f * MathF.PI * 2f; Vector2 val = center + new Vector2(Mathf.Cos(num), Mathf.Sin(num)) * radius; lineRenderer.SetPosition(i, new Vector3(val.x, val.y, 0f)); } } } private static Material? CreateSharedMaterial() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color"); if (val == null) { return null; } return new Material(val) { hideFlags = (HideFlags)61 }; } } internal sealed class ScopiestScopeEffect : MonoBehaviour { internal float SavedSpread { get; set; } } internal sealed class SelfDamageReductionEffect : MonoBehaviour { internal int Stacks { get; set; } internal float Multiplier { get; set; } = 1f; internal bool IsNeutral { get { if (Stacks <= 0) { return Mathf.Approximately(Multiplier, 1f); } return false; } } internal float GetMultiplier() { return ((Stacks <= 0) ? 1f : Mathf.Pow(0.05f, (float)Stacks)) * Multiplier; } } internal sealed class StimsEffect : MonoBehaviour { private const float CooldownSeconds = 12f; private const float BuffDurationSeconds = 4f; private const float RegenPerSecond = 500f; private CharacterData? ownerData; private Player? ownerPlayer; private Block? hookedBlock; private GM_ArmsRace? hookedGameMode; private double cooldownReadyTime; private double buffExpiresAt = double.NegativeInfinity; internal int Stacks { get; set; } private bool IsBuffActive => (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time) < buffExpiresAt; private void OnEnable() { ResolveOwner(); TryHookBlock(); TryHookRoundReset(); } private void Start() { ResolveOwner(); TryHookBlock(); TryHookRoundReset(); } private void Update() { ResolveOwner(); TryHookBlock(); TryHookRoundReset(); if (IsBuffActive) { if (ownerData == null || ownerData.dead) { EndStim(); } else if (ownerData.view != null && ownerData.view.IsMine && ownerData.healthHandler != null) { ownerData.healthHandler.Heal(500f * TimeHandler.deltaTime); } } } private void OnDisable() { UnhookBlock(); UnhookRoundReset(); EndStim(); } private void OnDestroy() { UnhookBlock(); UnhookRoundReset(); EndStim(); } [PunRPC] private void RPCA_ActivateStim(double syncedCooldownReadyTime, double syncedBuffExpiresAt) { cooldownReadyTime = Math.Max(cooldownReadyTime, syncedCooldownReadyTime); buffExpiresAt = Math.Max(buffExpiresAt, syncedBuffExpiresAt); BeginStim(); } private void HandleBlock(BlockTriggerType triggerType) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if ((int)triggerType != 0 || Stacks <= 0) { return; } ResolveOwner(); if (ownerData == null || ownerPlayer == null || ownerData.view == null || !ownerData.view.IsMine || ownerData.dead) { return; } double num = (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time); if (!(num < cooldownReadyTime)) { double num2 = num + 12.0; double num3 = num + 4.0; if (PhotonNetwork.OfflineMode) { RPCA_ActivateStim(num2, num3); return; } ownerData.view.RPC("RPCA_ActivateStim", (RpcTarget)0, new object[2] { num2, num3 }); } } private void BeginStim() { ResolveOwner(); _ = ownerData; } private void EndStim() { buffExpiresAt = double.NegativeInfinity; } private void ResolveOwner() { if (ownerData == null) { ownerData = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); } if (ownerPlayer == null) { ownerPlayer = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); } } private void TryHookBlock() { Block val = ownerData?.block; if (val != null && !((Object)(object)val == (Object)(object)hookedBlock)) { UnhookBlock(); hookedBlock = val; Block? obj = hookedBlock; obj.BlockAction = (Action)Delegate.Combine(obj.BlockAction, new Action(HandleBlock)); } } private void UnhookBlock() { if (hookedBlock != null) { Block? obj = hookedBlock; obj.BlockAction = (Action)Delegate.Remove(obj.BlockAction, new Action(HandleBlock)); hookedBlock = null; } } private void TryHookRoundReset() { if (hookedGameMode == null && GM_ArmsRace.instance != null) { hookedGameMode = GM_ArmsRace.instance; GM_ArmsRace? obj = hookedGameMode; obj.pointOverAction = (Action)Delegate.Combine(obj.pointOverAction, new Action(HandlePointOver)); } } private void UnhookRoundReset() { if (hookedGameMode != null) { GM_ArmsRace? obj = hookedGameMode; obj.pointOverAction = (Action)Delegate.Remove(obj.pointOverAction, new Action(HandlePointOver)); hookedGameMode = null; } } private void HandlePointOver() { cooldownReadyTime = 0.0; EndStim(); } } internal sealed class SuppressorEffect : MonoBehaviour { private sealed class Snapshot { internal static readonly Snapshot Identity = new Snapshot(null, 1f, 1f, 1f, 1f); internal Gun? Gun { get; } internal float DamageMultiplier { get; } internal float ProjectileSpeedMultiplier { get; } internal float AttackSpeedMultiplier { get; } internal float SpreadMultiplier { get; } internal Snapshot(Gun? gun, float damageMultiplier, float projectileSpeedMultiplier, float attackSpeedMultiplier, float spreadMultiplier) { Gun = gun; DamageMultiplier = damageMultiplier; ProjectileSpeedMultiplier = projectileSpeedMultiplier; AttackSpeedMultiplier = attackSpeedMultiplier; SpreadMultiplier = spreadMultiplier; } } private const float ResetEffectiveFireDelaySeconds = 0.3f; private const float DamageBonusPerStep = 0.18f; private const float ProjectileSpeedBonusPerStep = 0.05f; private const float DamageStepSeconds = 0.01f; private const float SpreadMultiplier = 0.2f; private readonly List snapshots = new List(); private Gun? hookedGun; internal bool IsEmpty => snapshots.Count <= 0; internal void AddSnapshot(CharacterData data, Gun gun) { if (hookedGun == null) { hookedGun = gun; } float num = Mathf.Max(0.001f, data.stats?.attackSpeedMultiplier ?? 1f); float num2 = gun.attackSpeed / num; if (num2 >= 0.3f) { Snapshot snapshot = new Snapshot(gun, 1f, 1f, 1f, 0.2f); snapshots.Add(snapshot); ApplySnapshot(snapshot); return; } int num3 = Mathf.FloorToInt((0.3f - num2) / 0.01f); float damageMultiplier = ((num3 > 0) ? (1f + (float)num3 * 0.18f) : 1f); float projectileSpeedMultiplier = ((num3 > 0) ? (1f + (float)num3 * 0.05f) : 1f); float attackSpeedMultiplier = 0.3f * num / Mathf.Max(0.0001f, gun.attackSpeed); Snapshot snapshot2 = new Snapshot(gun, damageMultiplier, projectileSpeedMultiplier, attackSpeedMultiplier, 0.2f); snapshots.Add(snapshot2); ApplySnapshot(snapshot2); } internal void RemoveSnapshot() { if (snapshots.Count > 0) { int index = snapshots.Count - 1; Snapshot snapshot = snapshots[index]; snapshots.RemoveAt(index); RemoveSnapshot(snapshot); } } private void OnDestroy() { RemoveAllSnapshots(); } private static void ApplySnapshot(Snapshot snapshot) { if (snapshot.Gun != null) { Gun? gun = snapshot.Gun; gun.damage *= snapshot.DamageMultiplier; Gun? gun2 = snapshot.Gun; gun2.projectileSpeed *= snapshot.ProjectileSpeedMultiplier; Gun? gun3 = snapshot.Gun; gun3.attackSpeed *= snapshot.AttackSpeedMultiplier; Gun? gun4 = snapshot.Gun; gun4.spread *= snapshot.SpreadMultiplier; } } private static void RemoveSnapshot(Snapshot snapshot) { if (snapshot.Gun != null) { if (!Mathf.Approximately(snapshot.DamageMultiplier, 1f)) { Gun? gun = snapshot.Gun; gun.damage /= snapshot.DamageMultiplier; } if (!Mathf.Approximately(snapshot.ProjectileSpeedMultiplier, 1f)) { Gun? gun2 = snapshot.Gun; gun2.projectileSpeed /= snapshot.ProjectileSpeedMultiplier; } if (!Mathf.Approximately(snapshot.AttackSpeedMultiplier, 1f)) { Gun? gun3 = snapshot.Gun; gun3.attackSpeed /= snapshot.AttackSpeedMultiplier; } if (!Mathf.Approximately(snapshot.SpreadMultiplier, 1f)) { Gun? gun4 = snapshot.Gun; gun4.spread /= snapshot.SpreadMultiplier; } } } private void RemoveAllSnapshots() { for (int num = snapshots.Count - 1; num >= 0; num--) { RemoveSnapshot(snapshots[num]); } snapshots.Clear(); hookedGun = null; } } internal sealed class TackBurstController : MonoBehaviour { private sealed class TackPlaybackShot { internal TackShotPlan Plan { get; } internal TackVisualShot Visual { get; } internal bool Resolved { get; set; } internal TackPlaybackShot(TackShotPlan plan, TackVisualShot visual) { Plan = plan; Visual = visual; } } private TackShooterEffect? ownerEffect; private TackPlaybackShot[] shots = Array.Empty(); private bool configured; private int resolvedCount; private double fireTime; internal int BurstId { get; private set; } internal int OwnerPlayerId { get; private set; } internal float Speed { get; private set; } internal float FlatDamage { get; private set; } internal float PercentageDamage { get; private set; } internal void Configure(TackShooterEffect ownerEffect, int burstId, int ownerPlayerId, float speed, float flatDamage, float percentageDamage, Color color, double fireTime, float[] shotPayload, int[] resultPayload) { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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_00d8: Unknown result type (might be due to invalid IL or missing references) if (configured) { return; } int count = TackShotPlan.GetCount(shotPayload, resultPayload); if (count <= 0) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } configured = true; this.ownerEffect = ownerEffect; BurstId = burstId; OwnerPlayerId = ownerPlayerId; Speed = Mathf.Max(0.01f, speed); FlatDamage = Mathf.Max(0f, flatDamage); PercentageDamage = Mathf.Max(0f, percentageDamage); this.fireTime = fireTime; shots = new TackPlaybackShot[count]; for (int i = 0; i < count; i++) { TackShotPlan tackShotPlan = TackShotPlan.FromPayload(shotPayload, resultPayload, i); GameObject val = new GameObject($"DOLY_TackVisual_{burstId}_{i}"); val.transform.SetParent(((Component)this).transform, true); TackVisualShot tackVisualShot = val.AddComponent(); tackVisualShot.Configure(tackShotPlan.Origin, tackShotPlan.Direction, color); shots[i] = new TackPlaybackShot(tackShotPlan, tackVisualShot); } } private void Update() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) if (!configured) { return; } double num = (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time); if (num < fireTime) { return; } float num2 = Mathf.Max(0f, (float)(num - fireTime)); for (int i = 0; i < shots.Length; i++) { TackPlaybackShot tackPlaybackShot = shots[i]; if (!tackPlaybackShot.Resolved) { TackShotPlan plan = tackPlaybackShot.Plan; float travelTime = plan.GetTravelTime(Speed); float num3 = Mathf.Min(plan.TravelDistance, num2 * Speed); tackPlaybackShot.Visual.SetTipPosition(plan.Origin + plan.Direction * num3); if (!(num2 + 0.0001f < travelTime)) { ResolveShot(tackPlaybackShot); } } } if (resolvedCount >= shots.Length) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void OnDestroy() { if (ownerEffect != null) { ownerEffect.NotifyBurstFinished(BurstId, this); } } private void ResolveShot(TackPlaybackShot shot) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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) if (!shot.Resolved) { shot.Resolved = true; resolvedCount++; TackShotPlan plan = shot.Plan; if (plan.ImpactType == TackImpactType.None) { shot.Visual.FinishAt(plan.StopPoint); return; } shot.Visual.Resolve(plan.StopPoint, plan.Direction, plan.Normal, plan.ImpactType == TackImpactType.Blocked); ownerEffect?.ApplyPlannedImpact(OwnerPlayerId, FlatDamage, PercentageDamage, plan); } } } internal sealed class TackVisualShot : MonoBehaviour { private const float StemLength = 0.42f; private const float HeadWidth = 0.34f; private const float LineWidth = 0.08f; private static Material? sharedMaterial; private LineRenderer? stemRenderer; private LineRenderer? headRenderer; private Vector2 direction; internal void Configure(Vector2 tipPosition, Vector2 direction, Color color) { //IL_0018: 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_001d: 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_003b: 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) this.direction = ((((Vector2)(ref direction)).sqrMagnitude > 0.0001f) ? ((Vector2)(ref direction)).normalized : Vector2.right); stemRenderer = CreateRenderer("Stem", color); headRenderer = CreateRenderer("Head", color); SetTipPosition(tipPosition); } internal void SetTipPosition(Vector2 tipPosition) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) if (stemRenderer != null && headRenderer != null) { Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f - direction.y, direction.x); Vector2 val2 = tipPosition - direction * 0.42f; stemRenderer.SetPosition(0, Vector2.op_Implicit(tipPosition)); stemRenderer.SetPosition(1, Vector2.op_Implicit(val2)); headRenderer.SetPosition(0, Vector2.op_Implicit(val2 - val * 0.17f)); headRenderer.SetPosition(1, Vector2.op_Implicit(val2 + val * 0.17f)); } } internal void Resolve(Vector2 point, Vector2 impactDirection, Vector2 normal, bool wasBlocked) { //IL_001c: 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) //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (((Vector2)(ref impactDirection)).sqrMagnitude > 0.0001f) { direction = ((Vector2)(ref impactDirection)).normalized; } SetTipPosition(point); Object.Destroy((Object)(object)((Component)this).gameObject, wasBlocked ? 0.03f : 0.05f); } internal void FinishAt(Vector2 point) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) SetTipPosition(point); Object.Destroy((Object)(object)((Component)this).gameObject, 0.02f); } private static Material GetSharedMaterial() { //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) //IL_0037: Expected O, but got Unknown if (sharedMaterial != null) { return sharedMaterial; } sharedMaterial = new Material(Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color")) { hideFlags = (HideFlags)61 }; return sharedMaterial; } private LineRenderer CreateRenderer(string name, Color color) { //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_0049: 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) GameObject val = new GameObject(name); val.transform.SetParent(((Component)this).transform, false); LineRenderer obj = val.AddComponent(); ((Renderer)obj).material = GetSharedMaterial(); obj.useWorldSpace = true; obj.positionCount = 2; obj.widthMultiplier = 0.08f; obj.numCapVertices = 6; obj.startColor = color; obj.endColor = color; ((Renderer)obj).sortingOrder = 1000; return obj; } } internal enum TackImpactType { None, World, Blocked, Health, Damagable } internal sealed class TackShotPlan { internal const int FloatStride = 9; internal const int IntStride = 3; internal Vector2 Origin { get; } internal Vector2 Direction { get; } internal Vector2 StopPoint { get; } internal Vector2 Normal { get; } internal float TravelDistance { get; } internal TackImpactType ImpactType { get; } internal int ViewId { get; } internal int ColliderId { get; } internal TackShotPlan(Vector2 origin, Vector2 direction, Vector2 stopPoint, Vector2 normal, float travelDistance, TackImpactType impactType, int viewId, int colliderId) { //IL_0007: 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_000e: 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_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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) Origin = origin; Direction = direction; StopPoint = stopPoint; Normal = normal; TravelDistance = travelDistance; ImpactType = impactType; ViewId = viewId; ColliderId = colliderId; } internal float GetTravelTime(float speed) { return TravelDistance / Mathf.Max(0.01f, speed); } internal void WriteTo(float[] shotPayload, int[] resultPayload, int shotIndex) { //IL_0008: 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_0028: 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_0048: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) int num = shotIndex * 9; shotPayload[num] = Origin.x; shotPayload[num + 1] = Origin.y; shotPayload[num + 2] = Direction.x; shotPayload[num + 3] = Direction.y; shotPayload[num + 4] = StopPoint.x; shotPayload[num + 5] = StopPoint.y; shotPayload[num + 6] = Normal.x; shotPayload[num + 7] = Normal.y; shotPayload[num + 8] = TravelDistance; int num2 = shotIndex * 3; resultPayload[num2] = (int)ImpactType; resultPayload[num2 + 1] = ViewId; resultPayload[num2 + 2] = ColliderId; } internal static TackShotPlan FromPayload(float[] shotPayload, int[] resultPayload, int shotIndex) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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) //IL_003e: Unknown result type (might be due to invalid IL or missing references) int num = shotIndex * 9; int num2 = shotIndex * 3; return new TackShotPlan(new Vector2(shotPayload[num], shotPayload[num + 1]), new Vector2(shotPayload[num + 2], shotPayload[num + 3]), new Vector2(shotPayload[num + 4], shotPayload[num + 5]), new Vector2(shotPayload[num + 6], shotPayload[num + 7]), shotPayload[num + 8], (TackImpactType)resultPayload[num2], resultPayload[num2 + 1], resultPayload[num2 + 2]); } internal static int GetCount(float[] shotPayload, int[] resultPayload) { if (shotPayload == null || resultPayload == null) { return 0; } if (shotPayload.Length == 0 || resultPayload.Length == 0) { return 0; } if (shotPayload.Length % 9 != 0 || resultPayload.Length % 3 != 0) { return 0; } int num = shotPayload.Length / 9; int num2 = resultPayload.Length / 3; if (num != num2) { return 0; } return num; } } internal static class TackBurstPlanner { private const float TackHitRadius = 0.18f; private const int MaxSweepHits = 48; internal static TackShotPlan PlanShot(Player? ownerPlayer, Vector2 origin, Vector2 direction, float range, bool ignoreBlock, int worldMask, int playerMask) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: 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) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) Vector2 val = ((((Vector2)(ref direction)).sqrMagnitude > 0.0001f) ? ((Vector2)(ref direction)).normalized : Vector2.right); float num = Mathf.Max(0.01f, range); int num2 = worldMask | playerMask; RaycastHit2D[] array = (RaycastHit2D[])(object)new RaycastHit2D[48]; int num3 = Physics2D.CircleCastNonAlloc(origin, 0.18f, val, array, num, num2); bool flag = false; TackShotPlan tackShotPlan = null; for (int i = 0; i < num3; i++) { if (TryCreatePlan(ownerPlayer, origin, val, ignoreBlock, array[i], out TackShotPlan plan) && (!flag || tackShotPlan == null || !(plan.TravelDistance >= tackShotPlan.TravelDistance))) { flag = true; tackShotPlan = plan; } } if (flag) { return tackShotPlan; } Vector2 stopPoint = origin + val * num; return new TackShotPlan(origin, val, stopPoint, -val, num, TackImpactType.None, -1, -1); } private static bool TryCreatePlan(Player? ownerPlayer, Vector2 origin, Vector2 direction, bool ignoreBlock, RaycastHit2D hit, out TackShotPlan plan) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) plan = null; if (!Object.op_Implicit((Object)(object)((RaycastHit2D)(ref hit)).collider) || !((Behaviour)((RaycastHit2D)(ref hit)).collider).enabled || ((RaycastHit2D)(ref hit)).collider.isTrigger) { return false; } if (ownerPlayer != null && (Object)(object)((RaycastHit2D)(ref hit)).transform.root == (Object)(object)((Component)ownerPlayer).transform.root) { return false; } if (!TryClassifyImpact(hit, ignoreBlock, out var impactType)) { return false; } if (!TackHitResolver.TryDescribeHit(hit, origin, direction, out var point, out var normal, out var viewId, out var colliderId)) { return false; } float num = ((RaycastHit2D)(ref hit)).distance; if (num <= 0.0001f) { num = Mathf.Max(0f, Vector2.Dot(point - origin, direction)); } plan = new TackShotPlan(origin, direction, point, normal, num, impactType, viewId, colliderId); return true; } private static bool TryClassifyImpact(RaycastHit2D hit, bool ignoreBlock, out TackImpactType impactType) { impactType = TackImpactType.None; if ((((Component)((RaycastHit2D)(ref hit)).collider).GetComponent() ?? ((Component)((RaycastHit2D)(ref hit)).collider).GetComponentInParent()) != null) { if (ignoreBlock) { return false; } impactType = TackImpactType.Blocked; return true; } HealthHandler val = ((Component)((RaycastHit2D)(ref hit)).transform).GetComponent() ?? ((Component)((RaycastHit2D)(ref hit)).transform).GetComponentInParent(); if (val != null) { Block val2 = ((Component)val).GetComponent() ?? ((Component)val).GetComponentInParent(); if (!ignoreBlock && val2 != null && val2.IsBlocking()) { impactType = TackImpactType.Blocked; return true; } impactType = TackImpactType.Health; return true; } if ((((Component)((RaycastHit2D)(ref hit)).collider).GetComponentInParent() ?? ((Component)((RaycastHit2D)(ref hit)).transform).GetComponentInParent()) != null) { impactType = TackImpactType.Damagable; return true; } impactType = TackImpactType.World; return true; } } internal static class TackHitResolver { private const int HelldiverSentryViewId = -2; internal static bool TryDescribeHit(RaycastHit2D hit, Vector2 origin, Vector2 direction, out Vector2 point, out Vector2 normal, out int viewId, out int colliderId) { //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_000d: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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) //IL_0052: 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) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) point = Vector2.zero; normal = Vector2.zero; viewId = -1; colliderId = -1; if (((RaycastHit2D)(ref hit)).collider == null) { return false; } Vector2 val; if (!(((RaycastHit2D)(ref hit)).distance <= 0.0001f)) { val = ((RaycastHit2D)(ref hit)).point; } else { Bounds bounds = ((RaycastHit2D)(ref hit)).collider.bounds; val = Vector2.op_Implicit(((Bounds)(ref bounds)).ClosestPoint(Vector2.op_Implicit(origin))); } point = val; Vector2 normal2 = ((RaycastHit2D)(ref hit)).normal; Vector2 val2; if (!(((Vector2)(ref normal2)).sqrMagnitude > 0.0001f)) { val2 = -direction; } else { normal2 = ((RaycastHit2D)(ref hit)).normal; val2 = ((Vector2)(ref normal2)).normalized; } normal = val2; if (HelldiverSentryDamageable.TryGetFromCollider(((RaycastHit2D)(ref hit)).collider, out HelldiverSentryDamageable sentry)) { viewId = -2; colliderId = sentry.Seed; return colliderId >= 0; } Transform root = ((RaycastHit2D)(ref hit)).transform.root; PhotonView component = ((Component)root).GetComponent(); if (component != null) { viewId = component.ViewID; colliderId = FindColliderIndex(root, ((RaycastHit2D)(ref hit)).collider); return colliderId >= 0; } colliderId = FindMapColliderIndex(((RaycastHit2D)(ref hit)).collider); return colliderId >= 0; } internal static bool TryResolveTarget(int viewId, int colliderId, out Collider2D collider, out Transform targetTransform) { collider = null; targetTransform = null; if (viewId == -2) { return HelldiverSentryDamageable.TryResolveTargetBySeed(colliderId, out collider, out targetTransform); } if (viewId >= 0) { PhotonView photonView = PhotonNetwork.GetPhotonView(viewId); if (photonView == null) { return false; } Collider2D[] componentsInChildren = ((Component)((Component)photonView).transform.root).GetComponentsInChildren(); if (colliderId < 0 || colliderId >= componentsInChildren.Length || componentsInChildren[colliderId] == null) { return false; } collider = componentsInChildren[colliderId]; targetTransform = ((Component)collider).transform; return true; } Collider2D[] mapColliders = GetMapColliders(); if (colliderId < 0 || colliderId >= mapColliders.Length || mapColliders[colliderId] == null) { return false; } collider = mapColliders[colliderId]; targetTransform = ((Component)collider).transform; return true; } private static int FindColliderIndex(Transform root, Collider2D targetCollider) { Collider2D[] componentsInChildren = ((Component)root).GetComponentsInChildren(); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] == (Object)(object)targetCollider) { return i; } } return -1; } private static int FindMapColliderIndex(Collider2D targetCollider) { Collider2D[] mapColliders = GetMapColliders(); for (int i = 0; i < mapColliders.Length; i++) { if ((Object)(object)mapColliders[i] == (Object)(object)targetCollider) { return i; } } return -1; } private static Collider2D[] GetMapColliders() { MapManager instance = MapManager.instance; object obj; if (instance == null) { obj = null; } else { MapWrapper currentMap = instance.currentMap; obj = ((currentMap != null) ? currentMap.Map : null); } if (obj == null) { return Array.Empty(); } return ((Component)MapManager.instance.currentMap.Map).GetComponentsInChildren(); } } internal sealed class TackShooterEffect : ProjectileEffectBase { private const float SpawnOffset = 0.75f; private const float SpawnPadding = 0.2f; private const float RingOfFirePercentDamagePerTack = 0.003f; private static readonly Color DefaultTackColor = new Color(1f, 0.41f, 0.71f, 1f); private static readonly Color HotShotsTackColor = Color.red; private static readonly Color DefaultRingOfFireColor = new Color(1f, 0.45f, 0.12f, 1f); private readonly Dictionary activeBursts = new Dictionary(); private int nextBurstId = 1; internal int TackCount { get; set; } internal float TackRange { get; set; } internal float TackDamageMultiplier { get; set; } = 1f; internal int UnblockableStacks { get; set; } internal int HotShotsColorStacks { get; set; } internal float BlockPierceDamageMultiplier { get; set; } = 1f; internal int RingOfFireStacks { get; set; } internal float ResolvedRingOfFirePercentDamage { get { if (RingOfFireStacks > 0) { return (float)Mathf.Max(0, TackCount) * 0.003f; } return 0f; } } internal bool IsEmpty { get { if (TackCount <= 0 && TackRange <= 0f && Mathf.Approximately(TackDamageMultiplier, 1f) && UnblockableStacks <= 0 && HotShotsColorStacks <= 0 && Mathf.Approximately(BlockPierceDamageMultiplier, 1f)) { return RingOfFireStacks <= 0; } return false; } } protected override void Update() { base.Update(); if (base.HookedGun != null && base.OwnerData?.stats != null) { float num = 0.033f * Mathf.Max(0.001f, base.OwnerData.stats.attackSpeedMultiplier); if (base.HookedGun.attackSpeed < num) { base.HookedGun.attackSpeed = num; } } } protected override void AttachToProjectile(GameObject projectile, ProjectileHit projectileHit) { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) if (base.OwnerPlayer == null) { return; } PhotonView component = projectile.GetComponent(); if (component == null || !component.IsMine) { return; } if (RingOfFireStacks > 0) { TrySpawnRingOfFire(projectileHit); } else if (TackCount > 0 && !(TackRange <= 0f)) { RayCastTrail component2 = projectile.GetComponent(); int worldMask = ((component2 != null) ? ((LayerMask)(ref component2.mask)).value : LayerMask.GetMask(new string[3] { "Default", "IgnorePlayer", "IgnoreMap" })); int playerMask = ((component2 != null) ? ((LayerMask)(ref component2.playerMask)).value : LayerMask.GetMask(new string[1] { "Player" })); Vector2 forward = ResolveSourceForward(projectile); int num = nextBurstId++; double num2 = (PhotonNetwork.OfflineMode ? ((double)Time.unscaledTime) : PhotonNetwork.Time); float range = TackRange * 1f; float num3 = Mathf.Max(0f, projectileHit.damage * 0.5f * TackDamageMultiplier); float num4 = Mathf.Max(0f, projectileHit.percentageDamage * 0.5f * TackDamageMultiplier); bool ignoreBlock = UnblockableStacks > 0; BuildTackShotPayload(projectile, forward, range, ignoreBlock, worldMask, playerMask, out float[] shotPayload, out int[] resultPayload); if (PhotonNetwork.OfflineMode || base.OwnerData?.view == null) { RPCA_BeginTackBurst(num, base.OwnerPlayer.playerID, 32f, num3, num4, HotShotsColorStacks > 0, num2, shotPayload, resultPayload); return; } base.OwnerData.view.RPC("RPCA_BeginTackBurst", (RpcTarget)0, new object[9] { num, base.OwnerPlayer.playerID, 32f, num3, num4, HotShotsColorStacks > 0, num2, shotPayload, resultPayload }); } } protected override void OnDestroy() { foreach (TackBurstController item in new List(activeBursts.Values)) { if (item != null) { Object.Destroy((Object)(object)((Component)item).gameObject); } } activeBursts.Clear(); base.OnDestroy(); } [PunRPC] private void RPCA_BeginTackBurst(int burstId, int ownerPlayerId, float speed, float flatDamage, float percentageDamage, bool useHotShotsColor, double fireTime, float[] shotPayload, int[] resultPayload) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) if (TackShotPlan.GetCount(shotPayload, resultPayload) > 0) { if (activeBursts.TryGetValue(burstId, out TackBurstController value) && value != null) { Object.Destroy((Object)(object)((Component)value).gameObject); activeBursts.Remove(burstId); } TackBurstController tackBurstController = new GameObject($"DOLY_TackBurst_{ownerPlayerId}_{burstId}").AddComponent(); tackBurstController.Configure(this, burstId, ownerPlayerId, speed, flatDamage, percentageDamage, useHotShotsColor ? HotShotsTackColor : DefaultTackColor, fireTime, shotPayload, resultPayload); activeBursts[burstId] = tackBurstController; } } internal void NotifyBurstFinished(int burstId, TackBurstController burst) { if (activeBursts.TryGetValue(burstId, out TackBurstController value) && (Object)(object)value == (Object)(object)burst) { activeBursts.Remove(burstId); } } [PunRPC] private void RPCA_SpawnRingOfFire(int ownerPlayerId, int ownerTeamId, float centerX, float centerY, float finalRadius, float duration, float flatDamage, float percentageDamage, bool ignoreBlock, float blockPierceDamageMultiplier, bool useHotShotsColor) { //IL_0005: 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_0030: 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) new GameObject("DOLY_RingOfFireWave").AddComponent().Configure(new Vector2(centerX, centerY), finalRadius, duration, flatDamage, percentageDamage, ownerPlayerId, ownerTeamId, ignoreBlock, blockPierceDamageMultiplier, useHotShotsColor ? HotShotsTackColor : DefaultRingOfFireColor); } private void TrySpawnRingOfFire(ProjectileHit projectileHit) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) if (base.OwnerPlayer != null && base.OwnerData?.view != null && TackCount > 0 && !(TackRange <= 0f)) { float num = TackRange * 1f; float num2 = Mathf.Max(0.05f, num / 32f); float num3 = projectileHit.damage * 0.5f * TackDamageMultiplier; float num4 = projectileHit.percentageDamage * 0.5f * TackDamageMultiplier + (float)TackCount * 0.003f; Vector3 position = ((Component)base.OwnerPlayer).transform.position; base.OwnerData.view.RPC("RPCA_SpawnRingOfFire", (RpcTarget)0, new object[11] { base.OwnerPlayer.playerID, base.OwnerPlayer.teamID, position.x, position.y, num, num2, num3, num4, UnblockableStacks > 0, BlockPierceDamageMultiplier, HotShotsColorStacks > 0 }); } } internal void ApplyPlannedImpact(int ownerPlayerId, float flatDamage, float percentageDamage, TackShotPlan plan) { ApplyPlannedImpactInternal(ownerPlayerId, flatDamage, percentageDamage, plan); } private float CalculateSpawnDistance(GameObject sourceProjectile, Vector2 direction) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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) //IL_0052: Unknown result type (might be due to invalid IL or missing references) Vector2 val = Vector2.op_Implicit(((Component)base.OwnerPlayer).transform.position); float num = 0.75f; if (TryGetCombinedBounds(((Component)base.OwnerPlayer).gameObject, out var combinedBounds)) { num = Mathf.Max(num, GetBoundsDistanceAlongDirection(combinedBounds, val, direction) + 0.2f); } if (TryGetCombinedBounds(sourceProjectile, out var combinedBounds2)) { return Mathf.Max(num, GetBoundsDistanceAlongDirection(combinedBounds2, val, direction) + 0.2f); } return Mathf.Max(num, Vector2.Dot(Vector2.op_Implicit(sourceProjectile.transform.position) - val, direction) + 0.2f); } private static Vector2 ResolveSourceForward(GameObject projectile) { //IL_0006: 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_0010: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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) Vector2 val = Vector2.op_Implicit(projectile.transform.forward); if (((Vector2)(ref val)).sqrMagnitude > 0.0001f) { return ((Vector2)(ref val)).normalized; } MoveTransform component = projectile.GetComponent(); if (component != null && ((Vector3)(ref component.velocity)).sqrMagnitude > 0.0001f) { Vector2 val2 = Vector2.op_Implicit(component.velocity); return ((Vector2)(ref val2)).normalized; } return Vector2.right; } private void BuildTackShotPayload(GameObject sourceProjectile, Vector2 forward, float range, bool ignoreBlock, int worldMask, int playerMask, out float[] shotPayload, out int[] resultPayload) { //IL_002c: 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_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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) shotPayload = new float[TackCount * 9]; resultPayload = new int[TackCount * 3]; Vector2 val = Vector2.op_Implicit(((Component)base.OwnerPlayer).transform.position); float num = Mathf.Atan2(forward.y, forward.x) * 57.29578f; float num2 = 360f / (float)TackCount; for (int i = 0; i < TackCount; i++) { float num3 = num + num2 * (float)i; Vector2 val2 = new Vector2(Mathf.Cos(num3 * (MathF.PI / 180f)), Mathf.Sin(num3 * (MathF.PI / 180f))); Vector2 normalized = ((Vector2)(ref val2)).normalized; float num4 = CalculateSpawnDistance(sourceProjectile, normalized); Vector2 origin = val + normalized * num4; TackBurstPlanner.PlanShot(base.OwnerPlayer, origin, normalized, range, ignoreBlock, worldMask, playerMask).WriteTo(shotPayload, resultPayload, i); } } private static void ApplyPlannedImpactInternal(int ownerPlayerId, float flatDamage, float percentageDamage, TackShotPlan plan) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) if (plan.ImpactType == TackImpactType.None || plan.ImpactType == TackImpactType.World) { return; } if (plan.ImpactType == TackImpactType.Blocked) { PlayBlockedFeedback(plan); } else { if (!TackHitResolver.TryResolveTarget(plan.ViewId, plan.ColliderId, out Collider2D collider, out Transform targetTransform)) { return; } Player val = ResolveOwnerPlayer(ownerPlayerId); object obj; if (val == null) { obj = null; } else { CharacterData data = val.data; if (data == null) { obj = null; } else { WeaponHandler weaponHandler = data.weaponHandler; if (weaponHandler == null) { obj = null; } else { Gun gun = weaponHandler.gun; obj = ((gun != null) ? ((Component)gun).gameObject : null); } } } GameObject val2 = (GameObject)obj; Vector2 direction = plan.Direction; Vector2 val3; if (!(((Vector2)(ref direction)).sqrMagnitude > 0.0001f)) { val3 = Vector2.right; } else { direction = plan.Direction; val3 = ((Vector2)(ref direction)).normalized; } Vector2 val4 = val3; if (plan.ImpactType == TackImpactType.Damagable) { Damagable val5 = ((Component)collider).GetComponentInParent() ?? ((Component)targetTransform).GetComponentInParent(); if (val5 != null && !(flatDamage <= 0f)) { val5.TakeDamage(val4 * flatDamage, plan.StopPoint, val2, val, true, true); } return; } HealthHandler val6 = ((Component)targetTransform).GetComponent() ?? ((Component)targetTransform).GetComponentInParent(); if (val6 != null) { CharacterData val7 = ((Component)val6).GetComponent() ?? ((Component)val6).GetComponentInParent(); float num = flatDamage + percentageDamage * (val7?.maxHealth ?? 0f); if (val7?.block != null && val7.block.IsBlocking()) { num *= ((val == null) ? null : ((Component)val).gameObject.GetComponent()?.BlockPierceDamageMultiplier).GetValueOrDefault(1f); } if (!(num <= 0f)) { ((Damagable)val6).TakeDamage(val4 * num, plan.StopPoint, val2, val, true, true); } } } } private static void PlayBlockedFeedback(TackShotPlan plan) { //IL_00aa: 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_004c: 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) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) if (!TackHitResolver.TryResolveTarget(plan.ViewId, plan.ColliderId, out Collider2D _, out Transform targetTransform)) { return; } Block val = ((Component)targetTransform).GetComponent() ?? ((Component)targetTransform).GetComponentInParent(); if (val != null) { if (val.blockedPart != null) { ((Component)val.blockedPart).transform.position = Vector2.op_Implicit(plan.StopPoint + Vector2.op_Implicit(((Component)val).transform.forward) * 5f); ((Component)val.blockedPart).transform.rotation = Quaternion.LookRotation(Vector2.op_Implicit(-plan.Direction * 1.5f)); val.blockedPart.Play(); } GamefeelManager.GameFeel(plan.Direction); } } private static Player? ResolveOwnerPlayer(int ownerPlayerId) { if (PlayerManager.instance == null || ownerPlayerId < 0) { return null; } return PlayerManager.instance.GetPlayerWithID(ownerPlayerId); } private static bool TryGetCombinedBounds(GameObject root, out Bounds combinedBounds) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) combinedBounds = default(Bounds); bool flag = false; Collider2D[] componentsInChildren = root.GetComponentsInChildren(false); foreach (Collider2D val in componentsInChildren) { if (((Behaviour)val).enabled && !val.isTrigger) { if (!flag) { combinedBounds = val.bounds; flag = true; } else { ((Bounds)(ref combinedBounds)).Encapsulate(val.bounds); } } } return flag; } private static float GetBoundsDistanceAlongDirection(Bounds bounds, Vector2 origin, Vector2 direction) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_000d: 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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) Vector2 val = Vector2.op_Implicit(((Bounds)(ref bounds)).center) - origin; float num = Mathf.Abs(direction.x) * ((Bounds)(ref bounds)).extents.x + Mathf.Abs(direction.y) * ((Bounds)(ref bounds)).extents.y; return Mathf.Max(0f, Vector2.Dot(val, direction) + num); } } internal sealed class TrapperEffect : ProjectileEffectBase { private const float MinimumDrag = 5f; private const float MaximumGravity = 0f; private const float MaximumDragMinSpeed = 0.01f; private const float MinimumLifetimeSeconds = 60f; internal int SourceCount { get; set; } internal bool IsNeutral => SourceCount <= 0; protected override void AttachToProjectile(GameObject projectile, ProjectileHit projectileHit) { if (SourceCount <= 0) { return; } MoveTransform component = projectile.GetComponent(); if (component != null) { component.allowStop = true; component.drag = Mathf.Max(component.drag, 5f); component.dragMinSpeed = Mathf.Min(component.dragMinSpeed, 0.01f); component.gravity = Mathf.Min(component.gravity, 0f); RemoveAfterSeconds component2 = projectile.GetComponent(); if (component2 != null) { component2.seconds = Mathf.Max(component2.seconds, 60f); } projectile.GetOrAddComponent().Configure(base.OwnerPlayer?.playerID ?? (-1)); projectile.GetOrAddComponent().Configure(); projectile.GetOrAddComponent().Configure(); } } } internal sealed class TrapperProjectileTag : MonoBehaviour { internal int OwnerPlayerId { get; private set; } = -1; internal void Configure(int ownerPlayerId) { OwnerPlayerId = ownerPlayerId; } } internal sealed class TrapperStationaryContact : MonoBehaviour { private const float StationarySpeedThreshold = 0.4f; private const float CheckIntervalSeconds = 0.05f; private readonly Collider2D[] overlapResults = (Collider2D[])(object)new Collider2D[8]; private MoveTransform? move; private ProjectileHit? projectileHit; private RayCastTrail? rayCastTrail; private float nextCheckTime; private bool configured; internal void Configure() { if (!configured) { configured = true; move = ((Component)this).GetComponent(); projectileHit = ((Component)this).GetComponent(); rayCastTrail = ((Component)this).GetComponent(); } } private void Update() { //IL_0074: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Expected O, but got Unknown //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: 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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) if (!configured || move == null || projectileHit == null || rayCastTrail == null || ((Vector3)(ref move.velocity)).sqrMagnitude > 0.16000001f || Time.time < nextCheckTime) { return; } nextCheckTime = Time.time + 0.05f; float num = Mathf.Max(0.05f, rayCastTrail.size); int num2 = Physics2D.OverlapCircleNonAlloc(Vector2.op_Implicit(((Component)this).transform.position), num, overlapResults, LayerMask.op_Implicit(rayCastTrail.playerMask)); Collider2D val = null; float num3 = float.PositiveInfinity; Bounds bounds; for (int i = 0; i < num2; i++) { Collider2D val2 = overlapResults[i]; if (val2 != null && !((Object)(object)((Component)val2).transform.root == (Object)(object)((Component)this).transform.root) && ((Component)val2).GetComponentInParent() != null) { bounds = val2.bounds; float num4 = Vector2.SqrMagnitude(Vector2.op_Implicit(((Bounds)(ref bounds)).ClosestPoint(((Component)this).transform.position)) - Vector2.op_Implicit(((Component)this).transform.position)); if (!(num4 >= num3)) { num3 = num4; val = val2; } } } if (val != null) { bounds = val.bounds; Vector3 val3 = ((Bounds)(ref bounds)).ClosestPoint(((Component)this).transform.position); Vector2 val4 = Vector2.op_Implicit(((Component)this).transform.position) - Vector2.op_Implicit(val3); Vector2 normal = ((Vector2)(ref val4)).normalized; if (((Vector2)(ref normal)).sqrMagnitude <= 0.0001f) { normal = Vector2.up; } ((RayHit)projectileHit).Hit(new HitInfo { point = Vector2.op_Implicit(val3), normal = normal, collider = val, rigidbody = val.attachedRigidbody, transform = ((Component)val).transform.root }, false); } } } internal sealed class TrapperVisualIndicator : MonoBehaviour { private sealed class OverlaySpriteState { internal SpriteRenderer? Source; internal SpriteRenderer? Overlay; } private const int SegmentCount = 28; private const float VisibleSpeedThreshold = 3f; private static Material? sharedSpriteMaterial; private static Material? sharedLineMaterial; private readonly List overlaySprites = new List(); private LineRenderer? outlineFallback; private MoveTransform? move; private Renderer[] renderers = Array.Empty(); private bool configured; internal void Configure() { if (!configured) { configured = true; move = ((Component)this).GetComponent(); renderers = ((Component)this).GetComponentsInChildren(false); CreateSpriteOverlays(); EnsureOutlineFallback(); UpdateVisibility(forceRefresh: true); } } private void LateUpdate() { if (configured) { UpdateVisibility(forceRefresh: false); } } private void UpdateVisibility(bool forceRefresh) { bool flag = move != null && ((Vector3)(ref move.velocity)).magnitude <= 3f; for (int i = 0; i < overlaySprites.Count; i++) { OverlaySpriteState overlaySpriteState = overlaySprites[i]; if (overlaySpriteState.Source != null && overlaySpriteState.Overlay != null) { if (forceRefresh) { CopySpriteRenderer(overlaySpriteState.Source, overlaySpriteState.Overlay); } ((Renderer)overlaySpriteState.Overlay).enabled = flag; } } if (outlineFallback != null) { bool flag2 = flag && overlaySprites.Count == 0; ((Renderer)outlineFallback).enabled = flag2; if (flag2) { UpdateOutlineFallback(); } } } private void CreateSpriteOverlays() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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) SpriteRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren(false); foreach (SpriteRenderer val in componentsInChildren) { if (!((Object)((Component)val).gameObject).name.StartsWith("DOLY_TrapperOverlay_")) { GameObject val2 = new GameObject("DOLY_TrapperOverlay_" + ((Object)((Component)val).gameObject).name); val2.transform.SetParent(((Component)val).transform.parent, false); val2.transform.localPosition = ((Component)val).transform.localPosition; val2.transform.localRotation = ((Component)val).transform.localRotation; val2.transform.localScale = ((Component)val).transform.localScale; SpriteRenderer val3 = val2.AddComponent(); CopySpriteRenderer(val, val3); ((Renderer)val3).enabled = false; overlaySprites.Add(new OverlaySpriteState { Source = val, Overlay = val3 }); } } } private void CopySpriteRenderer(SpriteRenderer source, SpriteRenderer overlay) { //IL_0024: 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_004d: 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_0065: 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) if (sharedSpriteMaterial == null) { sharedSpriteMaterial = CreateMaterial("Sprites/Default"); } overlay.sprite = source.sprite; overlay.color = ResolveOverlayColor(source.color); overlay.flipX = source.flipX; overlay.flipY = source.flipY; overlay.drawMode = source.drawMode; overlay.size = source.size; overlay.maskInteraction = source.maskInteraction; overlay.spriteSortPoint = source.spriteSortPoint; ((Renderer)overlay).sortingLayerID = ((Renderer)source).sortingLayerID; ((Renderer)overlay).sortingOrder = ((Renderer)source).sortingOrder + 1; ((Renderer)overlay).sharedMaterial = sharedSpriteMaterial ?? ((Renderer)source).sharedMaterial; } private void EnsureOutlineFallback() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown if (outlineFallback == null) { GameObject val = new GameObject("DOLY_TrapperOutline"); val.transform.SetParent(((Component)this).transform, false); outlineFallback = val.AddComponent(); if (sharedLineMaterial == null) { sharedLineMaterial = CreateMaterial("Sprites/Default") ?? CreateMaterial("Unlit/Color"); } if (sharedLineMaterial != null) { ((Renderer)outlineFallback).material = sharedLineMaterial; } outlineFallback.useWorldSpace = true; outlineFallback.loop = true; outlineFallback.positionCount = 28; outlineFallback.widthMultiplier = 0.08f; outlineFallback.numCapVertices = 6; outlineFallback.numCornerVertices = 6; ((Renderer)outlineFallback).sortingOrder = 1000; ((Renderer)outlineFallback).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)outlineFallback).receiveShadows = false; ((Renderer)outlineFallback).allowOcclusionWhenDynamic = false; ((Renderer)outlineFallback).enabled = false; } } private void UpdateOutlineFallback() { //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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) if (outlineFallback != null) { Color val = ResolveFallbackColor(); outlineFallback.startColor = val; outlineFallback.endColor = val; float num = ResolveWorldRadius(); outlineFallback.widthMultiplier = Mathf.Max(0.03f, num * 0.12f); Vector3 position = ((Component)this).transform.position; for (int i = 0; i < 28; i++) { float num2 = (float)i / 28f * MathF.PI * 2f; Vector3 val2 = position + new Vector3(Mathf.Cos(num2), Mathf.Sin(num2), 0f) * num; outlineFallback.SetPosition(i, val2); } } } private float ResolveWorldRadius() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) float num = 0.2f; for (int i = 0; i < renderers.Length; i++) { Renderer val = renderers[i]; if (val != null && (outlineFallback == null || !((Object)(object)((Component)val).gameObject == (Object)(object)((Component)outlineFallback).gameObject)) && !(val is TrailRenderer) && !(val is LineRenderer)) { Bounds bounds = val.bounds; Vector3 extents = ((Bounds)(ref bounds)).extents; num = Mathf.Max(new float[3] { num, extents.x, extents.y }); } } return num; } private Color ResolveFallbackColor() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_003c: 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) ProjectileHit component = ((Component)this).GetComponent(); if (component != null && component.projectileColor.a > 0f) { return ResolveOverlayColor(component.projectileColor); } SpriteRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren(false); int num = 0; if (num < componentsInChildren.Length) { return ResolveOverlayColor(componentsInChildren[num].color); } return new Color(1f, 0.92f, 0.4f, 0.95f); } private static Color ResolveOverlayColor(Color source) { //IL_0002: 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) source.a = Mathf.Max(source.a, 0.95f); return source; } private static Material? CreateMaterial(string shaderName) { //IL_000d: 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_001b: Expected O, but got Unknown Shader val = Shader.Find(shaderName); if (val == null) { return null; } return new Material(val) { hideFlags = (HideFlags)61 }; } } internal sealed class WallTouchHazardEffect : MonoBehaviour { private const float DamageFractionPerTrigger = 0.1f; private const float TriggerCooldownSeconds = 0.2f; private const float WallPushForce = 600f; private CharacterData? ownerData; private Player? ownerPlayer; private HealthHandler? healthHandler; private bool hooked; private float nextTriggerTime; internal int SourceCount { get; set; } internal bool IsNeutral => SourceCount <= 0; private void OnEnable() { ResolveOwner(); TryHookWallTouches(); } private void Start() { ResolveOwner(); TryHookWallTouches(); } private void Update() { ResolveOwner(); TryHookWallTouches(); } private void OnDisable() { UnhookWallTouches(); } private void OnDestroy() { UnhookWallTouches(); } [PunRPC] private void RPCA_ApplyWallTouchPenalty(float positionX, float positionY, float normalX, float normalY, float damageAmount) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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_00a4: Unknown result type (might be due to invalid IL or missing references) ResolveOwner(); if (SourceCount <= 0 || ownerData == null || ownerPlayer == null || healthHandler == null || ownerData.dead) { return; } if (damageAmount > 0f) { HealthHandler? obj = healthHandler; Vector2 val = Vector2.up * damageAmount; Vector2 val2 = new Vector2(positionX, positionY); WeaponHandler weaponHandler = ownerData.weaponHandler; object obj2; if (weaponHandler == null) { obj2 = null; } else { Gun gun = weaponHandler.gun; obj2 = ((gun != null) ? ((Component)gun).gameObject : null); } ((Damagable)obj).TakeDamage(val, val2, (GameObject)obj2, ownerPlayer, true, false); } Vector2 up = default(Vector2); ((Vector2)(ref up))..ctor(normalX, normalY); if (((Vector2)(ref up)).sqrMagnitude <= 0.0001f) { up = Vector2.up; } healthHandler.TakeForce(((Vector2)(ref up)).normalized * 600f, (ForceMode2D)1, true, true, 0f); } private void HandleTouchWall(float sinceWall, Vector3 position, Vector3 normal) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) ResolveOwner(); if (SourceCount > 0 && ownerData != null && ownerPlayer != null && healthHandler != null && ownerData.view.IsMine && !ownerData.dead && !(Time.time < nextTriggerTime)) { nextTriggerTime = Time.time + 0.2f; float num = ownerData.maxHealth * 0.1f * (float)SourceCount; ownerData.view.RPC("RPCA_ApplyWallTouchPenalty", (RpcTarget)0, new object[5] { position.x, position.y, normal.x, normal.y, num }); } } private void ResolveOwner() { if (ownerData == null) { ownerData = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); } if (ownerPlayer == null) { ownerPlayer = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); } if (healthHandler == null) { healthHandler = ((Component)this).GetComponent() ?? ((Component)this).GetComponentInParent(); } } private void TryHookWallTouches() { if (!hooked && ownerData != null) { CharacterData? obj = ownerData; obj.TouchWallAction = (Action)Delegate.Combine(obj.TouchWallAction, new Action(HandleTouchWall)); hooked = true; } } private void UnhookWallTouches() { if (hooked && ownerData != null) { CharacterData? obj = ownerData; obj.TouchWallAction = (Action)Delegate.Remove(obj.TouchWallAction, new Action(HandleTouchWall)); hooked = false; } } } } namespace RoundsDolyMods.Cards { internal sealed class AdvancedConstructionCard : HelldiverClassCard { internal const string CardName = "Advanced Construction"; private const float SentryHealthBonus = 1.5f; protected override string CardTitle => "Advanced Construction"; protected override string CardDescription => "Reinforces sentries with state-of-the-art cyanoacrylate adhesives, greatly improving their durability under fire."; protected override string RarityName => "Exotic"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HelldiverClassCard.RegisterHelldiverCard(cardInfo); cardInfo.allowMultiple = true; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.GetOrAddHelldiverEffect(player).SentryHealthUpgradeCount++; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.SentryHealthUpgradeCount = Mathf.Max(0, component.SentryHealthUpgradeCount - 1); HelldiverClassCard.CleanupHelldiverEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[1] { CardStats.Positive("Sentry HP", $"+{150f:0}%") }; } } internal sealed class AegisSmiteCard : HolySmiteClassCard { private const float DelayMultiplier = 0.8f; internal const string CardName = "Aegis Smite"; protected override string CardTitle => "Aegis Smite"; protected override string CardDescription => "God protects those below."; protected override string RarityName => "Rare"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HolySmiteClassCard.RegisterHolySmiteCard(cardInfo); statModifiers.health = 1.3f; cardInfo.allowMultiple = true; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect orAddHolySmiteEffect = HolySmiteClassCard.GetOrAddHolySmiteEffect(player); orAddHolySmiteEffect.DamageTakenMultiplierWhenNotReady *= 0.5f; orAddHolySmiteEffect.AdditionalCooldownSeconds += 4f; orAddHolySmiteEffect.DelayMultiplier *= 0.8f; HolySmiteClassCard.RefreshHolySmiteStyle(orAddHolySmiteEffect, data); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.DamageTakenMultiplierWhenNotReady /= 0.5f; component.AdditionalCooldownSeconds = Mathf.Max(0f, component.AdditionalCooldownSeconds - 4f); component.DelayMultiplier /= 0.8f; HolySmiteClassCard.RefreshHolySmiteStyle(component, data); HolySmiteClassCard.CleanupHolySmiteEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[4] { CardStats.Positive("DMG taken when Smite on CD", "-50%"), CardStats.Positive("HP", "+30%"), CardStats.Negative("Smite cooldown", "+4s"), CardStats.Positive("Smite delay", "-20%") }; } } internal sealed class AtchissonAa12Card : DolyCard { protected override string CardTitle => "Atchisson AA-12"; protected override string CardDescription => "Full Auto Shotgun"; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { gun.numberOfProjectiles = 6; gun.projectileSpeed = 1.6f; gun.ammo = 24; gun.damage = 0.3f; gun.projectileSize = -0.4f; gun.spread = 0.25f; gun.destroyBulletAfter = 0.3f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { gun.attackSpeed /= 1.25f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { gun.attackSpeed *= 1.25f; } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("ATKSPD", "+25%"), CardStats.Positive("Bullets", "+6"), CardStats.Positive("Bullet speed", "+60%"), CardStats.Positive("AMMO", "+24"), CardStats.Negative("DMG", "-70%") }; } } internal sealed class AtomicCard : DolyCard { internal const string CardName = "I AM ATOMIC"; internal const float AtomicFlatDamageBonus = 400f; private const float AtomicDamageMultiplier = 21f; private const float ChannelHealthMultiplier = 51f; protected override string CardTitle => "I AM ATOMIC"; protected override string CardDescription => "We are Shadow Garden. We lurk in the shadows, and hunt the shadows."; protected override string RarityName => "Divine"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { gun.damage = 2.5f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { AtomicEffect orAddComponent = ((Component)player).gameObject.GetOrAddComponent(); orAddComponent.EntryCount++; orAddComponent.DamageMultiplier *= 21f; orAddComponent.FlatDamageBonus += 400f; orAddComponent.ChannelHealthMultiplier *= 51f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { AtomicEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.EntryCount--; component.DamageMultiplier /= 21f; component.FlatDamageBonus -= 400f; component.ChannelHealthMultiplier /= 51f; if (component.IsNeutral) { Object.Destroy((Object)(object)component); } } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("Atomic DMG", "+2000%"), CardStats.Positive("Channel HP", "+5000%"), CardStats.Positive("DMG", "+150%"), CardStats.Neutral("Channel time", "3s"), CardStats.Negative("Cooldown", "40s") }; } } internal sealed class AutocannonSentryCard : HelldiverSentryCard { internal const string CardName = "A/AC-8 Autocannon Sentry"; protected override HelldiverStratagemType SentryType => HelldiverStratagemType.AutocannonSentry; protected override string CardTitle => "A/AC-8 Autocannon Sentry"; protected override string CardDescription => "An automated cannon turret firing anti-tank ammunition over long ranges."; protected override string RarityName => "Legendary"; protected override Rarity FallbackRarity => (Rarity)2; } internal sealed class AwDangItCard : DolyCard { internal const string CardName = "Aw Dang It"; protected override string CardTitle => "Aw Dang It"; protected override string CardDescription => "Don't gamble kids."; protected override string RarityName => "Common"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { cardInfo.allowMultiple = true; statModifiers.health = 0.9f; gun.damage = 0.9f; gun.attackSpeed = 1.1111112f; gun.ammo = -1; gun.projectileSpeed = 0.9f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { GamblecoreTracker orAddComponent = ((Component)player).gameObject.GetOrAddComponent(); if (orAddComponent.PendingAwDangItReassignCount > 0) { orAddComponent.PendingAwDangItReassignCount--; } } public override void OnReassignCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { ((Component)player).gameObject.GetOrAddComponent().PendingAwDangItReassignCount++; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { GamblecoreTracker component = ((Component)player).gameObject.GetComponent(); if (component != null && component.IsEmpty) { Object.Destroy((Object)(object)component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Negative("HP", "-10%"), CardStats.Negative("DMG", "-10%"), CardStats.Negative("ATKSPD", "-10%"), CardStats.Negative("AMMO", "-1"), CardStats.Negative("Bullet speed", "-10%") }; } } internal sealed class BeepboopCard : DolyCard { internal const string CardName = "BEEPBOOP"; protected override string CardTitle => "BEEPBOOP"; protected override string CardDescription => "01100011 01101100 01100001 01101110 01101011 01100101 01110010"; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { statModifiers.health = 2.2f; statModifiers.sizeMultiplier = 1.4f; statModifiers.movementSpeed = 1.15f; statModifiers.jump = 2f; statModifiers.gravity = 4.5f; gun.reloadTime = 0.7f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { ((Component)player).gameObject.GetOrAddComponent().AddStack(); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { BeepboopEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.RemoveStack(); if (component.IsNeutral) { Object.Destroy((Object)(object)component); } } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[6] { CardStats.Positive("HP", "+120%"), CardStats.Positive("Size", "+40%"), CardStats.Positive("Reload time", "-30%"), CardStats.Positive("Move speed", "+15%"), CardStats.Positive("Jump height", "+100%"), CardStats.Negative("Gravity", "+350%") }; } } internal sealed class BiodegradableBulletsCard : DolyCard { internal const string CardName = "Biodegradable Bullets"; private const float AttackSpeedMultiplier = 1.1f; protected override string CardTitle => "Biodegradable Bullets"; protected override string CardDescription => "Blocked bullets just disintegrate instead of reflecting."; protected override string RarityName => "Common"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { cardInfo.allowMultiple = false; statModifiers.lifeSteal = 0.1f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.ApplyAttackSpeedMultiplier(gun, 1.1f); ((Component)player).gameObject.GetOrAddComponent().SourceCount++; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.RemoveAttackSpeedMultiplier(gun, 1.1f); BiodegradableBulletsEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.SourceCount--; if (component.SourceCount <= 0) { Object.Destroy((Object)(object)component); } } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[2] { CardStats.Positive("ATKSPD", "+10%"), CardStats.Positive("Life steal", "+10%") }; } } internal sealed class BladeOfTheRuinedKingCard : DolyCard { private const float AttackSpeedMultiplier = 1.6f; protected override string CardTitle => "Blade of the Ruined King"; protected override string CardDescription => "On hit, bullets deal bonus damage equal to 18% of the target's current health."; protected override string RarityName => "Rare"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { statModifiers.lifeSteal = 0.2f; gun.ammo = 6; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.ApplyAttackSpeedMultiplier(gun, 1.6f); ((Component)player).gameObject.GetOrAddComponent().Stacks++; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.RemoveAttackSpeedMultiplier(gun, 1.6f); BladeOfTheRuinedKingEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.Stacks--; if (component.Stacks <= 0) { Object.Destroy((Object)(object)component); } } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[4] { CardStats.Positive("ATKSPD", "+60%"), CardStats.Positive("Life steal", "+20%"), CardStats.Positive("AMMO", "+6"), CardStats.Positive("Enemy HP Bullet DMG", "+18%") }; } } internal sealed class CompressedAirCard : DolyCard { internal const string CardName = "Compressed Air"; private const float AttackSpeedMultiplier = 0.8f; protected override string CardTitle => "Compressed Air"; protected override string CardDescription => "For cleaning keyboards only."; protected override string RarityName => "Common"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { gun.knockback = 100.99f; gun.gravity = 0.2f; gun.projectileSpeed = 0.6f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.ApplyAttackSpeedMultiplier(gun, 0.8f); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.RemoveAttackSpeedMultiplier(gun, 0.8f); } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[4] { CardStats.Positive("Bullet knockback", "+9999%"), CardStats.Positive("Bullet gravity", "-80%"), CardStats.Negative("Bullet speed", "-40%"), CardStats.Negative("ATKSPD", "-20%") }; } } internal sealed class ConfessionCard : HolySmiteClassCard { internal const string CardName = "Confession"; protected override string CardTitle => "Confession"; protected override string CardDescription => "The truth will set you free..."; protected override string RarityName => "Epic"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HolySmiteClassCard.RegisterHolySmiteCard(cardInfo); gun.damage = 2f; gun.projectileSpeed = 0.65f; gun.knockback = 0.5f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect orAddHolySmiteEffect = HolySmiteClassCard.GetOrAddHolySmiteEffect(player); orAddHolySmiteEffect.DamageMultiplier *= 2f; orAddHolySmiteEffect.DelayMultiplier *= 0.2f; orAddHolySmiteEffect.SizeMultiplier *= 0.2f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.DamageMultiplier /= 2f; component.DelayMultiplier /= 0.2f; component.SizeMultiplier /= 0.2f; HolySmiteClassCard.CleanupHolySmiteEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("DMG", "+100%"), CardStats.Positive("Smite DMG", "+100%"), CardStats.Positive("Smite delay", "-80%"), CardStats.Negative("Bullet speed", "-35%"), CardStats.Negative("Smite size", "-80%") }; } } internal sealed class CoughingBabyCard : DolyCard { internal const string CardName = "Coughing Baby"; private const float BonusHealth = 100f; private const float AttackSpeedMultiplier = 0.2f; private const float RecoilDelta = 10f; protected override string CardTitle => "Coughing Baby"; protected override string CardDescription => "We call this an even matchup."; protected override string RarityName => "Legendary"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { gun.slow = 0.5f; statModifiers.movementSpeed = 2f; statModifiers.jump = 1.5f; statModifiers.sizeMultiplier = 0.2f; gun.numberOfProjectiles = 50; gun.reflects = 5; gun.projectileSpeed = 2f; gun.damage = 1.7f; gun.spread = 0.45f; gun.projectileSize = -0.4f; gun.ammo = -10; gun.reloadTimeAdd = 2.5f; gun.destroyBulletAfter = 0.3f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.ApplyAttackSpeedMultiplier(gun, 0.2f); gun.bodyRecoil += 10f; data.maxHealth += 100f; data.health += 100f; ((Component)player).gameObject.GetOrAddComponent().Multiplier *= 0.1f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.RemoveAttackSpeedMultiplier(gun, 0.2f); gun.bodyRecoil -= 10f; data.maxHealth = Mathf.Max(1f, data.maxHealth - 100f); if (!data.dead) { data.health = Mathf.Max(1f, Mathf.Min(data.maxHealth, data.health - 100f)); } SelfDamageReductionEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.Multiplier /= 0.1f; if (component.IsNeutral) { Object.Destroy((Object)(object)component); } } } protected override CardInfoStat[] GetStats() { return Array.Empty(); } } internal sealed class DamageCharmCard : DolyCard { private const float BonusDamage = 20f; protected override string CardTitle => "Damage Charm"; protected override string RarityName => "Common"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { cardInfo.allowMultiple = true; gun.damage = DolyCard.ConvertFlatDamageBonusToMultiplier(gun, 20f); } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[1] { CardStats.Positive("DMG", "+20") }; } } internal sealed class DemocracyProtectsCard : HelldiverClassCard { internal const string CardName = "Democracy Protects"; protected override string CardTitle => "Democracy Protects"; protected override string CardDescription => "Democracy needs me."; protected override string RarityName => "Rare"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HelldiverClassCard.RegisterHelldiverCard(cardInfo); cardInfo.allowMultiple = false; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.ApplyFlatHealthBonus(data, 50f); ((Component)player).gameObject.GetOrAddComponent().Stacks = 1; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.RemoveFlatHealthBonus(data, 50f); DemocracyProtectsEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.Stacks = 0; if (component.Stacks <= 0) { Object.Destroy((Object)(object)component); } } } protected override CardInfoStat[] GetStats() { return HelldiverClassCard.PrependFlatHealthStat((CardInfoStat[])(object)new CardInfoStat[1] { CardStats.Positive("Fatal damage", "50% survive") }, 50f); } } internal sealed class DevilsMarkCard : HolySmiteClassCard { internal const string CardName = "Devil's Mark"; protected override string CardTitle => "Devil's Mark"; protected override string CardDescription => "Those blinded by the light... must be evil."; protected override string RarityName => "Rare"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HolySmiteClassCard.RegisterHolySmiteCard(cardInfo); statModifiers.health = 1.2f; gun.damage = 1.2f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect orAddHolySmiteEffect = HolySmiteClassCard.GetOrAddHolySmiteEffect(player); orAddHolySmiteEffect.MarkDamageMultiplier *= 2.2f; orAddHolySmiteEffect.SizeMultiplier *= 2.2f; orAddHolySmiteEffect.DamageMultiplier *= 0.4f; HolySmiteClassCard.RefreshHolySmiteStyle(orAddHolySmiteEffect, data); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.MarkDamageMultiplier /= 2.2f; component.SizeMultiplier /= 2.2f; component.DamageMultiplier /= 0.4f; HolySmiteClassCard.RefreshHolySmiteStyle(component, data); HolySmiteClassCard.CleanupHolySmiteEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("Mark DMG", "+120%"), CardStats.Positive("Smite size", "+120%"), CardStats.Positive("HP", "+20%"), CardStats.Positive("DMG", "+20%"), CardStats.Negative("Smite DMG", "-60%") }; } } internal sealed class DiscoSmiteCard : HolySmiteClassCard { private const float AdditionalDelaySeconds = 0.25f; internal const string CardName = "Disco Smite"; protected override string CardTitle => "Disco Smite"; protected override string CardDescription => "Stayin' alive is no longer an option."; protected override string RarityName => "Mythical"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HolySmiteClassCard.RegisterHolySmiteCard(cardInfo); cardInfo.allowMultiple = true; statModifiers.movementSpeed = 1.25f; statModifiers.jump = 1.15f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect orAddHolySmiteEffect = HolySmiteClassCard.GetOrAddHolySmiteEffect(player); orAddHolySmiteEffect.CooldownMultiplier *= 0.8f; orAddHolySmiteEffect.SizeMultiplier *= 0.8f; orAddHolySmiteEffect.AdditionalDelaySeconds += 0.25f; HolySmiteClassCard.RefreshHolySmiteStyle(orAddHolySmiteEffect, data); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.CooldownMultiplier /= 0.8f; component.SizeMultiplier /= 0.8f; component.AdditionalDelaySeconds = Math.Max(0f, component.AdditionalDelaySeconds - 0.25f); HolySmiteClassCard.RefreshHolySmiteStyle(component, data); HolySmiteClassCard.CleanupHolySmiteEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[6] { CardStats.Positive("Disco Smite", "Yes"), CardStats.Positive("Move speed", "+25%"), CardStats.Positive("Jump height", "+15%"), CardStats.Positive("Smite cooldown", "-20%"), CardStats.Negative("Smite size", "-20%"), CardStats.Negative("Smite delay", "+0.25s") }; } } internal sealed class DivineJudgmentCard : HolySmiteClassCard { internal const string CardName = "Divine Judgment"; protected override string CardTitle => "Divine Judgment"; protected override string CardDescription => "And on the eighth day, God said 'Bet.'"; protected override string RarityName => "Legendary"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HolySmiteClassCard.RegisterHolySmiteCard(cardInfo); statModifiers.health = 1.3f; gun.damage = 1.2f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect orAddHolySmiteEffect = HolySmiteClassCard.GetOrAddHolySmiteEffect(player); orAddHolySmiteEffect.DamageMultiplier *= 2.2f; orAddHolySmiteEffect.SizeMultiplier *= 1.9f; orAddHolySmiteEffect.DelayMultiplier *= 0.8f; HolySmiteClassCard.RefreshHolySmiteStyle(orAddHolySmiteEffect, data); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.DamageMultiplier /= 2.2f; component.SizeMultiplier /= 1.9f; component.DelayMultiplier /= 0.8f; HolySmiteClassCard.RefreshHolySmiteStyle(component, data); HolySmiteClassCard.CleanupHolySmiteEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("HP", "+30%"), CardStats.Positive("Smite DMG", "+120%"), CardStats.Positive("Smite size", "+90%"), CardStats.Positive("DMG", "+20%"), CardStats.Positive("Smite delay", "-20%") }; } } internal abstract class DolyCard : CustomCard, IToggleCardCategory { private const float DefaultProjectileBaseDamage = 55f; protected virtual string CardDescription => string.Empty; protected virtual string RarityName => "Common"; protected virtual Rarity FallbackRarity => (Rarity)0; protected virtual CardThemeColorType CardTheme => (CardThemeColorType)7; protected abstract string CardTitle { get; } protected virtual string ToggleCardCategoryPath => "Standard"; protected virtual int? ToggleCardCategoryPriority => 100; protected static void ApplyAttackSpeedMultiplier(Gun gun, float multiplier) { gun.attackSpeed /= multiplier; } protected static void RemoveAttackSpeedMultiplier(Gun gun, float multiplier) { gun.attackSpeed *= multiplier; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { } protected static float ConvertFlatDamageBonusToMultiplier(Gun gun, float bonusDamage) { float num = ResolveBaseProjectileDamage(gun); return (num + bonusDamage) / num; } private static float ResolveBaseProjectileDamage(Gun gun) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (gun.projectiles == null) { return 55f; } ProjectilesToSpawn[] projectiles = gun.projectiles; for (int i = 0; i < projectiles.Length; i++) { GameObject val = projectiles[i]?.objectToSpawn; ProjectileHit val2 = ((val != null) ? val.GetComponent() : null); if (val2 != null && val != null) { float num = Mathf.Max(0.01f, val.transform.localScale.x); return Mathf.Max(0.1f, val2.damage) * num; } } return 55f; } protected override string GetTitle() { return CardTitle; } protected override string GetDescription() { return CardDescription; } protected override GameObject? GetCardArt() { return null; } protected override Rarity GetRarity() { //IL_0007: 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) return DolyRarityHelper.Resolve(RarityName, FallbackRarity); } protected override CardThemeColorType GetTheme() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return CardTheme; } public override string GetModName() { return "DOLY"; } public ToggleCardCategoryInfo GetCardCategoryInfo() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return new ToggleCardCategoryInfo(ToggleCardCategoryPath, ToggleCardCategoryPriority); } } internal sealed class DropMagCard : DolyCard { private const int AmmoBonus = 6; private const float ReloadTimeMultiplier = 0.2f; protected override string CardTitle => "Drop Mag"; protected override string CardDescription => "Why dont you just pick it back up?"; protected override string RarityName => "Rare"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { gun.ammo = 6; gun.reloadTime = 0.2f; gun.damage = 0.9f; statModifiers.automaticReload = false; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { ((Component)player).gameObject.GetOrAddComponent().SourceCount++; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DropMagEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.SourceCount--; if (component.SourceCount <= 0) { Object.Destroy((Object)(object)component); } } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[4] { CardStats.Positive("AMMO", "+6"), CardStats.Positive("Reload time", "-80%"), CardStats.Negative("AMMO / reload", "-1"), CardStats.Negative("DMG", "-10%") }; } } internal sealed class DrumMagCard : DolyCard { private const float AttackSpeedMultiplier = 1.3f; protected override string CardTitle => "Drum Mag"; protected override string RarityName => "Rare"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { gun.ammo = 26; gun.reloadTimeAdd = 0.5f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.ApplyAttackSpeedMultiplier(gun, 1.3f); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.RemoveAttackSpeedMultiplier(gun, 1.3f); } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[3] { CardStats.Positive("AMMO", "+26"), CardStats.Positive("ATKSPD", "+30%"), CardStats.Negative("Reload time", "+0.5s") }; } } internal sealed class DuctTaped12xScopeCard : DolyCard { private const float AttackSpeedMultiplier = 0.6f; protected override string CardTitle => "Duct-Taped 12x Scope"; protected override string CardDescription => "I fired, and then I fired again. I missed both times."; protected override string RarityName => "Rare"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { gun.projectileSpeed = 5.2f; gun.damage = 1.5f; gun.spread = 0.2f; gun.ammo = -1; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.ApplyAttackSpeedMultiplier(gun, 0.6f); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.RemoveAttackSpeedMultiplier(gun, 0.6f); } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("Bullet speed", "+420%"), CardStats.Positive("DMG", "+50%"), CardStats.Negative("Spread", "+0.2"), CardStats.Negative("ATKSPD", "-40%"), CardStats.Negative("AMMO", "-1") }; } } internal sealed class Eagle500kgBombCard : HelldiverClassCard { internal const string CardName = "Eagle 500kg Bomb"; protected override string CardTitle => "Eagle 500kg Bomb"; protected override string CardDescription => "A large bomb obliterating almost any target close to impact."; protected override string RarityName => "Epic"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HelldiverClassCard.RegisterHelldiverCard(cardInfo); cardInfo.allowMultiple = false; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.ApplyFlatHealthBonus(data, 50f); HelldiverClassCard.GetOrAddHelldiverEffect(player).AddStratagem(HelldiverStratagemType.Eagle500kgBomb); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.RemoveFlatHealthBonus(data, 50f); HelldiverEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.RemoveStratagem(HelldiverStratagemType.Eagle500kgBomb); HelldiverClassCard.CleanupHelldiverEffect(component); } } protected override CardInfoStat[] GetStats() { HelldiverStratagemDefinition definition = HelldiverClassRegistry.GetDefinition(HelldiverStratagemType.Eagle500kgBomb); return HelldiverClassCard.PrependFlatHealthStat((CardInfoStat[])(object)new CardInfoStat[3] { CardStats.Neutral("Call-in time", $"{definition.CallInTimeSeconds:0.0}s"), CardStats.Neutral("Cooldown", $"{definition.CooldownSeconds:0}s"), CardStats.Neutral("Charges", $"{definition.UsesPerRound}/round") }, 50f); } } internal sealed class EagleAirstrikeCard : HelldiverClassCard { internal const string CardName = "Eagle Airstrike"; protected override string CardTitle => "Eagle Airstrike"; protected override string CardDescription => "A barrage of powerful bombardment creating a non-targeted carpet of explosions."; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HelldiverClassCard.RegisterHelldiverCard(cardInfo); cardInfo.allowMultiple = false; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.ApplyFlatHealthBonus(data, 50f); HelldiverClassCard.GetOrAddHelldiverEffect(player).AddStratagem(HelldiverStratagemType.EagleAirstrike); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.RemoveFlatHealthBonus(data, 50f); HelldiverEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.RemoveStratagem(HelldiverStratagemType.EagleAirstrike); HelldiverClassCard.CleanupHelldiverEffect(component); } } protected override CardInfoStat[] GetStats() { HelldiverStratagemDefinition definition = HelldiverClassRegistry.GetDefinition(HelldiverStratagemType.EagleAirstrike); return HelldiverClassCard.PrependFlatHealthStat((CardInfoStat[])(object)new CardInfoStat[3] { CardStats.Neutral("Call-in time", $"{definition.CallInTimeSeconds:0.0}s"), CardStats.Neutral("Cooldown", $"{definition.CooldownSeconds:0}s"), CardStats.Neutral("Charges", $"{definition.UsesPerRound}/round") }, 50f); } } internal sealed class EagleClusterBombCard : HelldiverClassCard { internal const string CardName = "Eagle Cluster Bomb"; protected override string CardTitle => "Eagle Cluster Bomb"; protected override string CardDescription => "A targeted air strike efficient at clearing smaller targets."; protected override string RarityName => "Rare"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HelldiverClassCard.RegisterHelldiverCard(cardInfo); cardInfo.allowMultiple = false; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.ApplyFlatHealthBonus(data, 50f); HelldiverClassCard.GetOrAddHelldiverEffect(player).AddStratagem(HelldiverStratagemType.EagleClusterBomb); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.RemoveFlatHealthBonus(data, 50f); HelldiverEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.RemoveStratagem(HelldiverStratagemType.EagleClusterBomb); HelldiverClassCard.CleanupHelldiverEffect(component); } } protected override CardInfoStat[] GetStats() { HelldiverStratagemDefinition definition = HelldiverClassRegistry.GetDefinition(HelldiverStratagemType.EagleClusterBomb); return HelldiverClassCard.PrependFlatHealthStat((CardInfoStat[])(object)new CardInfoStat[3] { CardStats.Neutral("Call-in time", $"{definition.CallInTimeSeconds:0.0}s"), CardStats.Neutral("Cooldown", $"{definition.CooldownSeconds:0}s"), CardStats.Neutral("Charges", $"{definition.UsesPerRound}/round") }, 50f); } } internal sealed class EagleRearmCard : HelldiverClassCard { internal const string CardName = "Eagle Rearm"; protected override string CardTitle => "Eagle Rearm"; protected override string CardDescription => "Send the Eagle back to the Super Destroyer to replenish its munitions."; protected override string RarityName => "Common"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HelldiverClassCard.RegisterHelldiverCard(cardInfo); cardInfo.allowMultiple = false; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.ApplyFlatHealthBonus(data, 50f); HelldiverClassCard.GetOrAddHelldiverEffect(player).AddStratagem(HelldiverStratagemType.EagleRearm); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.RemoveFlatHealthBonus(data, 50f); HelldiverEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.RemoveStratagem(HelldiverStratagemType.EagleRearm); HelldiverClassCard.CleanupHelldiverEffect(component); } } protected override CardInfoStat[] GetStats() { HelldiverStratagemDefinition definition = HelldiverClassRegistry.GetDefinition(HelldiverStratagemType.EagleRearm); return HelldiverClassCard.PrependFlatHealthStat((CardInfoStat[])(object)new CardInfoStat[2] { CardStats.Neutral("Call-in time", $"{definition.CallInTimeSeconds:0.0}s"), CardStats.Neutral("Rearm time", $"{definition.CooldownSeconds:0}s") }, 50f); } } internal sealed class EagleStrafingRunCard : HelldiverClassCard { internal const string CardName = "Eagle Strafing Run"; protected override string CardTitle => "Eagle Strafing Run"; protected override string CardDescription => "A strafing run of the battlefield to clear small targets, delivered almost instantly."; protected override string RarityName => "Common"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HelldiverClassCard.RegisterHelldiverCard(cardInfo); cardInfo.allowMultiple = false; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.ApplyFlatHealthBonus(data, 50f); HelldiverClassCard.GetOrAddHelldiverEffect(player).AddStratagem(HelldiverStratagemType.EagleStrafingRun); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.RemoveFlatHealthBonus(data, 50f); HelldiverEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.RemoveStratagem(HelldiverStratagemType.EagleStrafingRun); HelldiverClassCard.CleanupHelldiverEffect(component); } } protected override CardInfoStat[] GetStats() { HelldiverStratagemDefinition definition = HelldiverClassRegistry.GetDefinition(HelldiverStratagemType.EagleStrafingRun); return HelldiverClassCard.PrependFlatHealthStat((CardInfoStat[])(object)new CardInfoStat[3] { CardStats.Neutral("Call-in time", $"{definition.CallInTimeSeconds:0.0}s"), CardStats.Neutral("Cooldown", $"{definition.CooldownSeconds:0}s"), CardStats.Neutral("Charges", $"{definition.UsesPerRound}/round") }, 50f); } } internal sealed class EvenFasterShootingCard : TackShooterClassCard { protected override string CardTitle => "Even Faster Shooting"; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { TackShooterClassCard.RegisterTackShooterCard(cardInfo); gun.ammo = 6; gun.projectileSpeed = 0.9f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterClassCard.ApplyAttackSpeedBonus(gun, 1.9f); gunAmmo.reloadTimeMultiplier *= 0.7f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterClassCard.RemoveAttackSpeedBonus(gun, 1.9f); gunAmmo.reloadTimeMultiplier /= 0.7f; } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[4] { CardStats.Positive("ATKSPD", "+90%"), CardStats.Positive("AMMO", "+6"), CardStats.Positive("Reload time", "-30%"), CardStats.Negative("Bullet speed", "-10%") }; } } internal sealed class EvenMoreTacksCard : TackShooterClassCard { protected override string CardTitle => "Even More Tacks"; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { TackShooterClassCard.RegisterTackShooterCard(cardInfo); statModifiers.health = 1.3f; gun.ammo = 4; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterClassCard.GetOrAddTackEffect(player).TackCount += 8; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.TackCount -= 8; TackShooterClassCard.CleanupTackEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[3] { CardStats.Positive("HP", "+30%"), CardStats.Positive("Tacks", "+8"), CardStats.Positive("AMMO", "+4") }; } } internal sealed class ExpandedWeaponsBayCard : HelldiverClassCard { internal const string CardName = "Expanded Weapons Bay"; protected override string CardTitle => "Expanded Weapons Bay"; protected override string CardDescription => "Trims excess leg space in the cockpit, allowing the Eagle to carry additional payloads."; protected override string RarityName => "Common"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HelldiverClassCard.RegisterHelldiverCard(cardInfo); cardInfo.allowMultiple = false; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.ApplyFlatHealthBonus(data, 50f); HelldiverEffect orAddHelldiverEffect = HelldiverClassCard.GetOrAddHelldiverEffect(player); if (orAddHelldiverEffect.ExpandedWeaponsBayCount <= 0) { orAddHelldiverEffect.ExpandedWeaponsBayCount = 1; orAddHelldiverEffect.RefreshExpandedWeaponsBay(1); } } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.RemoveFlatHealthBonus(data, 50f); HelldiverEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { if (component.ExpandedWeaponsBayCount > 0) { component.ExpandedWeaponsBayCount = 0; component.RefreshExpandedWeaponsBay(-1); } HelldiverClassCard.CleanupHelldiverEffect(component); } } protected override CardInfoStat[] GetStats() { return HelldiverClassCard.PrependFlatHealthStat((CardInfoStat[])(object)new CardInfoStat[1] { CardStats.Positive("Eagle charges", "+1") }, 50f); } } internal sealed class ExtendedMagazineCard : DolyCard { private const float AttackSpeedMultiplier = 1.15f; protected override string CardTitle => "Extended Magazine"; protected override string RarityName => "Common"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { gun.ammo = 8; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.ApplyAttackSpeedMultiplier(gun, 1.15f); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.RemoveAttackSpeedMultiplier(gun, 1.15f); } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[2] { CardStats.Positive("AMMO", "+8"), CardStats.Positive("ATKSPD", "+15%") }; } } internal sealed class FasterShootingCard : TackShooterClassCard { protected override string CardTitle => "Faster Shooting"; protected override string RarityName => "Common"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { TackShooterClassCard.RegisterTackShooterCard(cardInfo); gun.ammo = 4; gun.projectileSpeed = 0.9f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterClassCard.ApplyAttackSpeedBonus(gun, 1.4f); gunAmmo.reloadTimeMultiplier *= 0.7f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterClassCard.RemoveAttackSpeedBonus(gun, 1.4f); gunAmmo.reloadTimeMultiplier /= 0.7f; } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[4] { CardStats.Positive("ATKSPD", "+40%"), CardStats.Positive("AMMO", "+4"), CardStats.Positive("Reload time", "-30%"), CardStats.Negative("Bullet speed", "-10%") }; } } internal sealed class FlamingSmiteCard : HolySmiteClassCard { private const float AdditionalDelaySeconds = 0.5f; internal const string CardName = "Flaming Smite"; protected override string CardTitle => "Flaming Smite"; protected override string CardDescription => "When staring at the sun burns, no matter how strong you are. Burns 10% Max HP per second."; protected override string RarityName => "Rare"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HolySmiteClassCard.RegisterHolySmiteCard(cardInfo); cardInfo.allowMultiple = true; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect orAddHolySmiteEffect = HolySmiteClassCard.GetOrAddHolySmiteEffect(player); orAddHolySmiteEffect.BurnMaxHealthFractionPerSecond = Mathf.Max(orAddHolySmiteEffect.BurnMaxHealthFractionPerSecond, 0.1f); orAddHolySmiteEffect.BurnDurationSeconds += 4f; orAddHolySmiteEffect.SizeMultiplier *= 1.8f; orAddHolySmiteEffect.DamageMultiplier *= 0.4f; orAddHolySmiteEffect.AdditionalCooldownSeconds += 1f; orAddHolySmiteEffect.AdditionalDelaySeconds += 0.5f; HolySmiteClassCard.RefreshHolySmiteStyle(orAddHolySmiteEffect, data); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.BurnDurationSeconds = Mathf.Max(0f, component.BurnDurationSeconds - 4f); if (component.BurnDurationSeconds <= 0f) { component.BurnDurationSeconds = 0f; component.BurnMaxHealthFractionPerSecond = 0f; } component.SizeMultiplier /= 1.8f; component.DamageMultiplier /= 0.4f; component.AdditionalCooldownSeconds = Mathf.Max(0f, component.AdditionalCooldownSeconds - 1f); component.AdditionalDelaySeconds = Mathf.Max(0f, component.AdditionalDelaySeconds - 0.5f); HolySmiteClassCard.RefreshHolySmiteStyle(component, data); HolySmiteClassCard.CleanupHolySmiteEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("Smite burn", "+4s"), CardStats.Positive("Smite size", "+80%"), CardStats.Negative("Smite DMG", "-60%"), CardStats.Negative("Smite cooldown", "+1s"), CardStats.Negative("Smite delay", "+0.5s") }; } } internal sealed class FlappyBirdCard : DolyCard { protected override string CardTitle => "Flappy Bird"; protected override string CardDescription => "Walls might hurt."; protected override string RarityName => "Rare"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { statModifiers.numberOfJumps = 42; statModifiers.jump = 1.15f; statModifiers.gravity = 0.5f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { ((Component)player).gameObject.GetOrAddComponent().SourceCount++; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { WallTouchHazardEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.SourceCount--; if (component.IsNeutral) { Object.Destroy((Object)(object)component); } } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[3] { CardStats.Positive("Jumps", "+42"), CardStats.Positive("Jump height", "+15%"), CardStats.Positive("Gravity", "-50%") }; } } internal sealed class FriendliestOfFiresCard : DolyCard { protected override string CardTitle => "Friendliest of Fires"; protected override string CardDescription => "Perhaps a hug?"; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { gun.attackSpeed = 1.25f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { ((Component)player).gameObject.GetOrAddComponent().Stacks++; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { SelfDamageReductionEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.Stacks--; if (component.IsNeutral) { Object.Destroy((Object)(object)component); } } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[2] { CardStats.Positive("Self damage", "-95%"), CardStats.Negative("ATKSPD", "-20%") }; } } internal sealed class FullSteamAheadCard : DolyCard { private const float AttackSpeedMultiplier = 1.6f; private const float RecoilDelta = -50f; protected override string CardTitle => "Full Steam Ahead"; protected override string CardDescription => "Choo Choo!"; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { gun.ammo = 4; gun.damage = 0.8f; gun.projectileSpeed = 1.3f; gun.reloadTimeAdd = 0.25f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { gun.bodyRecoil += -50f; DolyCard.ApplyAttackSpeedMultiplier(gun, 1.6f); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { gun.bodyRecoil -= -50f; DolyCard.RemoveAttackSpeedMultiplier(gun, 1.6f); } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[6] { CardStats.Positive("Recoil", "-50"), CardStats.Positive("ATKSPD", "+60%"), CardStats.Positive("Bullet speed", "+30%"), CardStats.Positive("AMMO", "+4"), CardStats.Negative("DMG", "-20%"), CardStats.Negative("Reload time", "+0.25s") }; } } internal sealed class GamblecoreCard : DolyCard { internal const string CardName = "Gamblecore"; private const float WinChance = 0.25f; protected override string CardTitle => "Gamblecore"; protected override string CardDescription => "Lets go gambling!"; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { cardInfo.allowMultiple = true; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { Player player2 = player; GamblecoreTracker orAddComponent = ((Component)player2).gameObject.GetOrAddComponent(); orAddComponent.GamblecoreCount++; if (orAddComponent.PendingReassignCount > 0) { orAddComponent.PendingReassignCount--; } else if (PhotonNetwork.OfflineMode || PhotonNetwork.IsMasterClient) { ExtensionMethods.ExecuteAfterFrames((MonoBehaviour)(object)Unbound.Instance, 1, (Action)delegate { AwardGambleResult(player2); }); } } public override void OnReassignCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { ((Component)player).gameObject.GetOrAddComponent().PendingReassignCount++; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { GamblecoreTracker component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.GamblecoreCount--; if (component.IsEmpty) { Object.Destroy((Object)(object)component); } } } protected override CardInfoStat[] GetStats() { return Array.Empty(); } private static void AwardGambleResult(Player player) { if (player != null && player.data != null && GamblecoreRegistry.AwDangItCardInfo != null && GamblecoreRegistry.ICantStopWinningCardInfo != null) { CardInfo val = ((Random.value < 0.25f) ? GamblecoreRegistry.ICantStopWinningCardInfo : GamblecoreRegistry.AwDangItCardInfo); Cards.instance.AddCardToPlayer(player, val, false, "", 0f, 0f, true); } } } internal sealed class GatlingSentryCard : HelldiverSentryCard { internal const string CardName = "A/G-16 Gatling Sentry"; protected override HelldiverStratagemType SentryType => HelldiverStratagemType.GatlingSentry; protected override string CardTitle => "A/G-16 Gatling Sentry"; protected override string CardDescription => "A heavier machine gun sentry that trades sluggish tracking for overwhelming sustained fire."; protected override string RarityName => "Rare"; protected override Rarity FallbackRarity => (Rarity)2; } internal sealed class GiantSlayerCard : DolyCard { protected override string CardTitle => "Giant Slayer"; protected override string CardDescription => "Deal bonus damage to targets with more than double your max health."; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { statModifiers.health = 0.8f; statModifiers.movementSpeed = 1.2f; statModifiers.sizeMultiplier = 0.85f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { ((Component)player).gameObject.GetOrAddComponent().Stacks++; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { GiantSlayerEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.Stacks--; if (component.Stacks <= 0) { Object.Destroy((Object)(object)component); } } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[4] { CardStats.Positive("DMG vs enemies 2x your HP", "+200%"), CardStats.Positive("Move speed", "+20%"), CardStats.Positive("Size", "-15%"), CardStats.Negative("HP", "-20%") }; } } internal sealed class GodlySmiteCard : HolySmiteClassCard { private const float AdditionalDelaySeconds = 0.25f; internal const string CardName = "Godly Smite"; protected override string CardTitle => "Godly Smite"; protected override string CardDescription => "This is what peak performance looks like."; protected override string RarityName => "Rare"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HolySmiteClassCard.RegisterHolySmiteCard(cardInfo); statModifiers.health = 1.2f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect orAddHolySmiteEffect = HolySmiteClassCard.GetOrAddHolySmiteEffect(player); orAddHolySmiteEffect.DamageMultiplier *= 1.6f; orAddHolySmiteEffect.SizeMultiplier *= 1.3f; orAddHolySmiteEffect.AdditionalDelaySeconds += 0.25f; HolySmiteClassCard.RefreshHolySmiteStyle(orAddHolySmiteEffect, data); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.DamageMultiplier /= 1.6f; component.SizeMultiplier /= 1.3f; component.AdditionalDelaySeconds = Math.Max(0f, component.AdditionalDelaySeconds - 0.25f); HolySmiteClassCard.RefreshHolySmiteStyle(component, data); HolySmiteClassCard.CleanupHolySmiteEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[4] { CardStats.Positive("HP", "+20%"), CardStats.Positive("Smite DMG", "+60%"), CardStats.Positive("Smite size", "+30%"), CardStats.Negative("Smite delay", "+0.25s") }; } } internal sealed class GreaterDamageCharmCard : DolyCard { private const float BonusDamage = 40f; protected override string CardTitle => "Greater Damage Charm"; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { cardInfo.allowMultiple = true; gun.damage = DolyCard.ConvertFlatDamageBonusToMultiplier(gun, 40f); } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[1] { CardStats.Positive("DMG", "+40") }; } } internal sealed class GreaterHealthCharmCard : DolyCard { private const float BonusHealth = 160f; protected override string CardTitle => "Greater Health Charm"; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { cardInfo.allowMultiple = true; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { data.maxHealth += 160f; data.health += 160f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { data.maxHealth = Mathf.Max(1f, data.maxHealth - 160f); if (!data.dead) { data.health = Mathf.Max(1f, Mathf.Min(data.maxHealth, data.health - 160f)); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[1] { CardStats.Positive("HP", "+160") }; } } internal sealed class GreaterSmiteCard : HolySmiteClassCard { internal const string CardName = "Greater Smite"; protected override string CardTitle => "Greater Smite"; protected override string CardDescription => "Same god, bigger mood."; protected override string RarityName => "Common"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HolySmiteClassCard.RegisterHolySmiteCard(cardInfo); gun.projectileSpeed = 0.9f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteClassCard.ApplyAttackSpeedRate(gun, 0.9f); HolySmiteEffect orAddHolySmiteEffect = HolySmiteClassCard.GetOrAddHolySmiteEffect(player); orAddHolySmiteEffect.DamageMultiplier *= 1.3f; orAddHolySmiteEffect.SizeMultiplier *= 1.1f; HolySmiteClassCard.RefreshHolySmiteStyle(orAddHolySmiteEffect, data); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteClassCard.RemoveAttackSpeedRate(gun, 0.9f); HolySmiteEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.DamageMultiplier /= 1.3f; component.SizeMultiplier /= 1.1f; HolySmiteClassCard.RefreshHolySmiteStyle(component, data); HolySmiteClassCard.CleanupHolySmiteEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[4] { CardStats.Positive("Smite DMG", "+30%"), CardStats.Positive("Smite size", "+10%"), CardStats.Negative("ATKSPD", "-10%"), CardStats.Negative("Bullet speed", "-10%") }; } } internal sealed class GrievousWoundsCard : DolyCard { protected override string CardTitle => "Grievous Wounds"; protected override string CardDescription => "Disable healing for 4 seconds when you deal damage."; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { statModifiers.health = 1.5f; gun.damage = 1.1f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { ((Component)player).gameObject.GetOrAddComponent().Stacks++; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { GrievousWoundsEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.Stacks--; if (component.Stacks <= 0) { Object.Destroy((Object)(object)component); } } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[2] { CardStats.Positive("HP", "+50%"), CardStats.Positive("DMG", "+10%") }; } } internal sealed class HealthCharmCard : DolyCard { private const float BonusHealth = 80f; protected override string CardTitle => "Health Charm"; protected override string RarityName => "Common"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { cardInfo.allowMultiple = true; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { data.maxHealth += 80f; data.health += 80f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { data.maxHealth = Mathf.Max(1f, data.maxHealth - 80f); if (!data.dead) { data.health = Mathf.Max(1f, Mathf.Min(data.maxHealth, data.health - 80f)); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[1] { CardStats.Positive("HP", "+80") }; } } internal sealed class HelldiverCard : HelldiverClassCard { internal const string CardName = "Helldiver"; protected override string CardTitle => "Helldiver"; protected override string CardDescription => "Input a stratagem code, arm it, then throw the beacon with block."; protected override string RarityName => "Scarce"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HelldiverClassCard.RegisterHelldiverEntry(cardInfo); cardInfo.allowMultiple = false; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.ApplyFlatHealthBonus(data, 50f); HelldiverEffect orAddHelldiverEffect = HelldiverClassCard.GetOrAddHelldiverEffect(player); orAddHelldiverEffect.EntryCount = 1; orAddHelldiverEffect.AddStratagem(HelldiverStratagemType.OrbitalPrecisionStrike); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.RemoveFlatHealthBonus(data, 50f); HelldiverEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.EntryCount = 0; component.RemoveStratagem(HelldiverStratagemType.OrbitalPrecisionStrike); HelldiverClassCard.CleanupHelldiverEffect(component); } } protected override CardInfoStat[] GetStats() { HelldiverStratagemDefinition definition = HelldiverClassRegistry.GetDefinition(HelldiverStratagemType.OrbitalPrecisionStrike); return HelldiverClassCard.PrependFlatHealthStat((CardInfoStat[])(object)new CardInfoStat[2] { CardStats.Neutral("Call-in time", $"{definition.CallInTimeSeconds:0.0}s"), CardStats.Neutral("Cooldown", $"{definition.CooldownSeconds:0}s") }, 50f); } } internal abstract class HelldiverClassCard : DolyCard { protected const float StandardHelldiverBonusHealth = 50f; protected override CardThemeColorType CardTheme => (CardThemeColorType)7; protected override string ToggleCardCategoryPath => "Classes/Helldiver"; protected override int? ToggleCardCategoryPriority => 30; protected static void RegisterHelldiverEntry(CardInfo cardInfo) { HelldiverClassRegistry.EntryCardInfo = cardInfo; ClassManagerBridge.RegisterEntry(cardInfo, "Helldiver"); } protected static void RegisterHelldiverCard(CardInfo cardInfo) { if (HelldiverClassRegistry.EntryCardInfo == null) { Debug.LogWarning("[DOLY] Helldiver entry card is not registered yet; class requirement was skipped."); } else { ClassManagerBridge.RegisterRequiredCard(cardInfo, "Helldiver", HelldiverClassRegistry.EntryCardInfo); } } protected static HelldiverEffect GetOrAddHelldiverEffect(Player player) { HelldiverRuntime.GetOrAdd(player); return ((Component)player).gameObject.GetOrAddComponent(); } protected static void CleanupHelldiverEffect(HelldiverEffect? effect) { if (effect != null && effect.IsEmpty) { Object.Destroy((Object)(object)effect); } } protected static void ApplyFlatHealthBonus(CharacterData data, float amount) { data.maxHealth += amount; data.health += amount; } protected static void RemoveFlatHealthBonus(CharacterData data, float amount) { data.maxHealth = Mathf.Max(1f, data.maxHealth - amount); if (!data.dead) { data.health = Mathf.Max(1f, Mathf.Min(data.maxHealth, data.health - amount)); } } protected static CardInfoStat[] PrependFlatHealthStat(CardInfoStat[] stats, float amount) { CardInfoStat[] array = (CardInfoStat[])(object)new CardInfoStat[stats.Length + 1]; array[0] = CardStats.Positive("HP", $"+{amount:0}"); for (int i = 0; i < stats.Length; i++) { array[i + 1] = stats[i]; } return array; } } internal abstract class HelldiverSentryCard : HelldiverClassCard { protected abstract HelldiverStratagemType SentryType { get; } public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HelldiverClassCard.RegisterHelldiverCard(cardInfo); cardInfo.allowMultiple = false; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.ApplyFlatHealthBonus(data, 50f); HelldiverClassCard.GetOrAddHelldiverEffect(player).AddStratagem(SentryType); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.RemoveFlatHealthBonus(data, 50f); HelldiverEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.RemoveStratagem(SentryType); HelldiverClassCard.CleanupHelldiverEffect(component); } } protected override CardInfoStat[] GetStats() { HelldiverStratagemDefinition definition = HelldiverClassRegistry.GetDefinition(SentryType); HelldiverSentryConfig helldiverSentryConfig = HelldiverSentryConfig.Get(SentryType); return HelldiverClassCard.PrependFlatHealthStat((CardInfoStat[])(object)new CardInfoStat[4] { CardStats.Neutral("Call-in time", $"{definition.CallInTimeSeconds:0.0}s"), CardStats.Neutral("Cooldown", $"{definition.CooldownSeconds:0}s"), CardStats.Neutral("HP", $"{helldiverSentryConfig.Health:0}"), CardStats.Neutral("Duration", $"{helldiverSentryConfig.LifetimeSeconds:0}s") }, 50f); } } internal sealed class HeresyCard : DolyCard { internal const string CardName = "Heresy"; protected override string CardTitle => "Heresy"; protected override string CardDescription => "Your gods abandoned you. Mine are accepting new members."; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { statModifiers.health = 0.8f; statModifiers.movementSpeed = 1.15f; statModifiers.jump = 1.1f; block.cdMultiplier = 0.7f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { ((Component)player).gameObject.GetOrAddComponent().DamageTakenMultiplier *= 0.25f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteResistanceEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.DamageTakenMultiplier /= 0.25f; if (component.IsNeutral) { Object.Destroy((Object)(object)component); } } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("Smite DMG taken", "-75%"), CardStats.Positive("Move speed", "+15%"), CardStats.Positive("Jump height", "+10%"), CardStats.Positive("Block cooldown", "-30%"), CardStats.Negative("HP", "-20%") }; } } internal sealed class HighQualityLubricantCard : HelldiverClassCard { internal const string CardName = "High-Quality Lubricant"; private const float SentryTargetingSpeedBonus = 0.5f; protected override string CardTitle => "High-Quality Lubricant"; protected override string CardDescription => "Applies the near-frictionless lubricant known as \"Super Jelly\" to sentry ring mounts."; protected override string RarityName => "Scarce"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HelldiverClassCard.RegisterHelldiverCard(cardInfo); cardInfo.allowMultiple = true; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.GetOrAddHelldiverEffect(player).SentryTargetingSpeedUpgradeCount++; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.SentryTargetingSpeedUpgradeCount = Mathf.Max(0, component.SentryTargetingSpeedUpgradeCount - 1); HelldiverClassCard.CleanupHelldiverEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[1] { CardStats.Positive("Sentry targeting speed", $"+{50f:0}%") }; } } internal sealed class HolySmiteCard : HolySmiteClassCard { internal const string CardName = "Holy Smite"; protected override string CardTitle => "Holy Smite"; protected override string CardDescription => "Call down and smite the evil with holy bullets."; protected override string RarityName => "Scarce"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HolySmiteClassCard.RegisterHolySmiteEntry(cardInfo); cardInfo.allowMultiple = false; statModifiers.health = 1.4f; gun.damage = 0.9f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect orAddHolySmiteEffect = HolySmiteClassCard.GetOrAddHolySmiteEffect(player); orAddHolySmiteEffect.EntryCount++; HolySmiteClassCard.RefreshHolySmiteStyle(orAddHolySmiteEffect, data); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.EntryCount--; HolySmiteClassCard.RefreshHolySmiteStyle(component, data); HolySmiteClassCard.CleanupHolySmiteEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[4] { CardStats.Positive("HP", "+40%"), CardStats.Negative("DMG", "-10%"), CardStats.Neutral("Smite cooldown", "5s"), CardStats.Neutral("Smite delay", "1.2s") }; } } internal abstract class HolySmiteClassCard : DolyCard { protected override string ToggleCardCategoryPath => "Classes/Holy Smite"; protected override int? ToggleCardCategoryPriority => 20; protected static void ApplyAttackSpeedRate(Gun gun, float rateMultiplier) { gun.attackSpeed /= rateMultiplier; } protected static void RemoveAttackSpeedRate(Gun gun, float rateMultiplier) { gun.attackSpeed *= rateMultiplier; } protected static void RegisterHolySmiteEntry(CardInfo cardInfo) { HolySmiteClassRegistry.EntryCardInfo = cardInfo; ClassManagerBridge.RegisterEntry(cardInfo, "Holy Smite"); } protected static void RegisterHolySmiteCard(CardInfo cardInfo) { if (HolySmiteClassRegistry.EntryCardInfo == null) { Debug.LogWarning("[DOLY] Holy Smite entry card is not registered yet; class requirement was skipped."); } else { ClassManagerBridge.RegisterRequiredCard(cardInfo, "Holy Smite", HolySmiteClassRegistry.EntryCardInfo); } } protected static HolySmiteEffect GetOrAddHolySmiteEffect(Player player) { return ((Component)player).gameObject.GetOrAddComponent(); } protected static void RefreshHolySmiteStyle(HolySmiteEffect effect, CharacterData data) { effect.RefreshStyle(data.currentCards); } protected static void CleanupHolySmiteEffect(HolySmiteEffect? effect) { if (effect != null && effect.IsEmpty) { Object.Destroy((Object)(object)effect); } } } internal sealed class HotShotsCard : TackShooterClassCard { protected override string CardTitle => "Hot Shots"; protected override string CardDescription => "Superhot tacks pierce through block!"; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { TackShooterClassCard.RegisterTackShooterCard(cardInfo); statModifiers.movementSpeed = 1.1f; block.cdAdd = 0.25f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterClassCard.ApplyAttackSpeedBonus(gun, 0.9f); TackShooterEffect orAddTackEffect = TackShooterClassCard.GetOrAddTackEffect(player); orAddTackEffect.UnblockableStacks++; orAddTackEffect.HotShotsColorStacks++; orAddTackEffect.BlockPierceDamageMultiplier *= 0.5f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterClassCard.RemoveAttackSpeedBonus(gun, 0.9f); TackShooterEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.UnblockableStacks--; component.HotShotsColorStacks--; component.BlockPierceDamageMultiplier /= 0.5f; TackShooterClassCard.CleanupTackEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[4] { CardStats.Positive("Piercing Tacks", "Yes"), CardStats.Positive("Move speed", "+10%"), CardStats.Negative("Block cooldown", "+0.25s"), CardStats.Negative("ATKSPD", "-10%") }; } } internal sealed class HydrogenBombCard : DolyCard { internal const string CardName = "Hydrogen Bomb"; private const float AttackSpeedMultiplier = 0.3f; protected override string CardTitle => "Hydrogen Bomb"; protected override string CardDescription => "vs Coughing Baby"; protected override string RarityName => "Legendary"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { gun.damage = 5.2f; gun.projectileSize = 0.69f; gun.projectileSpeed = 0.3f; gun.gravity = 0.04f; gun.knockback = 11f; gun.reloadTimeAdd = 6f; gun.unblockable = true; gun.ammo = -5; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.ApplyAttackSpeedMultiplier(gun, 0.3f); ProjectileGrowthEffect orAddComponent = ((Component)player).gameObject.GetOrAddComponent(); orAddComponent.DamageGrowthSourceCount++; orAddComponent.SizeGrowthSourceCount++; orAddComponent.BulletDamageGrowthMultiplier *= 1.69f; orAddComponent.BulletSizeGrowthMultiplier *= 5.2f; HydrogenBombEffect orAddComponent2 = ((Component)player).gameObject.GetOrAddComponent(); orAddComponent2.SplashSourceCount++; orAddComponent2.SplashRadiusMultiplier *= 1.69f; orAddComponent2.SplashDamageMultiplier *= 1.5f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.RemoveAttackSpeedMultiplier(gun, 0.3f); ProjectileGrowthEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.DamageGrowthSourceCount = Math.Max(0, component.DamageGrowthSourceCount - 1); component.SizeGrowthSourceCount = Math.Max(0, component.SizeGrowthSourceCount - 1); component.BulletDamageGrowthMultiplier /= 1.69f; component.BulletSizeGrowthMultiplier /= 5.2f; if (component.IsNeutral) { Object.Destroy((Object)(object)component); } } HydrogenBombEffect component2 = ((Component)player).gameObject.GetComponent(); if (component2 != null) { component2.SplashSourceCount = Math.Max(0, component2.SplashSourceCount - 1); component2.SplashRadiusMultiplier /= 1.69f; component2.SplashDamageMultiplier /= 1.5f; if (component2.IsNeutral) { Object.Destroy((Object)(object)component2); } } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[7] { CardStats.Positive("DMG", "+420%"), CardStats.Positive("Unblockable Bullets", "Yes"), CardStats.Positive("Bullet size growth", "+420%"), CardStats.Positive("Bullet DMG growth", "+69%"), CardStats.Negative("AMMO", "-5"), CardStats.Negative("ATKSPD", "-70%"), CardStats.Negative("Reload time", "+6s") }; } } internal sealed class ICantStopWinningCard : DolyCard { internal const string CardName = "I Can't Stop Winning"; protected override string CardTitle => "I Can't Stop Winning"; protected override string CardDescription => "99% of gamblers quit before they win big"; protected override string RarityName => "Epic"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { cardInfo.allowMultiple = true; statModifiers.health = 1.77f; gun.damage = 1.77f; gun.attackSpeed = 100f / 177f; gun.projectileSpeed = 1.77f; statModifiers.regen = 7f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("HP", "+77%"), CardStats.Positive("DMG", "+77%"), CardStats.Positive("ATKSPD", "+77%"), CardStats.Positive("Bullet speed", "+77%"), CardStats.Positive("Regen", "+7") }; } } internal sealed class LaserSentryCard : HelldiverSentryCard { internal const string CardName = "A/LAS-98 Laser Sentry"; protected override HelldiverStratagemType SentryType => HelldiverStratagemType.LaserSentry; protected override string CardTitle => "A/LAS-98 Laser Sentry"; protected override string CardDescription => "A precise automated laser turret that burns targets with a continuous beam."; protected override string RarityName => "Exotic"; protected override Rarity FallbackRarity => (Rarity)2; } internal sealed class LongRangeTacksCard : TackShooterClassCard { protected override string CardTitle => "Long Range Tacks"; protected override string RarityName => "Common"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { TackShooterClassCard.RegisterTackShooterCard(cardInfo); statModifiers.movementSpeed = 1.1f; gun.projectileSpeed = 1.1f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterClassCard.GetOrAddTackEffect(player).TackRange += 2f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.TackRange -= 2f; TackShooterClassCard.CleanupTackEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[3] { CardStats.Positive("Tack range", "+2"), CardStats.Positive("Move speed", "+10%"), CardStats.Positive("Bullet speed", "+10%") }; } } internal sealed class MachineGunSentryCard : HelldiverSentryCard { internal const string CardName = "A/MG-43 Machine Gun Sentry"; protected override HelldiverStratagemType SentryType => HelldiverStratagemType.MachineGunSentry; protected override string CardTitle => "A/MG-43 Machine Gun Sentry"; protected override string CardDescription => "An agile automated machine gun turret. Will fire at targets even if Helldivers will be caught in the crossfire."; protected override string RarityName => "Scarce"; protected override Rarity FallbackRarity => (Rarity)2; } internal sealed class Makeshift2xScopeCard : DolyCard { private const float AttackSpeedMultiplier = 0.7f; protected override string CardTitle => "Makeshift 2x Scope"; protected override string CardDescription => "I fired. I missed."; protected override string RarityName => "Common"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { gun.projectileSpeed = 2.4f; gun.damage = 1.2f; gun.spread = 0.1f; gun.ammo = -1; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.ApplyAttackSpeedMultiplier(gun, 0.7f); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.RemoveAttackSpeedMultiplier(gun, 0.7f); } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("Bullet speed", "+140%"), CardStats.Positive("DMG", "+20%"), CardStats.Negative("Spread", "+0.1"), CardStats.Negative("ATKSPD", "-30%"), CardStats.Negative("AMMO", "-1") }; } } internal sealed class MegaCard : DolyCard { protected override string CardTitle => "MEGA"; protected override string CardDescription => "Doctor... you're huge!"; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { statModifiers.sizeMultiplier = 2.5f; statModifiers.health = 3.5f; statModifiers.jump = 1.3f; statModifiers.gravity = 1.3f; gun.damage = 1.2f; gun.projectileSize = 0.5f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("Size", "+150%"), CardStats.Positive("HP", "+250%"), CardStats.Positive("DMG", "+20%"), CardStats.Positive("Jump height", "+30%"), CardStats.Negative("Gravity", "+30%") }; } } internal sealed class MightySmiteCard : HolySmiteClassCard { private const float AdditionalDelaySeconds = 0.4f; internal const string CardName = "Mighty Smite"; protected override string CardTitle => "Mighty Smite"; protected override string CardDescription => "The heavy hand of fate."; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HolySmiteClassCard.RegisterHolySmiteCard(cardInfo); } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect orAddHolySmiteEffect = HolySmiteClassCard.GetOrAddHolySmiteEffect(player); orAddHolySmiteEffect.DamageMultiplier *= 1.4f; orAddHolySmiteEffect.SizeMultiplier *= 1.4f; orAddHolySmiteEffect.AdditionalDelaySeconds += 0.4f; HolySmiteClassCard.RefreshHolySmiteStyle(orAddHolySmiteEffect, data); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.DamageMultiplier /= 1.4f; component.SizeMultiplier /= 1.4f; component.AdditionalDelaySeconds = Math.Max(0f, component.AdditionalDelaySeconds - 0.4f); HolySmiteClassCard.RefreshHolySmiteStyle(component, data); HolySmiteClassCard.CleanupHolySmiteEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[3] { CardStats.Positive("Smite DMG", "+40%"), CardStats.Positive("Smite size", "+40%"), CardStats.Negative("Smite delay", "+0.4s") }; } } internal sealed class MoreBulletForYourBulletCard : DolyCard { internal const string CardName = "More bullet for your bullet"; protected override string CardTitle => "More bullet for your bullet"; protected override string CardDescription => "One more bullet joins every shot."; protected override string RarityName => "Common"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { gun.numberOfProjectiles++; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[1] { CardStats.Positive("Bullets", "+1") }; } } internal sealed class MoreTacksCard : TackShooterClassCard { protected override string CardTitle => "More Tacks"; protected override string RarityName => "Common"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { TackShooterClassCard.RegisterTackShooterCard(cardInfo); statModifiers.health = 1.2f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterClassCard.GetOrAddTackEffect(player).TackCount += 6; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.TackCount -= 6; TackShooterClassCard.CleanupTackEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[2] { CardStats.Positive("HP", "+20%"), CardStats.Positive("Tacks", "+6") }; } } internal sealed class Orbital120mmHEBarrageCard : HelldiverClassCard { internal const string CardName = "Orbital 120mm HE Barrage"; protected override string CardTitle => "Orbital 120mm HE Barrage"; protected override string CardDescription => "A precision artillery salvo over a small area"; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HelldiverClassCard.RegisterHelldiverCard(cardInfo); cardInfo.allowMultiple = false; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.ApplyFlatHealthBonus(data, 50f); HelldiverClassCard.GetOrAddHelldiverEffect(player).AddStratagem(HelldiverStratagemType.Orbital120mmHEBarrage); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.RemoveFlatHealthBonus(data, 50f); HelldiverEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.RemoveStratagem(HelldiverStratagemType.Orbital120mmHEBarrage); HelldiverClassCard.CleanupHelldiverEffect(component); } } protected override CardInfoStat[] GetStats() { HelldiverStratagemDefinition definition = HelldiverClassRegistry.GetDefinition(HelldiverStratagemType.Orbital120mmHEBarrage); return HelldiverClassCard.PrependFlatHealthStat((CardInfoStat[])(object)new CardInfoStat[2] { CardStats.Neutral("Call-in time", $"{definition.CallInTimeSeconds:0.0}s"), CardStats.Neutral("Cooldown", $"{definition.CooldownSeconds:0}s") }, 50f); } } internal sealed class Orbital380mmHEBarrageCard : HelldiverClassCard { internal const string CardName = "Orbital 380mm HE Barrage"; protected override string CardTitle => "Orbital 380mm HE Barrage"; protected override string CardDescription => "A prolonged barrage, wreaking extended destruction over a large area."; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HelldiverClassCard.RegisterHelldiverCard(cardInfo); cardInfo.allowMultiple = false; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.ApplyFlatHealthBonus(data, 50f); HelldiverClassCard.GetOrAddHelldiverEffect(player).AddStratagem(HelldiverStratagemType.Orbital380mmHEBarrage); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.RemoveFlatHealthBonus(data, 50f); HelldiverEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.RemoveStratagem(HelldiverStratagemType.Orbital380mmHEBarrage); HelldiverClassCard.CleanupHelldiverEffect(component); } } protected override CardInfoStat[] GetStats() { HelldiverStratagemDefinition definition = HelldiverClassRegistry.GetDefinition(HelldiverStratagemType.Orbital380mmHEBarrage); return HelldiverClassCard.PrependFlatHealthStat((CardInfoStat[])(object)new CardInfoStat[2] { CardStats.Neutral("Call-in time", $"{definition.CallInTimeSeconds:0.0}s"), CardStats.Neutral("Cooldown", $"{definition.CooldownSeconds:0}s") }, 50f); } } internal sealed class OrbitalEmsStrikeCard : HelldiverClassCard { internal const string CardName = "Orbital EMS Strike"; protected override string CardTitle => "Orbital EMS Strike"; protected override string CardDescription => "A 'compliance weapon' to modify enemy behavior. The projectile stuns all targets within the strike radius."; protected override string RarityName => "Common"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HelldiverClassCard.RegisterHelldiverCard(cardInfo); cardInfo.allowMultiple = false; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.ApplyFlatHealthBonus(data, 50f); HelldiverClassCard.GetOrAddHelldiverEffect(player).AddStratagem(HelldiverStratagemType.OrbitalEmsStrike); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.RemoveFlatHealthBonus(data, 50f); HelldiverEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.RemoveStratagem(HelldiverStratagemType.OrbitalEmsStrike); HelldiverClassCard.CleanupHelldiverEffect(component); } } protected override CardInfoStat[] GetStats() { HelldiverStratagemDefinition definition = HelldiverClassRegistry.GetDefinition(HelldiverStratagemType.OrbitalEmsStrike); return HelldiverClassCard.PrependFlatHealthStat((CardInfoStat[])(object)new CardInfoStat[2] { CardStats.Neutral("Call-in time", $"{definition.CallInTimeSeconds:0.0}s"), CardStats.Neutral("Cooldown", $"{definition.CooldownSeconds:0}s") }, 50f); } } internal sealed class OrbitalGasStrikeCard : HelldiverClassCard { internal const string CardName = "Orbital Gas Strike"; protected override string CardTitle => "Orbital Gas Strike"; protected override string CardDescription => "Disperses a lingering gas cloud"; protected override string RarityName => "Rare"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HelldiverClassCard.RegisterHelldiverCard(cardInfo); cardInfo.allowMultiple = false; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.ApplyFlatHealthBonus(data, 50f); HelldiverClassCard.GetOrAddHelldiverEffect(player).AddStratagem(HelldiverStratagemType.OrbitalGasStrike); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.RemoveFlatHealthBonus(data, 50f); HelldiverEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.RemoveStratagem(HelldiverStratagemType.OrbitalGasStrike); HelldiverClassCard.CleanupHelldiverEffect(component); } } protected override CardInfoStat[] GetStats() { HelldiverStratagemDefinition definition = HelldiverClassRegistry.GetDefinition(HelldiverStratagemType.OrbitalGasStrike); return HelldiverClassCard.PrependFlatHealthStat((CardInfoStat[])(object)new CardInfoStat[2] { CardStats.Neutral("Call-in time", $"{definition.CallInTimeSeconds:0.0}s"), CardStats.Neutral("Cooldown", $"{definition.CooldownSeconds:0}s") }, 50f); } } internal sealed class OrbitalGatlingBarrageCard : HelldiverClassCard { internal const string CardName = "Orbital Gatling Barrage"; protected override string CardTitle => "Orbital Gatling Barrage"; protected override string CardDescription => "A devastating barrage of 23mm rounds from above."; protected override string RarityName => "Common"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HelldiverClassCard.RegisterHelldiverCard(cardInfo); cardInfo.allowMultiple = false; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.ApplyFlatHealthBonus(data, 50f); HelldiverClassCard.GetOrAddHelldiverEffect(player).AddStratagem(HelldiverStratagemType.OrbitalGatlingBarrage); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.RemoveFlatHealthBonus(data, 50f); HelldiverEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.RemoveStratagem(HelldiverStratagemType.OrbitalGatlingBarrage); HelldiverClassCard.CleanupHelldiverEffect(component); } } protected override CardInfoStat[] GetStats() { HelldiverStratagemDefinition definition = HelldiverClassRegistry.GetDefinition(HelldiverStratagemType.OrbitalGatlingBarrage); return HelldiverClassCard.PrependFlatHealthStat((CardInfoStat[])(object)new CardInfoStat[2] { CardStats.Neutral("Call-in time", $"{definition.CallInTimeSeconds:0.0}s"), CardStats.Neutral("Cooldown", $"{definition.CooldownSeconds:0}s") }, 50f); } } internal sealed class OrbitalLaserCard : HolySmiteClassCard { private const float AdditionalDelaySeconds = 6f; private const float AdditionalCooldownSeconds = 20f; internal const string CardName = "Orbital Laser"; protected override string CardTitle => "Orbital Laser"; protected override string CardDescription => "I BRING DESTRUCTION"; protected override string RarityName => "Epic"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HolySmiteClassCard.RegisterHolySmiteCard(cardInfo); statModifiers.movementSpeed = 0.65f; gun.damage = 2f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect orAddHolySmiteEffect = HolySmiteClassCard.GetOrAddHolySmiteEffect(player); orAddHolySmiteEffect.DamageMultiplier *= 6f; orAddHolySmiteEffect.SizeMultiplier *= 6f; orAddHolySmiteEffect.AdditionalDelaySeconds += 6f; orAddHolySmiteEffect.AdditionalCooldownSeconds += 20f; HolySmiteClassCard.RefreshHolySmiteStyle(orAddHolySmiteEffect, data); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.DamageMultiplier /= 6f; component.SizeMultiplier /= 6f; component.AdditionalDelaySeconds = Math.Max(0f, component.AdditionalDelaySeconds - 6f); component.AdditionalCooldownSeconds = Math.Max(0f, component.AdditionalCooldownSeconds - 20f); HolySmiteClassCard.RefreshHolySmiteStyle(component, data); HolySmiteClassCard.CleanupHolySmiteEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[6] { CardStats.Positive("Smite DMG", "+500%"), CardStats.Positive("Smite size", "+500%"), CardStats.Positive("DMG", "+100%"), CardStats.Negative("Smite delay", "+6s"), CardStats.Negative("Smite cooldown", "+20s"), CardStats.Negative("Move speed", "-35%") }; } } internal sealed class OverdriveCard : TackShooterClassCard { protected override string CardTitle => "Overdrive"; protected override string CardDescription => "Shoots incredibly fast."; protected override string RarityName => "Epic"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { TackShooterClassCard.RegisterTackShooterCard(cardInfo); statModifiers.health = 1.3f; block.cdAdd = 0.25f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterClassCard.ApplyAttackSpeedBonus(gun, 1.8f); gunAmmo.reloadTimeMultiplier *= 0.7f; TackShooterClassCard.GetOrAddTackEffect(player).TackDamageMultiplier *= 1.4f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterClassCard.RemoveAttackSpeedBonus(gun, 1.8f); gunAmmo.reloadTimeMultiplier /= 0.7f; TackShooterEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.TackDamageMultiplier /= 1.4f; TackShooterClassCard.CleanupTackEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("HP", "+30%"), CardStats.Positive("Tack DMG", "+40%"), CardStats.Positive("ATKSPD", "+80%"), CardStats.Positive("Reload time", "-30%"), CardStats.Negative("Block cooldown", "+0.25s") }; } } internal sealed class QuakingSmiteCard : HolySmiteClassCard { internal const string CardName = "Quaking Smite"; protected override string CardTitle => "Quaking Smite"; protected override string CardDescription => "Smite can trigger on bounces. Now go do a crime."; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HolySmiteClassCard.RegisterHolySmiteCard(cardInfo); gun.reflects = 5; gun.projectileSpeed = 1.4f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect orAddHolySmiteEffect = HolySmiteClassCard.GetOrAddHolySmiteEffect(player); orAddHolySmiteEffect.AdditionalDelaySeconds += 0.75f; orAddHolySmiteEffect.AdditionalCooldownSeconds += 1f; orAddHolySmiteEffect.QuakingBounceChance += 0.3f; HolySmiteClassCard.RefreshHolySmiteStyle(orAddHolySmiteEffect, data); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.AdditionalDelaySeconds = Mathf.Max(0f, component.AdditionalDelaySeconds - 0.75f); component.AdditionalCooldownSeconds = Mathf.Max(0f, component.AdditionalCooldownSeconds - 1f); component.QuakingBounceChance = Mathf.Max(0f, component.QuakingBounceChance - 0.3f); HolySmiteClassCard.RefreshHolySmiteStyle(component, data); HolySmiteClassCard.CleanupHolySmiteEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("Bounces", "+5"), CardStats.Positive("Smite chance on bounce", "+30%"), CardStats.Positive("Bullet speed", "+40%"), CardStats.Negative("Smite delay", "+0.75s"), CardStats.Negative("Smite cooldown", "+1s") }; } } internal sealed class ReinforcementsCard : HelldiverClassCard { internal const string CardName = "Reinforcements"; protected override string CardTitle => "Reinforcements"; protected override string CardDescription => "Not today!"; protected override string RarityName => "Legendary"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HelldiverClassCard.RegisterHelldiverCard(cardInfo); cardInfo.allowMultiple = false; statModifiers.respawns = 1; } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[1] { CardStats.Positive("Revive", "+1") }; } } internal sealed class RejuvenatingSmiteCard : HolySmiteClassCard { private const float AdditionalDelaySeconds = 0.25f; internal const string CardName = "Rejuvenating Smite"; protected override string CardTitle => "Rejuvenating Smite"; protected override string CardDescription => "Your smite restores allies caught in the beam."; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HolySmiteClassCard.RegisterHolySmiteCard(cardInfo); statModifiers.health = 1.5f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect orAddHolySmiteEffect = HolySmiteClassCard.GetOrAddHolySmiteEffect(player); orAddHolySmiteEffect.RejuvenatingStackCount++; orAddHolySmiteEffect.CooldownMultiplier *= 0.7f; orAddHolySmiteEffect.AdditionalDelaySeconds += 0.25f; orAddHolySmiteEffect.DamageMultiplier *= 0.7f; HolySmiteClassCard.RefreshHolySmiteStyle(orAddHolySmiteEffect, data); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.RejuvenatingStackCount = Math.Max(0, component.RejuvenatingStackCount - 1); component.CooldownMultiplier /= 0.7f; component.AdditionalDelaySeconds = Math.Max(0f, component.AdditionalDelaySeconds - 0.25f); component.DamageMultiplier /= 0.7f; HolySmiteClassCard.RefreshHolySmiteStyle(component, data); HolySmiteClassCard.CleanupHolySmiteEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("Friendly healing from Smite", "+50%"), CardStats.Positive("HP", "+50%"), CardStats.Positive("Smite cooldown", "-30%"), CardStats.Negative("Smite delay", "+0.25s"), CardStats.Negative("Smite DMG", "-30%") }; } } internal sealed class RevelationSmiteCard : HolySmiteClassCard { private const float AdditionalDelaySeconds = 0.25f; internal const string CardName = "Revelation Smite"; protected override string CardTitle => "Revelation Smite"; protected override string CardDescription => "When one smite isn't enough to reveal the truth."; protected override string RarityName => "Epic"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HolySmiteClassCard.RegisterHolySmiteCard(cardInfo); statModifiers.health = 1.4f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect orAddHolySmiteEffect = HolySmiteClassCard.GetOrAddHolySmiteEffect(player); orAddHolySmiteEffect.DamageMultiplier *= 1.4f; orAddHolySmiteEffect.AdditionalCooldownSeconds += 2f; orAddHolySmiteEffect.AdditionalDelaySeconds += 0.25f; orAddHolySmiteEffect.AdditionalSmites += 2; HolySmiteClassCard.RefreshHolySmiteStyle(orAddHolySmiteEffect, data); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.DamageMultiplier /= 1.4f; component.AdditionalCooldownSeconds = Math.Max(0f, component.AdditionalCooldownSeconds - 2f); component.AdditionalDelaySeconds = Math.Max(0f, component.AdditionalDelaySeconds - 0.25f); component.AdditionalSmites -= 2; HolySmiteClassCard.RefreshHolySmiteStyle(component, data); HolySmiteClassCard.CleanupHolySmiteEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("Additional smites", "+2"), CardStats.Positive("Smite DMG", "+40%"), CardStats.Positive("HP", "+40%"), CardStats.Negative("Smite cooldown", "+2s"), CardStats.Negative("Smite delay", "+0.25s") }; } } internal sealed class RingOfFireCard : TackShooterClassCard { private const float AttackSpeedMultiplier = 0.85f; protected override string CardTitle => "Ring of Fire"; protected override string CardDescription => "Deadly Ring of Fire that go through walls and deal extra damage."; protected override string RarityName => "Epic"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { TackShooterClassCard.RegisterTackShooterCard(cardInfo); gun.reloadTimeAdd = 0.25f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterClassCard.ApplyAttackSpeedBonus(gun, 0.85f); TackShooterEffect orAddTackEffect = TackShooterClassCard.GetOrAddTackEffect(player); if (orAddTackEffect.RingOfFireStacks > 0) { orAddTackEffect.TackCount += 5; } orAddTackEffect.RingOfFireStacks++; orAddTackEffect.TackRange += 1f; orAddTackEffect.TackDamageMultiplier *= 2.5f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterClassCard.RemoveAttackSpeedBonus(gun, 0.85f); TackShooterEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { if (component.RingOfFireStacks > 1) { component.TackCount -= 5; } component.RingOfFireStacks--; component.TackRange -= 1f; component.TackDamageMultiplier /= 2.5f; TackShooterClassCard.CleanupTackEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("Enemy Max HP DMG / Tack", "+0.3%"), CardStats.Positive("Tack range", "+1"), CardStats.Positive("Tack DMG", "+150%"), CardStats.Negative("ATKSPD", "-15%"), CardStats.Negative("Reload time", "+0.25s") }; } } internal sealed class RocketSentryCard : HelldiverSentryCard { internal const string CardName = "A/MLS-4X Rocket Sentry"; protected override HelldiverStratagemType SentryType => HelldiverStratagemType.RocketSentry; protected override string CardTitle => "A/MLS-4X Rocket Sentry"; protected override string CardDescription => "A powerfully automated turret, effective against armored targets."; protected override string RarityName => "Exotic"; protected override Rarity FallbackRarity => (Rarity)2; } internal sealed class ScopiestScopeCard : DolyCard { private const float AttackSpeedMultiplier = 0.5f; protected override string CardTitle => "Scopiest Scope"; protected override string CardDescription => "*And then I had a popsicle.*"; protected override string RarityName => "Epic"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { gun.projectileSpeed = 4f; gun.damage = 1.6f; gun.gravity = 0.5f; gun.ammo = -1; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.ApplyAttackSpeedMultiplier(gun, 0.5f); ((Component)player).gameObject.GetOrAddComponent().SavedSpread = gun.spread; gun.spread = 0f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.RemoveAttackSpeedMultiplier(gun, 0.5f); ScopiestScopeEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { gun.spread = component.SavedSpread; Object.Destroy((Object)(object)component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[6] { CardStats.Positive("Bullet speed", "+300%"), CardStats.Positive("DMG", "+60%"), CardStats.Positive("Bullet gravity", "-50%"), CardStats.Positive("Current spread", "reset to 0"), CardStats.Negative("ATKSPD", "-50%"), CardStats.Negative("AMMO", "-1") }; } } internal sealed class ShockAbsorptionGelCard : HelldiverClassCard { internal const string CardName = "Shock Absorption Gel"; private const float SentryAmmoBonus = 0.5f; protected override string CardTitle => "Shock Absorption Gel"; protected override string CardDescription => "Lines Sentry pods with shock-absorbing hydrogel, allowing extra ammunition to be packed."; protected override string RarityName => "Scarce"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HelldiverClassCard.RegisterHelldiverCard(cardInfo); cardInfo.allowMultiple = true; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.GetOrAddHelldiverEffect(player).SentryAmmoUpgradeCount++; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.SentryAmmoUpgradeCount = Mathf.Max(0, component.SentryAmmoUpgradeCount - 1); HelldiverClassCard.CleanupHelldiverEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[1] { CardStats.Positive("Sentry ammo", $"+{50f:0}%") }; } } internal sealed class ShrinkRayCard : HolySmiteClassCard { internal const string CardName = "Shrink Ray"; protected override string CardTitle => "Shrink Ray"; protected override string CardDescription => "Pew Pew"; protected override string RarityName => "Exotic"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HolySmiteClassCard.RegisterHolySmiteCard(cardInfo); statModifiers.health = 1.4f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect orAddHolySmiteEffect = HolySmiteClassCard.GetOrAddHolySmiteEffect(player); orAddHolySmiteEffect.ShrinkSizeMultiplier *= 0.7f; orAddHolySmiteEffect.SizeMultiplier *= 1.3f; orAddHolySmiteEffect.DelayMultiplier *= 0.7f; orAddHolySmiteEffect.DamageMultiplier *= 0.8f; orAddHolySmiteEffect.AdditionalSmites--; HolySmiteClassCard.RefreshHolySmiteStyle(orAddHolySmiteEffect, data); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.ShrinkSizeMultiplier /= 0.7f; component.SizeMultiplier /= 1.3f; component.DelayMultiplier /= 0.7f; component.DamageMultiplier /= 0.8f; component.AdditionalSmites++; HolySmiteClassCard.RefreshHolySmiteStyle(component, data); HolySmiteClassCard.CleanupHolySmiteEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[6] { CardStats.Positive("HP", "+40%"), CardStats.Negative("Size on Smite", "-30%"), CardStats.Positive("Smite size", "+30%"), CardStats.Positive("Smite delay", "-30%"), CardStats.Negative("Smite DMG", "-20%"), CardStats.Negative("Additional Smite", "-1") }; } } internal sealed class SpeakOfTheDevilCard : HolySmiteClassCard { private const float AdditionalDelaySeconds = 0.66f; internal const string CardName = "Speak of the Devil"; protected override string CardTitle => "Speak of the Devil"; protected override string CardDescription => "Every Angel can lose their wings..."; protected override string RarityName => "Mythical"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HolySmiteClassCard.RegisterHolySmiteCard(cardInfo); } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect orAddHolySmiteEffect = HolySmiteClassCard.GetOrAddHolySmiteEffect(player); orAddHolySmiteEffect.AdditionalSmites += 6; orAddHolySmiteEffect.LifeStealFraction += 0.66f; orAddHolySmiteEffect.DamageMultiplier *= 7.66f; orAddHolySmiteEffect.SizeMultiplier *= 1.66f; orAddHolySmiteEffect.AdditionalDelaySeconds += 0.66f; orAddHolySmiteEffect.AdditionalCooldownSeconds += 6f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.AdditionalSmites -= 6; component.LifeStealFraction = Mathf.Max(0f, component.LifeStealFraction - 0.66f); component.DamageMultiplier /= 7.66f; component.SizeMultiplier /= 1.66f; component.AdditionalDelaySeconds = Mathf.Max(0f, component.AdditionalDelaySeconds - 0.66f); component.AdditionalCooldownSeconds = Mathf.Max(0f, component.AdditionalCooldownSeconds - 6f); HolySmiteClassCard.CleanupHolySmiteEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[6] { CardStats.Positive("Additional smites", "+6"), CardStats.Positive("Smite life steal", "+66%"), CardStats.Positive("Smite DMG", "+666%"), CardStats.Positive("Smite size", "+66%"), CardStats.Negative("Smite delay", "+0.66s"), CardStats.Negative("Smite cooldown", "+6s") }; } } internal sealed class StimsCard : HelldiverClassCard { internal const string CardName = "I NEED STIMS"; protected override string CardTitle => "I NEED STIMS"; protected override string CardDescription => "Injury? What injury!"; protected override string RarityName => "Legendary"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HelldiverClassCard.RegisterHelldiverCard(cardInfo); cardInfo.allowMultiple = false; statModifiers.health = 2f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { ((Component)player).gameObject.GetOrAddComponent().Stacks = 1; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { StimsEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.Stacks = 0; if (component.Stacks <= 0) { Object.Destroy((Object)(object)component); } } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[3] { CardStats.Positive("HP", "+100%"), CardStats.Positive("Regen on block", "+500/s for 4s"), CardStats.Neutral("Cooldown", "12s") }; } } internal sealed class StunningSmiteCard : HolySmiteClassCard { internal const string CardName = "Stunning Smite"; protected override string CardTitle => "Stunning Smite"; protected override string CardDescription => "Divine intervention, now with crowd control."; protected override string RarityName => "Exotic"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HolySmiteClassCard.RegisterHolySmiteCard(cardInfo); gun.damage = 1.2f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect orAddHolySmiteEffect = HolySmiteClassCard.GetOrAddHolySmiteEffect(player); orAddHolySmiteEffect.StunDuration += 1.5f; orAddHolySmiteEffect.SizeMultiplier *= 1.3f; orAddHolySmiteEffect.DelayMultiplier *= 0.9f; orAddHolySmiteEffect.AdditionalCooldownSeconds += 2f; HolySmiteClassCard.RefreshHolySmiteStyle(orAddHolySmiteEffect, data); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.StunDuration = Mathf.Max(0f, component.StunDuration - 1.5f); component.SizeMultiplier /= 1.3f; component.DelayMultiplier /= 0.9f; component.AdditionalCooldownSeconds = Mathf.Max(0f, component.AdditionalCooldownSeconds - 2f); HolySmiteClassCard.RefreshHolySmiteStyle(component, data); HolySmiteClassCard.CleanupHolySmiteEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("Stun duration", "+1.5s"), CardStats.Positive("Smite size", "+30%"), CardStats.Positive("Smite delay", "-10%"), CardStats.Positive("DMG", "+20%"), CardStats.Negative("Smite cooldown", "+2s") }; } } internal sealed class SuperiorDamageCharmCard : DolyCard { private const float BonusDamage = 100f; protected override string CardTitle => "Superior Damage Charm"; protected override string RarityName => "Exotic"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { cardInfo.allowMultiple = true; gun.damage = DolyCard.ConvertFlatDamageBonusToMultiplier(gun, 100f); } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[1] { CardStats.Positive("DMG", "+100") }; } } internal sealed class SuperiorHealthCharmCard : DolyCard { private const float BonusHealth = 400f; protected override string CardTitle => "Superior Health Charm"; protected override string RarityName => "Exotic"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { cardInfo.allowMultiple = true; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { data.maxHealth += 400f; data.health += 400f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { data.maxHealth = Mathf.Max(1f, data.maxHealth - 400f); if (!data.dead) { data.health = Mathf.Max(1f, Mathf.Min(data.maxHealth, data.health - 400f)); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[1] { CardStats.Positive("HP", "+400") }; } } internal sealed class SuperRangeTacksCard : TackShooterClassCard { protected override string CardTitle => "Super Range Tacks"; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { TackShooterClassCard.RegisterTackShooterCard(cardInfo); statModifiers.movementSpeed = 1.1f; gun.projectileSpeed = 1.2f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterClassCard.GetOrAddTackEffect(player).TackRange += 3f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.TackRange -= 3f; TackShooterClassCard.CleanupTackEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[3] { CardStats.Positive("Tack range", "+3"), CardStats.Positive("Move speed", "+10%"), CardStats.Positive("Bullet speed", "+20%") }; } } internal sealed class SuppressorCard : DolyCard { internal const string CardName = "Suppressor"; private const float ResetEffectiveFireDelaySeconds = 0.3f; protected override string CardTitle => "Suppressor"; protected override string CardDescription => "Convert current fire rate into raw damage and bullet speed."; protected override string RarityName => "Rare"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { ((Component)player).gameObject.GetOrAddComponent().AddSnapshot(data, gun); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { SuppressorEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.RemoveSnapshot(); if (component.IsEmpty) { Object.Destroy((Object)(object)component); } } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[4] { CardStats.Neutral("ATKSPD", "reset"), CardStats.Positive("DMG", "Scaling"), CardStats.Positive("Bullet speed", "Scaling"), CardStats.Positive("Bullet spread", "-80%") }; } } internal sealed class SupremeDamageCharmCard : DolyCard { private const float BonusDamage = 200f; protected override string CardTitle => "Supreme Damage Charm"; protected override string RarityName => "Mythical"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { cardInfo.allowMultiple = true; gun.damage = DolyCard.ConvertFlatDamageBonusToMultiplier(gun, 200f); } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[1] { CardStats.Positive("DMG", "+200") }; } } internal sealed class SupremeHealthCharmCard : DolyCard { private const float BonusHealth = 1500f; protected override string CardTitle => "Supreme Health Charm"; protected override string RarityName => "Mythical"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { cardInfo.allowMultiple = true; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { data.maxHealth += 1500f; data.health += 1500f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { data.maxHealth = Mathf.Max(1f, data.maxHealth - 1500f); if (!data.dead) { data.health = Mathf.Max(1f, Mathf.Min(data.maxHealth, data.health - 1500f)); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[1] { CardStats.Positive("HP", "+1500") }; } } internal sealed class TackShooterCard : TackShooterClassCard { protected override string CardTitle => "Tack Shooter"; protected override string CardDescription => "Shoots tacks in all directions!"; protected override string RarityName => "Scarce"; protected override Rarity FallbackRarity => (Rarity)0; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { TackShooterClassCard.RegisterTackShooterEntry(cardInfo); cardInfo.allowMultiple = false; gun.damage = 0.8f; gun.projectileSpeed = 0.8f; statModifiers.health = 1.8f; statModifiers.movementSpeed = 1.15f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterEffect orAddTackEffect = TackShooterClassCard.GetOrAddTackEffect(player); orAddTackEffect.TackCount += 8; orAddTackEffect.TackRange += 3f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.TackCount -= 8; component.TackRange -= 3f; TackShooterClassCard.CleanupTackEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("HP", "+80%"), CardStats.Positive("Move speed", "+15%"), CardStats.Positive("Tacks", "+8"), CardStats.Negative("DMG", "-20%"), CardStats.Negative("Bullet speed", "-20%") }; } } internal abstract class TackShooterClassCard : DolyCard { protected override string ToggleCardCategoryPath => "Classes/Tack Shooter"; protected override int? ToggleCardCategoryPriority => 10; protected static void ApplyAttackSpeedBonus(Gun gun, float multiplier) { gun.attackSpeed /= multiplier; } protected static void RemoveAttackSpeedBonus(Gun gun, float multiplier) { gun.attackSpeed *= multiplier; } protected static void RegisterTackShooterEntry(CardInfo cardInfo) { TackShooterClassRegistry.EntryCardInfo = cardInfo; ClassManagerBridge.RegisterEntry(cardInfo, "Tack Shooter"); } protected static void RegisterTackShooterCard(CardInfo cardInfo) { if (TackShooterClassRegistry.EntryCardInfo == null) { Debug.LogWarning("[DOLY] Tack Shooter entry card is not registered yet; class requirement was skipped."); } else { ClassManagerBridge.RegisterRequiredCard(cardInfo, "Tack Shooter", TackShooterClassRegistry.EntryCardInfo); } } protected static TackShooterEffect GetOrAddTackEffect(Player player) { return ((Component)player).gameObject.GetOrAddComponent(); } protected static void CleanupTackEffect(TackShooterEffect? effect) { if (effect != null && effect.IsEmpty) { Object.Destroy((Object)(object)effect); } } } internal sealed class TackSprayerCard : TackShooterClassCard { protected override string CardTitle => "Tack Sprayer"; protected override string RarityName => "Rare"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { TackShooterClassCard.RegisterTackShooterCard(cardInfo); statModifiers.health = 1.3f; gun.ammo = 10; gun.damage = 0.9f; block.cdAdd = 0.25f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterEffect orAddTackEffect = TackShooterClassCard.GetOrAddTackEffect(player); orAddTackEffect.TackCount += 10; orAddTackEffect.TackDamageMultiplier *= 1.2f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.TackCount -= 10; component.TackDamageMultiplier /= 1.2f; TackShooterClassCard.CleanupTackEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[6] { CardStats.Positive("HP", "+30%"), CardStats.Positive("Tack DMG", "+20%"), CardStats.Positive("Tacks", "+10"), CardStats.Positive("AMMO", "+10"), CardStats.Negative("Block cooldown", "+0.25s"), CardStats.Negative("DMG", "-10%") }; } } internal sealed class TargetingSoftwareUpgradeCard : HelldiverClassCard { internal const string CardName = "Targeting Software Upgrade"; protected override string CardTitle => "Targeting Software Upgrade"; protected override string CardDescription => "Increases orbital targeting speed by updating cannon targeting software to premium version."; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HelldiverClassCard.RegisterHelldiverCard(cardInfo); cardInfo.allowMultiple = false; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverClassCard.GetOrAddHelldiverEffect(player).TargetingSoftwareUpgradeCount = 1; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HelldiverEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.TargetingSoftwareUpgradeCount = 0; HelldiverClassCard.CleanupHelldiverEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[1] { CardStats.Positive("Orbital call-in time", "-60%") }; } } internal sealed class TheTackZoneCard : TackShooterClassCard { protected override string CardTitle => "The Tack Zone"; protected override string CardDescription => "Many, many tacks."; protected override string RarityName => "Legendary"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { TackShooterClassCard.RegisterTackShooterCard(cardInfo); statModifiers.health = 1.4f; gun.ammo = 8; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterClassCard.ApplyAttackSpeedBonus(gun, 1.5f); TackShooterEffect orAddTackEffect = TackShooterClassCard.GetOrAddTackEffect(player); orAddTackEffect.TackCount += 8; orAddTackEffect.TackRange += 2f; orAddTackEffect.TackDamageMultiplier *= 1.5f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { TackShooterClassCard.RemoveAttackSpeedBonus(gun, 1.5f); TackShooterEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.TackCount -= 8; component.TackRange -= 2f; component.TackDamageMultiplier /= 1.5f; TackShooterClassCard.CleanupTackEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[6] { CardStats.Positive("HP", "+40%"), CardStats.Positive("Tack DMG", "+50%"), CardStats.Positive("Tack range", "+2"), CardStats.Positive("Tacks", "+8"), CardStats.Positive("AMMO", "+8"), CardStats.Positive("ATKSPD", "+50%") }; } } internal sealed class ThunderingSmiteCard : HolySmiteClassCard { internal const string CardName = "Thundering Smite"; protected override string CardTitle => "Thundering Smite"; protected override string CardDescription => "Zeus called. He is angry."; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HolySmiteClassCard.RegisterHolySmiteCard(cardInfo); gun.projectileSpeed = 1.33f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect orAddHolySmiteEffect = HolySmiteClassCard.GetOrAddHolySmiteEffect(player); orAddHolySmiteEffect.DelayMultiplier *= 0.67f; orAddHolySmiteEffect.SizeMultiplier *= 0.67f; HolySmiteClassCard.RefreshHolySmiteStyle(orAddHolySmiteEffect, data); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.DelayMultiplier /= 0.67f; component.SizeMultiplier /= 0.67f; HolySmiteClassCard.RefreshHolySmiteStyle(component, data); HolySmiteClassCard.CleanupHolySmiteEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[3] { CardStats.Positive("Smite delay", "-33%"), CardStats.Positive("Bullet speed", "+33%"), CardStats.Negative("Smite size", "-33%") }; } } internal sealed class TrapperCard : DolyCard { private const float AttackSpeedMultiplier = 0.7f; private const float KnockbackMultiplier = 0.3f; protected override string CardTitle => "Trapper"; protected override string CardDescription => "Please walk into it"; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { gun.gravity = 0f; gun.damage = 1.8f; gun.drag = 5f; gun.dragMinSpeed = -0.99f; gun.projectileSize = 2f; gun.knockback = 0.3f; gun.destroyBulletAfter = 90f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { gun.attackSpeed /= 0.7f; ((Component)player).gameObject.GetOrAddComponent().SourceCount++; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { gun.attackSpeed *= 0.7f; TrapperEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.SourceCount--; if (component.IsNeutral) { Object.Destroy((Object)(object)component); } } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("DMG", "+80%"), CardStats.Positive("Bullet gravity", "-100%"), CardStats.Positive("Bullet drag", "+500%"), CardStats.Positive("Bullet lifetime", "90s"), CardStats.Negative("ATKSPD", "-30%") }; } } internal sealed class VampiricSmiteCard : HolySmiteClassCard { private const float AdditionalDelaySeconds = 0.25f; internal const string CardName = "Vampiric Smite"; protected override string CardTitle => "Vampiric Smite"; protected override string CardDescription => "The gods giveth, and the gods... mostly giveth back."; protected override string RarityName => "Rare"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HolySmiteClassCard.RegisterHolySmiteCard(cardInfo); statModifiers.health = 1.8f; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect orAddHolySmiteEffect = HolySmiteClassCard.GetOrAddHolySmiteEffect(player); orAddHolySmiteEffect.LifeStealFraction += 0.8f; orAddHolySmiteEffect.DamageMultiplier *= 0.9f; orAddHolySmiteEffect.SizeMultiplier *= 1.2f; orAddHolySmiteEffect.AdditionalDelaySeconds += 0.25f; HolySmiteClassCard.RefreshHolySmiteStyle(orAddHolySmiteEffect, data); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.LifeStealFraction = Mathf.Max(0f, component.LifeStealFraction - 0.8f); component.DamageMultiplier /= 0.9f; component.SizeMultiplier /= 1.2f; component.AdditionalDelaySeconds = Mathf.Max(0f, component.AdditionalDelaySeconds - 0.25f); HolySmiteClassCard.RefreshHolySmiteStyle(component, data); HolySmiteClassCard.CleanupHolySmiteEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("HP", "+80%"), CardStats.Positive("Smite life steal", "+80%"), CardStats.Positive("Smite size", "+20%"), CardStats.Negative("Smite DMG", "-10%"), CardStats.Negative("Smite delay", "+0.25s") }; } } internal sealed class Wobbly6xScopeCard : DolyCard { private const float AttackSpeedMultiplier = 0.7f; protected override string CardTitle => "Wobbly 6x Scope"; protected override string CardDescription => "So I fired again. I missed."; protected override string RarityName => "Uncommon"; protected override Rarity FallbackRarity => (Rarity)1; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { gun.projectileSpeed = 3.6f; gun.damage = 1.4f; gun.spread = 0.15f; gun.ammo = -1; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.ApplyAttackSpeedMultiplier(gun, 0.7f); } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { DolyCard.RemoveAttackSpeedMultiplier(gun, 0.7f); } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("Bullet speed", "+260%"), CardStats.Positive("DMG", "+40%"), CardStats.Negative("Spread", "+0.15"), CardStats.Negative("ATKSPD", "-30%"), CardStats.Negative("AMMO", "-1") }; } } internal sealed class ZealotsBargainCard : HolySmiteClassCard { internal const string CardName = "Zealot's Bargain"; protected override string CardTitle => "Zealot's Bargain"; protected override string CardDescription => "Faith without works is dead. Works without faith is just shooting."; protected override string RarityName => "Rare"; protected override Rarity FallbackRarity => (Rarity)2; public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block) { HolySmiteClassCard.RegisterHolySmiteCard(cardInfo); cardInfo.allowMultiple = true; gun.damage = 0.7f; gun.ammo = 8; } public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteClassCard.ApplyAttackSpeedRate(gun, 1.8f); HolySmiteEffect orAddHolySmiteEffect = HolySmiteClassCard.GetOrAddHolySmiteEffect(player); orAddHolySmiteEffect.CooldownReductionPerHit += 0.5f; orAddHolySmiteEffect.SizeMultiplier *= 0.9f; } public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats) { HolySmiteClassCard.RemoveAttackSpeedRate(gun, 1.8f); HolySmiteEffect component = ((Component)player).gameObject.GetComponent(); if (component != null) { component.CooldownReductionPerHit = Mathf.Max(0f, component.CooldownReductionPerHit - 0.5f); component.SizeMultiplier /= 0.9f; HolySmiteClassCard.CleanupHolySmiteEffect(component); } } protected override CardInfoStat[] GetStats() { return (CardInfoStat[])(object)new CardInfoStat[5] { CardStats.Positive("Smite cooldown per hit", "-0.5s"), CardStats.Positive("ATKSPD", "+80%"), CardStats.Positive("AMMO", "+8"), CardStats.Negative("Smite size", "-10%"), CardStats.Negative("DMG", "-30%") }; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }