Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of HostVeteranSurvivor v1.7.2
BepInEx/plugins/HostRoleSeries/HostRoleSelector.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETStandard,Version=v2.1")] [assembly: AssemblyVersion("1.0.0.0")] namespace HostRoleSeries; [BepInPlugin("local.bei.hostroleselector", "Host Role Selector", "1.0.0")] public sealed class RoleMenu : BaseUnityPlugin { public const string PluginId = "local.bei.hostroleselector"; private static RoleMenu instance; private readonly RoleRegistry roles = new RoleRegistry(); private ConfigEntry<KeyboardShortcut> menuKey; private ConfigEntry<string> preferred; private readonly List<InputKey> blockInputs = new List<InputKey>(); private bool open; private bool initialized; private int highlighted; private string pending; private string notice = ""; private float noticeUntil; private GUIStyle title; private GUIStyle text; private GUIStyle small; private GUIStyle button; private Texture2D pointer; private static readonly FieldInfo dead = typeof(PlayerAvatar).GetField("deadSet", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo spawned = typeof(PlayerAvatar).GetField("spawned", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo chat = typeof(ChatManager).GetField("chatActive", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo menuState = typeof(MenuManager).GetField("currentMenuState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); public static bool InputBlocked { get { if (Object.op_Implicit((Object)(object)instance)) { return instance.open; } return false; } } private void Awake() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) menuKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "RoleMenuKey", new KeyboardShortcut((KeyCode)286, Array.Empty<KeyCode>()), "Open the shared host-role menu. Arrows: select; Enter: apply; Escape: cancel."); preferred = ((BaseUnityPlugin)this).Config.Bind<string>("Selection", "SelectedRole", "", "Last selected role ID, or none. Empty selects the first installed enabled role on startup."); instance = this; } public static void Register(string id, string name, string description, int order, Func<bool> available, Action<bool> apply) { if (!Object.op_Implicit((Object)(object)instance)) { throw new InvalidOperationException("Host Role Selector is not loaded."); } instance.roles.Register(new RoleEntry(id, name, description, order, available, apply)); } public static void Unregister(string id) { if (Object.op_Implicit((Object)(object)instance)) { instance.roles.Remove(id); } } public static bool IsSelected(string id) { if (Object.op_Implicit((Object)(object)instance) && ((Behaviour)instance).isActiveAndEnabled && WorldReady()) { return instance.roles.ActiveId == id; } return false; } private static bool WorldReady() { if (Object.op_Implicit((Object)(object)GameManager.instance) && Object.op_Implicit((Object)(object)RunManager.instance) && SemiFunc.IsMasterClientOrSingleplayer() && !SemiFunc.MenuLevel() && (Object)(object)LevelGenerator.Instance != (Object)null) { return LevelGenerator.Instance.Generated; } return false; } private static bool MenuReady() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Invalid comparison between Unknown and I4 PlayerAvatar val = PlayerAvatar.instance; if (WorldReady() && Object.op_Implicit((Object)(object)val) && dead != null && spawned != null && (bool)spawned.GetValue(val) && !(bool)dead.GetValue(val) && Object.op_Implicit((Object)(object)GameDirector.instance) && (int)GameDirector.instance.currentState == 2 && (!Object.op_Implicit((Object)(object)ChatManager.instance) || chat == null || !(bool)chat.GetValue(ChatManager.instance))) { if (Object.op_Implicit((Object)(object)MenuManager.instance) && !(menuState == null)) { return (int)menuState.GetValue(MenuManager.instance) != 0; } return true; } return false; } private bool MenuPressed() { //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_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_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_0045: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = menuKey.Value; if ((int)((KeyboardShortcut)(ref value)).MainKey == 0 || !UnityInput.Current.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { if (!UnityInput.Current.GetKey(modifier)) { return false; } } return true; } private void Update() { try { if (!WorldReady()) { open = false; pending = null; roles.Select("none"); initialized = false; return; } if (!initialized) { roles.Select(roles.Initial(preferred.Value)); initialized = true; } roles.Validate(); if (!MenuReady()) { open = false; pending = null; return; } RoleEntry[] entries = roles.Entries; if (MenuPressed()) { open = !open; pending = null; highlighted = Array.FindIndex(entries, (RoleEntry e) => e.Id == roles.ActiveId) + 1; } if (!open) { return; } if (UnityInput.Current.GetKeyDown((KeyCode)27)) { open = false; pending = null; return; } if (Object.op_Implicit((Object)(object)CursorManager.instance)) { SemiFunc.CursorUnlock(0.1f); } if (Object.op_Implicit((Object)(object)CameraAim.Instance)) { CameraAim.Instance.OverrideAimStop(); } if (Object.op_Implicit((Object)(object)InputManager.instance)) { InputManager.instance.DisableControlsExcept(0.1f, blockInputs); } int num = entries.Length + 1; highlighted = Mathf.Clamp(highlighted, 0, num - 1); if (UnityInput.Current.GetKeyDown((KeyCode)276) || UnityInput.Current.GetKeyDown((KeyCode)273)) { highlighted = (highlighted + num - 1) % num; } if (UnityInput.Current.GetKeyDown((KeyCode)275) || UnityInput.Current.GetKeyDown((KeyCode)274)) { highlighted = (highlighted + 1) % num; } if (UnityInput.Current.GetKeyDown((KeyCode)8)) { pending = "none"; } if (UnityInput.Current.GetKeyDown((KeyCode)13)) { pending = ((highlighted == 0) ? "none" : entries[highlighted - 1].Id); } if (pending == null) { return; } string requested = pending; pending = null; if (!roles.Select(requested)) { notice = "This role is disabled in its config."; return; } preferred.Value = requested; if (!((BaseUnityPlugin)this).Config.SaveOnConfigSet) { ((BaseUnityPlugin)this).Config.Save(); } notice = "Role: " + ((requested == "none") ? "NONE" : Array.Find(entries, (RoleEntry e) => e.Id == requested).Name); noticeUntil = Time.unscaledTime + 4f; open = false; } catch (Exception ex) { open = false; pending = null; ((BaseUnityPlugin)this).Logger.LogError((object)("Role selection failed: " + ex)); } } private static void Fill(Rect rect, Color color) { //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_000b: Unknown result type (might be due to invalid IL or missing references) Color color2 = GUI.color; GUI.color = color; GUI.DrawTexture(rect, (Texture)(object)Texture2D.whiteTexture); GUI.color = color2; } private void OnGUI() { //IL_0532: Unknown result type (might be due to invalid IL or missing references) //IL_0538: 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) //IL_002b: 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_003e: Expected O, but got Unknown //IL_0049: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //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_008c: Expected O, but got Unknown //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_00a4: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown //IL_00c1: Expected O, but got Unknown //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_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //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_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_022f: 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_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0296: 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_0103: 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_044b: Unknown result type (might be due to invalid IL or missing references) //IL_049c: Unknown result type (might be due to invalid IL or missing references) //IL_04f7: Unknown result type (might be due to invalid IL or missing references) //IL_0507: Unknown result type (might be due to invalid IL or missing references) //IL_050c: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_0552: Unknown result type (might be due to invalid IL or missing references) //IL_0558: Invalid comparison between Unknown and I4 if (!MenuReady()) { return; } if (this.text == null) { this.text = new GUIStyle(GUI.skin.label) { fontSize = 19, wordWrap = true, richText = false }; this.text.normal.textColor = Color.white; title = new GUIStyle(this.text) { fontSize = 26, fontStyle = (FontStyle)1 }; small = new GUIStyle(this.text) { fontSize = 15 }; button = new GUIStyle(GUI.skin.button) { fontSize = 20, alignment = (TextAnchor)3, padding = new RectOffset(18, 12, 8, 8) }; } if (!open) { if (Time.unscaledTime < noticeUntil) { Fill(new Rect(22f, 22f, 460f, 55f), new Color(0.08f, 0.1f, 0.14f, 0.95f)); GUI.Label(new Rect(34f, 33f, 438f, 35f), notice, this.text); } return; } Matrix4x4 matrix = GUI.matrix; Color color = GUI.color; bool enabled = GUI.enabled; try { RoleEntry[] entries = roles.Entries; highlighted = Mathf.Clamp(highlighted, 0, entries.Length); float num = 230 + 62 * (entries.Length + 1); float num2 = Mathf.Min(1.1f, Mathf.Min((float)Screen.width / 820f, (float)Screen.height / (num + 60f))); GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one * num2); float num3 = ((float)Screen.width / num2 - 760f) / 2f; float num4 = ((float)Screen.height / num2 - num) / 2f; Fill(new Rect(num3, num4, 760f, num), new Color(0.1f, 0.12f, 0.16f, 0.98f)); Fill(new Rect(num3, num4, 760f, 58f), new Color(0.12f, 0.32f, 0.55f)); GUI.Label(new Rect(num3 + 22f, num4 + 14f, 660f, 40f), "HOST ROLES / SELECT YOUR ROLE", title); if (GUI.Button(new Rect(num3 + 702f, num4 + 12f, 40f, 34f), "X")) { open = false; pending = null; } Rect val = default(Rect); for (int i = 0; i <= entries.Length; i++) { string text = ((i == 0) ? "none" : entries[i - 1].Id); string text2 = ((i == 0) ? "NONE" : entries[i - 1].Name); bool flag = i == 0 || entries[i - 1].IsAvailable; ((Rect)(ref val))..ctor(num3 + 22f, num4 + 76f + (float)(i * 62), 716f, 52f); if (highlighted == i) { Fill(new Rect(((Rect)(ref val)).x - 4f, ((Rect)(ref val)).y - 3f, ((Rect)(ref val)).width + 8f, ((Rect)(ref val)).height + 6f), new Color(0.23f, 0.57f, 0.95f)); } GUI.enabled = enabled && flag; if (GUI.Button(val, text2 + ((text == roles.ActiveId) ? " [ACTIVE]" : "") + (flag ? "" : " [CFG OFF]"), button)) { highlighted = i; } } GUI.enabled = enabled; float num5 = num4 + 76f + (float)((entries.Length + 1) * 62); string text3 = ((highlighted == 0) ? "No host-role abilities. Stored resources are kept." : entries[Mathf.Clamp(highlighted - 1, 0, entries.Length - 1)].Description); GUI.Label(new Rect(num3 + 24f, num5 + 4f, 712f, 52f), text3, small); GUI.enabled = enabled && (highlighted == 0 || entries[highlighted - 1].IsAvailable); if (GUI.Button(new Rect(num3 + 22f, num5 + 62f, 716f, 43f), "APPLY SELECTED ROLE", button)) { pending = ((highlighted == 0) ? "none" : entries[highlighted - 1].Id); } GUI.enabled = enabled; GUI.Label(new Rect(num3 + 24f, num5 + 117f, 714f, 25f), "Arrows: select Enter: apply Backspace: none " + ((object)menuKey.Value/*cast due to .constrained prefix*/).ToString() + " / Esc: close", small); } finally { GUI.matrix = matrix; GUI.color = color; GUI.enabled = enabled; } if (open && (int)Event.current.type == 7) { DrawPointer(); } } private void DrawPointer() { //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) //IL_00a7: 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_00c4: 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_0021: Expected O, but got Unknown //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) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)pointer)) { pointer = new Texture2D(20, 28, (TextureFormat)4, false); Color[] array = (Color[])(object)new Color[560]; for (int i = 0; i < 28; i++) { for (int j = 0; j < 20; j++) { array[(27 - i) * 20 + j] = (((float)j <= (float)i * 0.6f) ? ((j > 1 && (float)j < (float)i * 0.6f - 2f) ? Color.white : Color.black) : Color.clear); } } pointer.SetPixels(array); pointer.Apply(); } Vector3 mousePosition = Input.mousePosition; GUI.DrawTexture(new Rect(mousePosition.x, (float)Screen.height - mousePosition.y, 20f, 28f), (Texture)(object)pointer); } private void OnDisable() { open = false; pending = null; roles.Select("none"); initialized = false; } private void OnDestroy() { try { roles.Select("none"); } finally { if (Object.op_Implicit((Object)(object)pointer)) { Object.Destroy((Object)(object)pointer); } if ((Object)(object)instance == (Object)(object)this) { instance = null; } } } } public sealed class RoleEntry { public string Id { get; } public string Name { get; } public string Description { get; } internal int Order { get; } internal Func<bool> Available { get; } internal Action<bool> Apply { get; } public bool IsAvailable => Available(); public RoleEntry(string id, string name, string description, int order, Func<bool> available, Action<bool> apply) { Id = id; Name = name; Description = description; Order = order; Available = available; Apply = apply; } } public sealed class RoleRegistry { public const string None = "none"; private readonly Dictionary<string, RoleEntry> entries = new Dictionary<string, RoleEntry>(); public string ActiveId { get; private set; } = "none"; public RoleEntry[] Entries => entries.Values.OrderBy((RoleEntry r) => r.Order).ThenBy<RoleEntry, string>((RoleEntry r) => r.Id, StringComparer.Ordinal).ToArray(); public void Register(RoleEntry entry) { if (entry == null || string.IsNullOrWhiteSpace(entry.Id) || entry.Id == "none" || entries.ContainsKey(entry.Id)) { throw new ArgumentException("Duplicate or invalid role registration."); } entries.Add(entry.Id, entry); } public bool Select(string id) { if (id == ActiveId) { return true; } RoleEntry value = null; if (id != "none" && (!entries.TryGetValue(id, out value) || !value.IsAvailable)) { return false; } string activeId = ActiveId; ActiveId = "none"; if (entries.TryGetValue(activeId, out var value2)) { value2.Apply(obj: false); } if (value == null) { return true; } try { ActiveId = id; value.Apply(obj: true); } catch { ActiveId = "none"; value.Apply(obj: false); throw; } return true; } public void Remove(string id) { if (ActiveId == id) { Select("none"); } entries.Remove(id); } public string Initial(string preferred) { if (preferred == "none") { return "none"; } if (preferred == null || !entries.TryGetValue(preferred, out var value)) { return Entries.FirstOrDefault((RoleEntry e) => e.IsAvailable)?.Id ?? "none"; } if (!value.IsAvailable) { return "none"; } return preferred; } public void Validate() { if (entries.TryGetValue(ActiveId, out var value) && !value.IsAvailable) { Select("none"); } } }
BepInEx/plugins/HostVeteranSurvivor/HostVeteranSurvivor.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using HostRoleSeries; using Photon.Pun; using REPOLib.Modules; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyFileVersion("1.7.2.0")] [assembly: TargetFramework(".NETStandard,Version=v2.1")] [assembly: AssemblyVersion("1.7.2.0")] namespace HostVeteranSurvivor; [BepInPlugin("local.bei.hostveteransurvivor", "Host Veteran Survivor", "1.7.2")] [BepInDependency("REPOLib", "4.2.0")] [BepInDependency("local.bei.hostroleselector", "1.0.0")] [BepInIncompatibility("local.bei.hostunarmedshotgun")] [BepInIncompatibility("local.bei.hostsurvivalbenefits")] public sealed class Plugin : BaseUnityPlugin { private sealed class FadingGun { internal GameObject Target; internal float DestroyAt; } private readonly AmmoRules ammo = new AmmoRules(); private readonly DodgeEnergyRules dodgeEnergy = new DodgeEnergyRules(); private readonly List<GameObject> dodgeEnergyBars = new List<GameObject>(); private GameObject ammoHud; private Canvas ammoCanvas; private readonly List<GameObject> ammoBars = new List<GameObject>(); private Component ammoNumber; private float nextHudAttempt; private float nextHudWarning; private readonly ControlDodgeWindow controlDodge = new ControlDodgeWindow(); private readonly DeathExplosionRules deathExplosionUses = new DeathExplosionRules(); private Item deathGrenadeItem; private GameObject deathGrenadeProxy; private object deathGrenadeStage; private object deathGrenadeRoom; private string deathGrenadeRoster; private float deathGrenadeReadyAt; private float deathGrenadeRetryAt; private bool deathExplosionPending; private PlayerAvatar deathExplosionPlayer; private Vector3 deathExplosionPosition; private float deathExplosionDeadline; private object deathExplosionStage; private object deathExplosionRoom; private ConfigEntry<bool> dodgeEnabled; private ConfigEntry<float> dodgeInvincibilitySeconds; private ConfigEntry<float> dodgeDistanceMultiplier; private ConfigEntry<KeyboardShortcut> dodgeKey; private int lastDodgeFrame = -1; private FieldInfo dodgeHealth; private FieldInfo dodgeInvincible; private FieldInfo dodgeGodMode; private FieldInfo dodgeKinematic; private FieldInfo dodgeMoveForce; private FieldInfo dodgeCanSlide; private FieldInfo dodgeSlideTimer; private FieldInfo dodgeSlideDirection; private FieldInfo dodgeSlideCurrent; private FieldInfo dodgeCrouchActive; private FieldInfo dodgeCrouchInactive; private FieldInfo dodgeSprinted; private FieldInfo dodgeRecharge; public const string PluginId = "local.bei.hostveteransurvivor"; internal const float ProxyScale = 0.0001f; internal const float MuzzleEffectSeconds = 2.5f; internal static Plugin Current; private ConfigEntry<bool> modEnabled; private ConfigEntry<int> selfDamagePerShot; private ConfigEntry<float> cooldownOverride; private ConfigEntry<float> warmupSeconds; private ConfigEntry<float> poseSeconds; private ConfigEntry<float> handForwardOffset; private ConfigEntry<float> poseLeadSeconds; private ConfigEntry<float> iconWarmupSeconds; private readonly IconWarmupGate iconGate = new IconWarmupGate(); private GameObject iconPrimer; private float nextIconNotice; private ConfigEntry<string> shotgunPrefabName; private Item shotgunItem; private ItemGun shotgunTemplate; private FieldInfo avatarDisabled; private FieldInfo avatarTumbling; private FieldInfo avatarDead; private FieldInfo avatarSpawned; private FieldInfo menuState; private FieldInfo chatActive; private FieldInfo mapActive; private FieldInfo grabCamera; private FieldInfo inputDisabled; private FieldInfo lastGrabber; private FieldInfo gunPhys; private FieldInfo disabledPosition; private readonly InteractionFireGate interactionGate = new InteractionFireGate(); private int interactionBlockedLogCount; private NativeNetwork network; private Harmony harmony; private float nextShotAt; private float nextCatalogAttempt; private bool busy; private bool remotePoseSent; private GameObject temporaryGun; private float temporaryGunDestroyAt; private readonly List<FadingGun> fadingGuns = new List<FadingGun>(); private PhysGrabber posingGrabber; private PlayerAvatar shotShooter; private PlayerAvatarRightArm posingArm; private float nextPlacementWarning; private static readonly FieldInfo bonusAvatarTumble = AccessTools.Field(typeof(PlayerAvatar), "tumble"); private static readonly FieldInfo bonusLaunch = AccessTools.Field(typeof(PlayerTumble), "tumbleLaunch"); private static readonly FieldInfo bonusJump = AccessTools.Field(typeof(PlayerController), "JumpExtra"); private static readonly FieldInfo bonusJumpRemaining = AccessTools.Field(typeof(PlayerController), "JumpExtraCurrent"); private static readonly FieldInfo bonusTumbleReady = AccessTools.Field(typeof(PlayerTumble), "setup"); private PlayerAvatar bonusPlayer; private PlayerController bonusController; private PlayerTumble bonusTumble; private string bonusSteamId; private bool bonusFailed; private PlayerAvatarVisuals suppressedLaunchVisual; private GameObject tumbleSmokeProxy; private PhysGrabObjectImpactDetector tumbleSmokeDetector; private PhysGrabObject tumbleSmokePhys; private object tumbleSmokeStage; private object tumbleSmokeRoom; private float tumbleSmokeReadyAt; private float tumbleSmokeRetryAt; private string tumbleSmokeRoster; private bool tumbleSmokeValueInitialized; private float smokeDiagnosticAt; private bool smokeHookLogged; private bool smokeSentLogged; private GameObject localSmokePrefab; private readonly SmokeTrailRules smokeTrail = new SmokeTrailRules(); private PlayerAvatar smokeTrailPlayer; private object smokeTrailStage; private Vector3 smokeTrailPosition; private ConfigEntry<int> reloadValueCost; private readonly ReloadRules reloadRules = new ReloadRules(); private bool reloadFailed; private bool reloadEffectFailed; private object reloadSession; private object reloadStage; private static readonly FieldInfo reloadHeld = AccessTools.Field(typeof(PhysGrabber), "grabbedPhysGrabObject"); private static readonly FieldInfo reloadValuable = AccessTools.Field(typeof(PhysGrabObjectImpactDetector), "valuableObject"); private static readonly FieldInfo reloadValue = AccessTools.Field(typeof(ValuableObject), "dollarValueCurrent"); private static readonly FieldInfo reloadReady = AccessTools.Field(typeof(ValuableObject), "dollarValueSet"); private static readonly MethodInfo reloadLogic = AccessTools.Method(typeof(PhysGrabObjectImpactDetector), "HealLogic", new Type[2] { typeof(float), typeof(Vector3) }, (Type[])null); private static readonly FieldInfo reloadBreakLevel = AccessTools.Field(typeof(PhysGrabObjectImpactDetector), "breakLevelLight"); private static readonly FieldInfo reloadToggleList = AccessTools.Field(typeof(PlayerExpression), "inputToggleList"); private static readonly FieldInfo reloadTogglePending = AccessTools.Field(typeof(PlayerExpression), "inputToggleListNew"); private bool RoleEnabled { get { if (((Behaviour)this).isActiveAndEnabled && modEnabled != null && modEnabled.Value) { return RoleMenu.IsSelected("local.bei.hostveteransurvivor"); } return false; } } private void UpdateAmmoContext() { if (!Object.op_Implicit((Object)(object)GameManager.instance) || !Object.op_Implicit((Object)(object)RunManager.instance) || SemiFunc.MenuLevel() || !SemiFunc.IsMasterClientOrSingleplayer()) { ammo.Reset(); dodgeEnergy.Reset(); DestroyAmmoHud(); } else if (LevelGenerator.Instance == null || !LevelGenerator.Instance.Generated) { HideAmmoHud(); } else { object currentSession = ((!SemiFunc.IsMultiplayer()) ? RunManager.instance : network?.Room); ammo.Observe(currentSession, SemiFunc.RunIsLevel() ? LevelGenerator.Instance : null); dodgeEnergy.Observe(currentSession, SemiFunc.RunIsLevel() ? LevelGenerator.Instance : null); } } private void HideAmmoHud() { if (Object.op_Implicit((Object)(object)ammoHud)) { ammoHud.SetActive(false); } } private void DestroyAmmoHud() { if (Object.op_Implicit((Object)(object)ammoCanvas)) { Object.Destroy((Object)(object)((Component)ammoCanvas).gameObject); } else if (Object.op_Implicit((Object)(object)ammoHud)) { Object.Destroy((Object)(object)ammoHud); } ammoHud = null; ammoCanvas = null; ammoNumber = null; ammoBars.Clear(); dodgeEnergyBars.Clear(); } private void UpdateAmmoHud() { //IL_0139: 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_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0179: 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_019e: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) try { PlayerAvatar instance = PlayerAvatar.instance; if (!((Behaviour)this).isActiveAndEnabled || !RoleEnabled || !Object.op_Implicit((Object)(object)GameManager.instance) || !Object.op_Implicit((Object)(object)RunManager.instance) || !SemiFunc.IsMasterClientOrSingleplayer() || SemiFunc.MenuLevel() || LevelGenerator.Instance == null || !LevelGenerator.Instance.Generated || !Object.op_Implicit((Object)(object)instance) || (bool)avatarDead.GetValue(instance) || (bool)avatarDisabled.GetValue(instance) || !(bool)avatarSpawned.GetValue(instance) || (Object.op_Implicit((Object)(object)MenuManager.instance) && (int)menuState.GetValue(MenuManager.instance) == 0)) { HideAmmoHud(); return; } if (!Object.op_Implicit((Object)(object)ammoHud)) { if (Time.unscaledTime < nextHudAttempt) { return; } nextHudAttempt = Time.unscaledTime + 1f; if (!BuildAmmoHud()) { return; } } ammoHud.SetActive(true); Transform transform = ((Component)ammoCanvas).transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); float num; if (Object.op_Implicit((Object)(object)val)) { Rect rect = val.rect; if (((Rect)(ref rect)).width > 0f) { rect = val.rect; num = ((Rect)(ref rect)).width / 1920f; goto IL_0168; } } num = 1f; goto IL_0168; IL_0168: float num2 = num; RectTransform val2 = (RectTransform)ammoHud.transform; ((Transform)val2).localScale = Vector3.one * (num2 * 0.7f); val2.anchoredPosition = new Vector2(-110f * num2, 28f * num2); for (int i = 0; i < ammoBars.Count; i++) { ammoBars[i].SetActive(i < ammo.Remaining); } for (int j = 0; j < dodgeEnergyBars.Count; j++) { dodgeEnergyBars[j].SetActive(j < dodgeEnergy.Remaining); } if (Object.op_Implicit((Object)(object)ammoNumber)) { SetHudProperty(ammoNumber, "text", ammo.Remaining + " / " + 8); } } catch (Exception ex) { DestroyAmmoHud(); if (Time.unscaledTime >= nextHudWarning) { nextHudWarning = Time.unscaledTime + 30f; ((BaseUnityPlugin)this).Logger.LogWarning((object)("Ammo HUD unavailable: " + ex.GetBaseException().Message)); } } } private static void SetHudProperty(Component target, string name, object value) { ((object)target).GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Public)?.SetValue(target, value); } private bool BuildAmmoHud() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_00bc: 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_00d5: 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_0116: 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_013e: 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_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: 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_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_01a8: 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_01d4: 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_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0236: 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_027d: Unknown result type (might be due to invalid IL or missing references) //IL_028c: 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_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: 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_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_032a: 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_0348: Unknown result type (might be due to invalid IL or missing references) //IL_0357: Unknown result type (might be due to invalid IL or missing references) //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_03ab: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Unknown result type (might be due to invalid IL or missing references) //IL_040a: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Expected O, but got Unknown //IL_0418: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_0425: Unknown result type (might be due to invalid IL or missing references) //IL_0426: Unknown result type (might be due to invalid IL or missing references) //IL_0427: Unknown result type (might be due to invalid IL or missing references) //IL_0428: Unknown result type (might be due to invalid IL or missing references) //IL_042d: Unknown result type (might be due to invalid IL or missing references) //IL_042e: Unknown result type (might be due to invalid IL or missing references) //IL_0435: Unknown result type (might be due to invalid IL or missing references) //IL_0437: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_043f: Unknown result type (might be due to invalid IL or missing references) //IL_0446: Unknown result type (might be due to invalid IL or missing references) //IL_0451: Unknown result type (might be due to invalid IL or missing references) //IL_0465: Unknown result type (might be due to invalid IL or missing references) //IL_04c8: Unknown result type (might be due to invalid IL or missing references) Type type = Type.GetType("UnityEngine.UI.RawImage, UnityEngine.UI", throwOnError: true); GameObject val = new GameObject("HostVeteranSurvivor Ammo Canvas", new Type[2] { typeof(RectTransform), typeof(Canvas) }); ammoCanvas = val.GetComponent<Canvas>(); ammoCanvas.renderMode = (RenderMode)0; ammoCanvas.sortingOrder = 100; ammoHud = new GameObject("HostVeteranSurvivor Ammo", new Type[1] { typeof(RectTransform) }); ammoHud.SetActive(false); RectTransform val2 = (RectTransform)ammoHud.transform; ((Transform)val2).SetParent(val.transform, false); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(1f, 0f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = new Vector2(1f, 0f); val2.sizeDelta = new Vector2(210f, 198f); Color val4 = default(Color); ((Color)(ref val4))..ctor(0.5019608f, 0.5019608f, 0.5019608f, 1f); CreateAmmoGraphic(type, "Background", Vector2.zero, new Vector2(210f, 62f), new Color(0.06f, 0.06f, 0.06f, 0.9f)); CreateAmmoGraphic(type, "Bottom border", Vector2.zero, new Vector2(210f, 4f), val4); CreateAmmoGraphic(type, "Top border", new Vector2(0f, 58f), new Vector2(210f, 4f), val4); CreateAmmoGraphic(type, "Left border", new Vector2(0f, 4f), new Vector2(4f, 54f), val4); CreateAmmoGraphic(type, "Right border", new Vector2(206f, 4f), new Vector2(4f, 54f), val4); for (int i = 0; i < 8; i++) { ammoBars.Add(CreateAmmoGraphic(type, "Round " + (i + 1), new Vector2(14f + (float)i * 22.875f, 15f), new Vector2(20.575f, 32f), val4)); } Color color = default(Color); ((Color)(ref color))..ctor(40f / 51f, 31f / 85f, 0.3529412f, 1f); CreateAmmoGraphic(type, "Dodge background", new Vector2(-123f, 0f), new Vector2(105f, 31f), new Color(0.06f, 0.06f, 0.06f, 0.9f)); CreateAmmoGraphic(type, "Dodge bottom border", new Vector2(-123f, 0f), new Vector2(105f, 2f), color); CreateAmmoGraphic(type, "Dodge top border", new Vector2(-123f, 29f), new Vector2(105f, 2f), color); CreateAmmoGraphic(type, "Dodge left border", new Vector2(-123f, 2f), new Vector2(2f, 27f), color); CreateAmmoGraphic(type, "Dodge right border", new Vector2(-20f, 2f), new Vector2(2f, 27f), color); for (int j = 0; j < 8; j++) { dodgeEnergyBars.Add(CreateAmmoGraphic(type, "Dodge charge " + (j + 1), new Vector2(-116f + (float)j * 11.4375f, 7.5f), new Vector2(10.2875f, 16f), color)); } Type type2 = Type.GetType("TMPro.TextMeshProUGUI, Unity.TextMeshPro", throwOnError: false); if (type2 != null) { Object[] array = Object.FindObjectsOfType(type2); if (array.Length != 0) { GameObject val5 = new GameObject("Ammo count", new Type[1] { typeof(RectTransform) }); RectTransform val6 = (RectTransform)val5.transform; ((Transform)val6).SetParent((Transform)(object)val2, false); Vector2 val7 = (val6.pivot = Vector2.zero); val3 = (val6.anchorMin = (val6.anchorMax = val7)); val6.anchoredPosition = new Vector2(0f, 64f); val6.sizeDelta = new Vector2(210f, 30f); ammoNumber = val5.AddComponent(type2); SetHudProperty(ammoNumber, "font", type2.GetProperty("font").GetValue(array[0])); SetHudProperty(ammoNumber, "fontSize", 24f); SetHudProperty(ammoNumber, "color", val4); SetHudProperty(ammoNumber, "raycastTarget", false); PropertyInfo property = type2.GetProperty("alignment"); property.SetValue(ammoNumber, Enum.Parse(property.PropertyType, "Right")); } } ((Transform)val2).SetAsLastSibling(); return true; } private GameObject CreateAmmoGraphic(Type rawType, string name, Vector2 position, Vector2 size, Color color) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_0038: 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_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_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_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) //IL_0054: 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_005f: 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_006a: 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_007b: 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_008c: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent(ammoHud.transform, false); Vector2 val3 = (val2.pivot = Vector2.zero); Vector2 anchorMin = (val2.anchorMax = val3); val2.anchorMin = anchorMin; ((Transform)val2).localScale = Vector3.one; ((Transform)val2).localRotation = Quaternion.identity; val2.anchoredPosition3D = new Vector3(position.x, position.y, 0f); val2.sizeDelta = size; Component target = val.AddComponent(rawType); SetHudProperty(target, "texture", Texture2D.whiteTexture); SetHudProperty(target, "uvRect", (object)new Rect(0f, 0f, 1f, 1f)); SetHudProperty(target, "material", null); SetHudProperty(target, "color", color); SetHudProperty(target, "raycastTarget", false); return val; } private void ImportLegacySettings(IReadOnlyDictionary<string, string> previous) { ConfigEntry<bool> val = ((BaseUnityPlugin)this).Config.Bind<bool>("Migration", "LegacySettingsImported", false, "Internal one-time import marker. Keep true to preserve your integrated settings."); if (val.Value) { return; } Dictionary<string, string> shotgun = LegacySettings.ReadFile(Path.Combine(Paths.ConfigPath, "local.bei.hostunarmedshotgun.cfg")); Dictionary<string, string> benefits = LegacySettings.ReadFile(Path.Combine(Paths.ConfigPath, "local.bei.hostsurvivalbenefits.cfg")); Dictionary<string, string> dictionary = LegacySettings.SelectImports(previous, shotgun, benefits, completed: false); foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in ((BaseUnityPlugin)this).Config) { if (dictionary.TryGetValue(item.Key.Section + "/" + item.Key.Key, out var value)) { item.Value.SetSerializedValue(value); } } val.Value = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Imported " + dictionary.Count + " legacy settings. Old cfg files were read only; future edits belong in local.bei.hostveteransurvivor.cfg.")); } private void ProtectControlDodge(PlayerAvatar player, float slideSeconds, float invincibleSeconds) { controlDodge.Begin(player, LevelGenerator.Instance, Time.time, slideSeconds, invincibleSeconds); } private void ClearControlDodge() { controlDodge.Clear(); } internal bool TryAvoidControlAttack(PlayerAvatar target) { if (!Object.op_Implicit((Object)(object)target) || (Object)(object)target != (Object)(object)PlayerAvatar.instance || !((Behaviour)this).isActiveAndEnabled || !RoleEnabled || RoleMenu.InputBlocked || !dodgeEnabled.Value || !Object.op_Implicit((Object)(object)GameManager.instance) || !SemiFunc.IsMasterClientOrSingleplayer() || !Object.op_Implicit((Object)(object)target.playerHealth) || (int)dodgeHealth.GetValue(target.playerHealth) <= 0 || (bool)avatarDisabled.GetValue(target) || (bool)avatarDead.GetValue(target) || (bool)avatarTumbling.GetValue(target)) { return false; } if (controlDodge.Active(target, LevelGenerator.Instance, Time.time)) { return true; } return TryEmergencyDodge(target.playerHealth); } private bool DeathExplosionEnabled() { if (((Behaviour)this).isActiveAndEnabled && RoleEnabled && Object.op_Implicit((Object)(object)GameManager.instance) && Object.op_Implicit((Object)(object)RunManager.instance) && SemiFunc.IsMasterClientOrSingleplayer()) { return !SemiFunc.MenuLevel(); } return false; } private Item FindDeathGrenade() { if (Object.op_Implicit((Object)(object)deathGrenadeItem)) { return deathGrenadeItem; } deathGrenadeItem = ((IEnumerable<Item>)Items.AllItems).FirstOrDefault((Func<Item, bool>)((Item item) => Object.op_Implicit((Object)(object)item) && item.prefab != null && ((PrefabRef<GameObject>)(object)item.prefab).IsValid() && Object.op_Implicit((Object)(object)((PrefabRef<GameObject>)(object)item.prefab).Prefab) && Object.op_Implicit((Object)(object)((PrefabRef<GameObject>)(object)item.prefab).Prefab.GetComponent<ItemGrenadeExplosive>()) && Object.op_Implicit((Object)(object)((PrefabRef<GameObject>)(object)item.prefab).Prefab.GetComponent<ItemGrenade>()) && Object.op_Implicit((Object)(object)((PrefabRef<GameObject>)(object)item.prefab).Prefab.GetComponent<ParticleScriptExplosion>()))); if (!Object.op_Implicit((Object)(object)deathGrenadeItem)) { throw new MissingMemberException("Standard explosive grenade prefab missing."); } return deathGrenadeItem; } internal void TriggerDeathExplosion(PlayerAvatar player, Vector3 position) { //IL_0032: 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_0098: 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_00b7: Unknown result type (might be due to invalid IL or missing references) try { if (!DeathExplosionEnabled() || !Object.op_Implicit((Object)(object)player) || player != PlayerAvatar.instance || !Object.op_Implicit((Object)(object)player.playerHealth) || player.playerHealth.isMenuAvatar || !ShotGeometry.Finite(position) || !Object.op_Implicit((Object)(object)LevelGenerator.Instance) || !LevelGenerator.Instance.Generated) { return; } object room = (SemiFunc.IsMultiplayer() ? network.Room : RunManager.instance); if (deathExplosionUses.TryConsume(LevelGenerator.Instance, room, HasNearbyLivingAlly(player, position))) { EmitLocalDeathExplosion(player, position); if (SemiFunc.IsMultiplayer()) { deathExplosionPending = true; deathExplosionPlayer = player; deathExplosionPosition = position; deathExplosionStage = LevelGenerator.Instance; deathExplosionRoom = network.Room; deathExplosionDeadline = Time.unscaledTime + 5f; UpdateDeathExplosionProxy(); } } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("[DeathExplosion] Could not emit death explosion: " + ex)); } } private bool HasNearbyLivingAlly(PlayerAvatar player, Vector3 deathPosition) { //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_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_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) foreach (PlayerAvatar item in SemiFunc.PlayerGetAll()) { if (!Object.op_Implicit((Object)(object)item) || item == player || !Object.op_Implicit((Object)(object)item.playerHealth) || item.playerHealth.isMenuAvatar || (bool)avatarDead.GetValue(item)) { continue; } Vector3 position = ((Component)item).transform.position; if (ShotGeometry.Finite(position)) { Vector3 val = position - deathPosition; if (!DeathExplosionRules.AllyWithinExclusionRadius(((Vector3)(ref val)).sqrMagnitude)) { continue; } } return true; } return false; } private void EmitLocalDeathExplosion(PlayerAvatar player, Vector3 position) { //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_0056: Expected O, but got Unknown //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_0062: Unknown result type (might be due to invalid IL or missing references) ParticleScriptExplosion component = ((PrefabRef<GameObject>)(object)FindDeathGrenade().prefab).Prefab.GetComponent<ParticleScriptExplosion>(); GameObject val = Resources.Load<GameObject>("Effects/Part Prefab Explosion"); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)component.explosionPreset)) { throw new MissingMemberException("Grenade explosion resources missing."); } GameObject val2 = new GameObject("HostVeteranSurvivor.DeathExplosion"); Object.Destroy((Object)val2, 1f); val2.transform.position = position; ParticleScriptExplosion val3 = val2.AddComponent<ParticleScriptExplosion>(); ((Behaviour)val3).enabled = false; val3.explosionPreset = component.explosionPreset; NeedField(typeof(ParticleScriptExplosion), "explosionPrefab", typeof(GameObject)).SetValue(val3, val); NeedField(typeof(ParticleScriptExplosion), "playerCausingHurtOverride", typeof(PlayerAvatar)).SetValue(val3, player); ItemGrenadeExplosive val4 = val2.AddComponent<ItemGrenadeExplosive>(); ((Behaviour)val4).enabled = false; NeedField(typeof(ItemGrenadeExplosive), "particleScriptExplosion", typeof(ParticleScriptExplosion)).SetValue(val4, val3); val4.Explosion(); } private void UpdateDeathExplosionProxy() { //IL_0139: 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_014c: 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_0329: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) if (!DeathExplosionEnabled() || !SemiFunc.IsMultiplayer() || !Object.op_Implicit((Object)(object)LevelGenerator.Instance) || !LevelGenerator.Instance.Generated || !Object.op_Implicit((Object)(object)PlayerAvatar.instance)) { CleanupDeathExplosion(); return; } try { object instance = LevelGenerator.Instance; object room = network.Room; if (deathGrenadeStage != instance || deathGrenadeRoom != room) { if (deathExplosionPending && (deathExplosionStage != instance || deathExplosionRoom != room)) { deathExplosionPending = false; } DestroyDeathGrenadeProxy(); deathGrenadeStage = instance; deathGrenadeRoom = room; deathGrenadeRetryAt = 0f; } if (deathExplosionPending && Time.unscaledTime > deathExplosionDeadline) { deathExplosionPending = false; deathExplosionPlayer = null; ((BaseUnityPlugin)this).Logger.LogWarning((object)"[DeathExplosion] Guest explosion preparation timed out; host explosion already occurred."); } if (!deathExplosionPending && (bool)avatarDead.GetValue(PlayerAvatar.instance)) { return; } int i; if (!Object.op_Implicit((Object)(object)deathGrenadeProxy)) { if (Time.unscaledTime < deathGrenadeRetryAt) { return; } deathGrenadeRetryAt = Time.unscaledTime + 3f; Vector3 val = (Vector3)disabledPosition.GetValue(AssetManager.instance); deathGrenadeProxy = NetworkPrefabs.SpawnNetworkPrefab(FindDeathGrenade().prefab, val, Quaternion.identity, (byte)0, new object[3] { 1f, 1f, 1f }); if (!Object.op_Implicit((Object)(object)deathGrenadeProxy)) { throw new InvalidOperationException("Death grenade carrier spawn failed."); } MonoBehaviour[] componentsInChildren = deathGrenadeProxy.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val2 in componentsInChildren) { if (Object.op_Implicit((Object)(object)val2) && ((object)val2).GetType().Name != "PhotonView" && ((object)val2).GetType().Name != "PhotonTransformView") { ((Behaviour)val2).enabled = false; } } Collider[] componentsInChildren2 = deathGrenadeProxy.GetComponentsInChildren<Collider>(true); for (i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].enabled = false; } Rigidbody component = deathGrenadeProxy.GetComponent<Rigidbody>(); component.isKinematic = true; component.useGravity = false; component.detectCollisions = false; deathGrenadeReadyAt = Time.unscaledTime + 0.75f; } string text = network.Roster(out i); if (text != deathGrenadeRoster) { deathGrenadeRoster = text; deathGrenadeReadyAt = Time.unscaledTime + 0.75f; } if (deathExplosionPending && !(Time.unscaledTime < deathGrenadeReadyAt)) { int num = (Object.op_Implicit((Object)(object)deathExplosionPlayer) ? network.ViewId(((Component)deathExplosionPlayer).gameObject) : 0); deathExplosionPending = false; if (num > 0) { network.Rpc(deathGrenadeProxy, "SetActivatorRPC", true, num); } network.Rpc(deathGrenadeProxy, "SetPositionRPC", true, deathExplosionPosition, Quaternion.identity); network.Rpc(deathGrenadeProxy, "TickEndRPC", true); deathExplosionPlayer = null; DestroyDeathGrenadeProxy(); } } catch (Exception ex) { DestroyDeathGrenadeProxy(); deathGrenadeRetryAt = Time.unscaledTime + 3f; ((BaseUnityPlugin)this).Logger.LogWarning((object)("[DeathExplosion] Guest explosion carrier failed: " + ex)); } } private void DestroyDeathGrenadeProxy() { GameObject val = deathGrenadeProxy; deathGrenadeProxy = null; deathGrenadeRoster = null; if (!Object.op_Implicit((Object)(object)val)) { return; } try { network.Destroy(val); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[DeathExplosion] Carrier cleanup failed: " + ex.Message)); } } private void CleanupDeathExplosion() { deathExplosionPending = false; deathExplosionPlayer = null; DestroyDeathGrenadeProxy(); deathGrenadeStage = (deathGrenadeRoom = null); deathGrenadeRetryAt = 0f; } private void BindDodgeSettings() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) dodgeEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("EmergencyDodge", "Enabled", true, "Enable emergency sliding while HoldKey is held. Also requires General.Enabled. Host/solo only."); dodgeInvincibilitySeconds = ((BaseUnityPlugin)this).Config.Bind<float>("EmergencyDodge", "InvincibilitySeconds", 0.5f, new ConfigDescription("Native invincibility after a successful dodge, in game seconds. 0 disables it. Also affects other damage handled by native invincibility, including shotgun self-damage.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); dodgeDistanceMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("EmergencyDodge", "DistanceMultiplier", 1.3f, new ConfigDescription("Scale the automatic dodge's initial slide velocity and decay vector. 1 restores previous distance; 1.3 is approximately 30% farther. Obstacles, input and physics affect actual travel. Does not change normal slides or duration.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 3f), Array.Empty<object>())); dodgeKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("EmergencyDodge", "HoldKey", new KeyboardShortcut((KeyCode)114, Array.Empty<KeyCode>()), "Hold to evade incoming attacks, including while airborne or crouching. No activation while tumbling or already sliding; release to stop accepting attacks. Replaces ActivationKey/WindowSeconds from 1.1.0. Default R. This key also arms the unarmed shotgun (hold + Interact). None disables both key-triggered actions."); } [MethodImpl(MethodImplOptions.NoInlining)] internal float DodgeStaminaCost(PlayerController controller) { return 5f; } private void InitializeDodge() { dodgeHealth = NeedField(typeof(PlayerHealth), "health", typeof(int)); dodgeInvincible = NeedField(typeof(PlayerHealth), "invincibleTimer", typeof(float)); dodgeGodMode = NeedField(typeof(PlayerHealth), "godMode", typeof(bool)); dodgeKinematic = NeedField(typeof(PlayerController), "kinematicTimer", typeof(float)); dodgeMoveForce = NeedField(typeof(PlayerController), "MoveForceTimer", typeof(float)); dodgeCanSlide = NeedField(typeof(PlayerController), "CanSlide", typeof(bool)); dodgeSlideTimer = NeedField(typeof(PlayerController), "SlideTimer", typeof(float)); dodgeSlideDirection = NeedField(typeof(PlayerController), "SlideDirection", typeof(Vector3)); dodgeSlideCurrent = NeedField(typeof(PlayerController), "SlideDirectionCurrent", typeof(Vector3)); dodgeCrouchActive = NeedField(typeof(PlayerController), "CrouchActiveTimer", typeof(float)); dodgeCrouchInactive = NeedField(typeof(PlayerController), "CrouchInactiveTimer", typeof(float)); dodgeSprinted = NeedField(typeof(PlayerController), "SprintedTimer", typeof(float)); dodgeRecharge = NeedField(typeof(PlayerController), "sprintRechargeTimer", typeof(float)); } private bool CanEmergencyDodge(PlayerHealth health) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Invalid comparison between Unknown and I4 if (!((Behaviour)this).isActiveAndEnabled || !RoleEnabled || RoleMenu.InputBlocked || !dodgeEnabled.Value || !Object.op_Implicit((Object)(object)GameManager.instance) || !Object.op_Implicit((Object)(object)RunManager.instance) || !Object.op_Implicit((Object)(object)InputManager.instance) || !SemiFunc.IsMasterClientOrSingleplayer() || SemiFunc.MenuLevel() || !Object.op_Implicit((Object)(object)GameDirector.instance) || GameDirector.instance.DisableInput || (int)GameDirector.instance.currentState != 2 || Time.timeScale <= 0f) { return false; } PlayerAvatar instance = PlayerAvatar.instance; PlayerController instance2 = PlayerController.instance; if (!Object.op_Implicit((Object)(object)health) || !Object.op_Implicit((Object)(object)instance) || (Object)(object)instance.playerHealth != (Object)(object)health || !Object.op_Implicit((Object)(object)instance2) || (Object)(object)instance2.playerAvatarScript != (Object)(object)instance || !Object.op_Implicit((Object)(object)instance2.rb) || instance2.rb.isKinematic || !Object.op_Implicit((Object)(object)instance2.CollisionController) || instance2.Sliding || (!instance2.DebugEnergy && instance2.EnergyCurrent <= 0f) || (float)inputDisabled.GetValue(instance2) > 0f || (float)dodgeKinematic.GetValue(instance2) > 0f || (float)dodgeMoveForce.GetValue(instance2) > 0f || (int)dodgeHealth.GetValue(health) <= 0) { return false; } if (LevelGenerator.Instance == null || !LevelGenerator.Instance.Generated || (bool)avatarDisabled.GetValue(instance) || (bool)avatarDead.GetValue(instance) || (bool)avatarTumbling.GetValue(instance) || !(bool)avatarSpawned.GetValue(instance)) { return false; } if (Object.op_Implicit((Object)(object)instance.mapToolController) && (bool)mapActive.GetValue(instance.mapToolController)) { return false; } if (Object.op_Implicit((Object)(object)MenuManager.instance) && (int)menuState.GetValue(MenuManager.instance) == 0) { return false; } if (Object.op_Implicit((Object)(object)ChatManager.instance) && (bool)chatActive.GetValue(ChatManager.instance)) { return false; } return GUIUtility.keyboardControl == 0; } private bool DodgeKeyHeld() { //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_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_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_0045: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = dodgeKey.Value; if ((int)((KeyboardShortcut)(ref value)).MainKey == 0 || !UnityInput.Current.GetKey(((KeyboardShortcut)(ref value)).MainKey)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { if (!UnityInput.Current.GetKey(modifier)) { return false; } } return true; } internal bool TryDirectEmergencyDodge(PlayerHealth health, int damage, int enemyIndex) { if (enemyIndex >= 0 && damage > 0) { return TryEmergencyDodge(health); } return false; } internal bool TryEmergencyDodge(PlayerHealth health) { //IL_00d8: 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_00f0: 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_0155: 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_016d: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) UpdateAmmoContext(); if (dodgeEnergy.Remaining <= 0 || !CanEmergencyDodge(health) || !DodgeKeyHeld() || lastDodgeFrame == Time.frameCount || (float)dodgeInvincible.GetValue(health) > 0f || (bool)dodgeGodMode.GetValue(health)) { return false; } PlayerController instance = PlayerController.instance; float slideTime = instance.SlideTime; float num = Mathf.Max(instance.MoveSpeed, instance.SprintSpeed); if (float.IsNaN(slideTime) || float.IsInfinity(slideTime) || slideTime <= 0f || float.IsNaN(num) || float.IsInfinity(num) || num <= 0f) { return false; } num = DodgeMotion.ScaleSpeed(num, dodgeDistanceMultiplier.Value); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(SemiFunc.InputMovementX(), 0f, SemiFunc.InputMovementY()); if (!ShotGeometry.Finite(val)) { return false; } val = ((((Vector3)(ref val)).sqrMagnitude > 0.01f) ? ((Vector3)(ref val)).normalized : Vector3.back); lastDodgeFrame = Time.frameCount; if (busy) { ((MonoBehaviour)this).StopAllCoroutines(); CleanupShot(); busy = false; } dodgeCanSlide.SetValue(instance, false); dodgeSprinted.SetValue(instance, 0f); dodgeSlideDirection.SetValue(instance, val * num); dodgeSlideCurrent.SetValue(instance, val * num); dodgeSlideTimer.SetValue(instance, slideTime); dodgeCrouchInactive.SetValue(instance, 0f); dodgeCrouchActive.SetValue(instance, Mathf.Max(slideTime, instance.CrouchTimeMin)); instance.CrouchOverride(slideTime); instance.Crouching = true; instance.sprinting = false; instance.Sliding = true; dodgeEnergy.TryConsume(); instance.moving = true; instance.CanInteract = false; if (!instance.DebugEnergy) { instance.EnergyCurrent = Mathf.Max(0f, instance.EnergyCurrent - DodgeStaminaCost(instance)); } dodgeRecharge.SetValue(instance, Mathf.Max(1f, (float)dodgeRecharge.GetValue(instance))); float value = dodgeInvincibilitySeconds.Value; ProtectControlDodge(instance.playerAvatarScript, slideTime, value); if (!float.IsNaN(value) && !float.IsInfinity(value) && value > 0f) { health.InvincibleSet(Mathf.Max((float)dodgeInvincible.GetValue(health), Mathf.Clamp(value, 0f, 10f))); } instance.ChangeState(); try { instance.playerAvatarScript.Slide(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Emergency slide effect failed: " + ex.Message)); } try { EmitTumbleBreakSmoke(instance.playerAvatarScript, follow: false); } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Emergency dodge smoke failed: " + ex2.Message)); } return true; } private void Awake() { bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet; ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; try { Dictionary<string, string> previous = LegacySettings.ReadFile(((BaseUnityPlugin)this).Config.ConfigFilePath); BindShotgunSettings(); BindDodgeSettings(); BindReloadSettings(); ImportLegacySettings(previous); } catch (Exception ex) { ((Behaviour)this).enabled = false; ((BaseUnityPlugin)this).Logger.LogError((object)("Configuration could not be loaded; original config files were not modified: " + ex)); return; } finally { ((BaseUnityPlugin)this).Config.SaveOnConfigSet = saveOnConfigSet; } try { ((BaseUnityPlugin)this).Config.Save(); } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not save integrated settings: " + ex2.Message)); } InitializePlugin(); } private void BindShotgunSettings() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Expected O, but got Unknown //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Expected O, but got Unknown //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Expected O, but got Unknown //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Expected O, but got Unknown modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable all integrated features, including the once-per-stage death explosion, for the local host or single-player only."); selfDamagePerShot = ((BaseUnityPlugin)this).Config.Bind<int>("Shooting", "SelfDamagePerShot", 10, new ConfigDescription("Health cost per fired shot. 0 disables self-damage. Applied through the vanilla health-donation damage path.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>())); cooldownOverride = ((BaseUnityPlugin)this).Config.Bind<float>("Shooting", "CooldownSeconds", 0f, new ConfigDescription("0 uses the vanilla shotgun cooldown. The temporary shot lifecycle must also finish before the next shot.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>())); shotgunPrefabName = ((BaseUnityPlugin)this).Config.Bind<string>("Shooting", "ShotgunPrefabName", "", "Optional exact vanilla shotgun PrefabName. Empty searches the catalog."); ((BaseUnityPlugin)this).Config.Bind<float>("Shooting", "MuzzleRightOffset", 0.3f, "Legacy setting, unused since 1.3.1. The muzzle now follows the actual right hand. Use HandForwardOffset for adjustment."); handForwardOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Shooting", "HandForwardOffset", 0.08f, new ConfigDescription("Distance ahead of the actual right-hand grabber, along the viewing direction, in game units.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.4f), Array.Empty<object>())); warmupSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Network", "SpawnWarmupSeconds", 0.2f, new ConfigDescription("Time for the temporary vanilla gun to initialize before firing. Live multiplayer timing is unverified.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), Array.Empty<object>())); iconWarmupSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Network", "IconWarmupSeconds", 5f, new ConfigDescription("Wait after spawning a full-size offscreen shotgun so guests can cache a normal inventory icon before tiny emitters. Repeated after map/roster changes. This is a timed safeguard, not a remote completion acknowledgement. Existing blank PNGs must first be removed on affected PCs.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>())); poseSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "ArmHoldSeconds", 0.9f, new ConfigDescription("Game seconds to keep the arm raised AFTER firing. Replaces GrabPoseSeconds from 1.8 and earlier.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 3f), Array.Empty<object>())); poseLeadSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "ArmRaiseSeconds", 0.65f, new ConfigDescription("Minimum game seconds between notifying observers to raise the arm and firing. Automatically extended for the native pose speed. Replaces PoseLeadSeconds from 1.8 and earlier.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 3f), Array.Empty<object>())); } private void InitializePlugin() { //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Expected O, but got Unknown //IL_0218: Unknown result type (might be due to invalid IL or missing references) try { avatarDisabled = NeedField(typeof(PlayerAvatar), "isDisabled", typeof(bool)); avatarTumbling = NeedField(typeof(PlayerAvatar), "isTumbling", typeof(bool)); avatarDead = NeedField(typeof(PlayerAvatar), "deadSet", typeof(bool)); avatarSpawned = NeedField(typeof(PlayerAvatar), "spawned", typeof(bool)); menuState = NeedField(typeof(MenuManager), "currentMenuState", typeof(int)); chatActive = NeedField(typeof(ChatManager), "chatActive", typeof(bool)); mapActive = NeedField(typeof(MapToolController), "Active", typeof(bool)); grabCamera = NeedField(typeof(PhysGrabber), "playerCamera", typeof(Camera)); inputDisabled = NeedField(typeof(PlayerController), "InputDisableTimer", typeof(float)); lastGrabber = NeedField(typeof(PhysGrabObject), "lastPlayerGrabbing", typeof(PlayerAvatar)); gunPhys = NeedField(typeof(ItemGun), "physGrabObject", typeof(PhysGrabObject)); disabledPosition = NeedField(typeof(AssetManager), "physDisabledPosition", typeof(Vector3)); InitializeDodge(); network = new NativeNetwork(); harmony = new Harmony("local.bei.hostveteransurvivor"); harmony.PatchAll(typeof(Plugin).Assembly); Current = this; RegisterRole(); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Host Veteran Survivor 1.7.2 loaded: role menu=F5; Enabled={modEnabled.Value}; dodge=hold {dodgeKey.Value}; self-damage={selfDamagePerShot.Value}."); } catch (Exception ex) { try { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } catch { } ((Behaviour)this).enabled = false; ((BaseUnityPlugin)this).Logger.LogError((object)("Unsupported game/network API; mod disabled: " + ex)); } } private static FieldInfo NeedField(Type owner, string name, Type expected) { FieldInfo field = owner.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null || field.FieldType != expected) { throw new MissingFieldException(owner.FullName, name); } return field; } private void LateUpdate() { UpdateValuableReload(); CleanupFadingGuns(!RoleEnabled); try { UpdateIconPreparation(); } catch (Exception ex) { iconGate.Reset(); ((Behaviour)this).enabled = false; ((BaseUnityPlugin)this).Logger.LogError((object)("Icon preparation failed; unarmed shotgun disabled for this run: " + ex)); return; } if (!RoleEnabled || busy || Time.timeScale <= 0f || Time.time < nextShotAt || !Object.op_Implicit((Object)(object)GameManager.instance) || !Object.op_Implicit((Object)(object)RunManager.instance) || !Object.op_Implicit((Object)(object)InputManager.instance)) { return; } try { if (!DodgeKeyHeld() || !InputManager.instance.KeyDown((InputKey)2)) { return; } if (InteractionBlocksFire()) { if (interactionBlockedLogCount++ < 10) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Unarmed fire skipped: interaction prompt/action has priority."); } } else if (!iconGate.Ready(Time.unscaledTime)) { if (Time.unscaledTime >= nextIconNotice) { nextIconNotice = Time.unscaledTime + 3f; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Shot skipped: preparing normal shotgun icons. Press E again after preparation."); } } else if (CanFire() && FindShotgun()) { busy = true; float num = ((cooldownOverride.Value > 0f) ? cooldownOverride.Value : shotgunTemplate.shootCooldown); nextShotAt = Time.time + Mathf.Max(0.1f, num); ((MonoBehaviour)this).StartCoroutine(GuardedShot()); } } catch (Exception ex2) { busy = false; nextShotAt = Time.time + 2f; ((BaseUnityPlugin)this).Logger.LogError((object)("Could not start unarmed shot: " + ex2)); } } private void Update() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Invalid comparison between Unknown and I4 UpdateAmmoContext(); if (Object.op_Implicit((Object)(object)GameManager.instance) && Object.op_Implicit((Object)(object)RunManager.instance) && !SemiFunc.MenuLevel() && SemiFunc.IsMasterClientOrSingleplayer() && LevelGenerator.Instance != null && LevelGenerator.Instance.Generated && Object.op_Implicit((Object)(object)GameDirector.instance) && (int)GameDirector.instance.currentState == 2) { dodgeEnergy.Advance(Time.deltaTime); } UpdateTumbleBonuses(); UpdateTumbleSmokeProxy(); UpdateDeathExplosionProxy(); UpdateSmokeTrail(); UpdateAmmoHud(); } internal void ObserveInteractionPrompt(string rawText, string localizedText) { if (InteractionFireGate.IsInteractionPrompt(rawText, localizedText)) { ObserveLocalInteraction(); } } internal void ObserveLocalInteraction() { interactionGate.Observe(Time.frameCount, Time.time); } private bool InteractionBlocksFire() { return interactionGate.IsBlocked(Time.frameCount, Time.time); } private bool CanFire() { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown if (RoleMenu.InputBlocked || ammo.Remaining <= 0) { return false; } if (!Object.op_Implicit((Object)(object)iconPrimer) || !iconGate.Ready(Time.unscaledTime)) { return false; } if (!Object.op_Implicit((Object)(object)GameManager.instance) || !Object.op_Implicit((Object)(object)RunManager.instance) || !RoleEnabled || !SemiFunc.IsMasterClientOrSingleplayer() || SemiFunc.MenuLevel()) { return false; } if (InteractionBlocksFire()) { return false; } PlayerAvatar instance = PlayerAvatar.instance; PlayerController instance2 = PlayerController.instance; PhysGrabber instance3 = PhysGrabber.instance; if (!Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)instance.playerHealth) || !Object.op_Implicit((Object)(object)instance2) || !Object.op_Implicit((Object)(object)instance3) || !Object.op_Implicit((Object)(Camera)grabCamera.GetValue(instance3))) { return false; } if (LevelGenerator.Instance == null || !LevelGenerator.Instance.Generated || (float)inputDisabled.GetValue(instance2) > 0f) { return false; } if ((bool)avatarDisabled.GetValue(instance) || (bool)avatarTumbling.GetValue(instance) || (bool)avatarDead.GetValue(instance) || !(bool)avatarSpawned.GetValue(instance)) { return false; } if (instance3.grabbed || Object.op_Implicit((Object)(object)instance3.grabbedObjectTransform) || Object.op_Implicit((Object)(object)instance2.physGrabObject)) { return false; } if (Object.op_Implicit((Object)(object)instance.mapToolController) && (bool)mapActive.GetValue(instance.mapToolController)) { return false; } if (Object.op_Implicit((Object)(object)MenuManager.instance) && (int)menuState.GetValue(MenuManager.instance) == 0) { return false; } if (Object.op_Implicit((Object)(object)ChatManager.instance) && (bool)chatActive.GetValue(ChatManager.instance)) { return false; } return GUIUtility.keyboardControl == 0; } private void UpdateIconPreparation() { //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_0174: 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) if (!RoleEnabled || !Object.op_Implicit((Object)(object)GameManager.instance) || !Object.op_Implicit((Object)(object)RunManager.instance) || !SemiFunc.IsMasterClientOrSingleplayer() || SemiFunc.MenuLevel() || LevelGenerator.Instance == null || !LevelGenerator.Instance.Generated) { iconGate.Reset(); CleanupIconPrimer(); return; } bool flag = SemiFunc.IsMultiplayer(); int count = 1; string text = (flag ? network.Roster(out count) : "solo"); List<PlayerAvatar> list = SemiFunc.PlayerGetList(); bool flag2 = list != null && list.Count >= count && list.All((PlayerAvatar a) => Object.op_Implicit((Object)(object)a) && (bool)avatarSpawned.GetValue(a)); if (iconGate.Refresh(LevelGenerator.Instance, flag ? network.Room : null, text, flag2)) { CleanupShot(keepMuzzleEffects: false); CleanupFadingGuns(force: true); ((MonoBehaviour)this).StopAllCoroutines(); busy = false; CleanupIconPrimer(); } if (!flag2 || (iconGate.Started && Object.op_Implicit((Object)(object)iconPrimer))) { return; } if (Object.op_Implicit((Object)(object)iconPrimer)) { CleanupIconPrimer(); } iconGate.Reset(); iconGate.Refresh(LevelGenerator.Instance, flag ? network.Room : null, text, flag2); if (FindShotgun()) { Vector3 val = (Vector3)disabledPosition.GetValue(AssetManager.instance); iconPrimer = NetworkPrefabs.SpawnNetworkPrefab(shotgunItem.prefab, val, Quaternion.identity, (byte)0, new object[3] { 1f, 1f, 1f }); if (!Object.op_Implicit((Object)(object)iconPrimer)) { throw new InvalidOperationException("Normal-size icon primer did not spawn."); } ItemAttributes component = iconPrimer.GetComponent<ItemAttributes>(); PhysGrabObject component2 = iconPrimer.GetComponent<PhysGrabObject>(); Rigidbody component3 = iconPrimer.GetComponent<Rigidbody>(); if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component2) || !Object.op_Implicit((Object)(object)component3)) { throw new InvalidOperationException("Icon primer components missing."); } ((Behaviour)component).enabled = false; ((Behaviour)component2).enabled = false; Collider[] componentsInChildren = iconPrimer.GetComponentsInChildren<Collider>(true); for (int num = 0; num < componentsInChildren.Length; num++) { componentsInChildren[num].enabled = false; } component3.useGravity = false; component3.detectCollisions = false; component3.isKinematic = true; iconGate.Begin(Time.unscaledTime, iconWarmupSeconds.Value); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Normal-size shotgun icon preparation started; wait=" + iconWarmupSeconds.Value + "s; peers=" + text)); } } private void CleanupIconPrimer() { if (!Object.op_Implicit((Object)(object)iconPrimer)) { iconPrimer = null; return; } if (DestroyProxy(iconPrimer)) { iconPrimer = null; return; } throw new InvalidOperationException("Could not remove the previous icon primer."); } private bool FindShotgun() { if (Object.op_Implicit((Object)(object)shotgunTemplate) && Object.op_Implicit((Object)(object)shotgunItem)) { return true; } if (!Object.op_Implicit((Object)(object)StatsManager.instance) || Time.unscaledTime < nextCatalogAttempt) { return false; } nextCatalogAttempt = Time.unscaledTime + 2f; string exact = shotgunPrefabName.Value.Trim(); foreach (Item item in (from item in Items.AllItems where Object.op_Implicit((Object)(object)item) && item.prefab != null && ((PrefabRef<GameObject>)(object)item.prefab).IsValid() where (exact.Length <= 0) ? (ContainsShotgun(((PrefabRef<GameObject>)(object)item.prefab).PrefabName) || ContainsShotgun(((Object)item).name)) : string.Equals(((PrefabRef<GameObject>)(object)item.prefab).PrefabName, exact, StringComparison.OrdinalIgnoreCase) orderby (!(NormalizeName(((PrefabRef<GameObject>)(object)item.prefab).PrefabName) == "itemgunshotgun")) ? 1 : 0 select item).ThenBy<Item, string>((Item item) => ((PrefabRef<GameObject>)(object)item.prefab).PrefabName, StringComparer.Ordinal)) { GameObject prefab = ((PrefabRef<GameObject>)(object)item.prefab).Prefab; if (Object.op_Implicit((Object)(object)prefab)) { ItemGun component = prefab.GetComponent<ItemGun>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.gunMuzzle) && Object.op_Implicit((Object)(object)component.bulletPrefab) && component.numberOfBullets > 0 && !(component.gunRange <= 0f)) { shotgunItem = item; shotgunTemplate = component; ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Vanilla shot source: {((PrefabRef<GameObject>)(object)item.prefab).PrefabName}; path={((PrefabRef<GameObject>)(object)item.prefab).ResourcePath}; pellets={component.numberOfBullets}; range={component.gunRange}; cooldown={component.shootCooldown}"); return true; } } } ((BaseUnityPlugin)this).Logger.LogWarning((object)"Vanilla shotgun data is not available yet. Try after level loading, or set its exact ShotgunPrefabName."); return false; } private static bool ContainsShotgun(string name) { if (name != null) { return name.IndexOf("shotgun", StringComparison.OrdinalIgnoreCase) >= 0; } return false; } private static string NormalizeName(string name) { return new string((name ?? "").Where(char.IsLetterOrDigit).ToArray()).ToLowerInvariant(); } private IEnumerator GuardedShot() { IEnumerator shot = ShotSequence(); try { while (true) { object current; try { if (!shot.MoveNext()) { break; } current = shot.Current; } catch (Exception ex) { nextShotAt = Time.time + 2f; ((BaseUnityPlugin)this).Logger.LogError((object)("Unarmed shot failed: " + ex)); break; } yield return current; } } finally { Plugin plugin = this; (shot as IDisposable)?.Dispose(); plugin.CleanupShot(); plugin.busy = false; } } private IEnumerator ShotSequence() { PlayerAvatar shooter = PlayerAvatar.instance; posingGrabber = PhysGrabber.instance; Camera aimCamera = (Camera)grabCamera.GetValue(posingGrabber); posingArm = (Object.op_Implicit((Object)(object)shooter.playerAvatarVisuals) ? ((Component)shooter.playerAvatarVisuals).GetComponentInChildren<PlayerAvatarRightArm>(true) : null); if (!Object.op_Implicit((Object)(object)posingArm) || !Object.op_Implicit((Object)(object)posingArm.grabberTransform) || !Object.op_Implicit((Object)(object)posingArm.rightArmParentTransform)) { throw new InvalidOperationException("Right-hand transforms are unavailable. Shot canceled."); } shotShooter = shooter; float raiseSeconds = ArmPoseTiming.RaiseDuration(poseLeadSeconds.Value, posingArm.poseSpeed); float holdSeconds = poseSeconds.Value; posingArm.GrabberPoseOverride(0.25f); Vector3 val = (Vector3)disabledPosition.GetValue(AssetManager.instance); temporaryGun = NetworkPrefabs.SpawnNetworkPrefab(shotgunItem.prefab, val, Quaternion.identity, (byte)0, new object[3] { 0.0001f, 0.0001f, 0.0001f }); temporaryGunDestroyAt = 0f; if (!Object.op_Implicit((Object)(object)temporaryGun)) { throw new InvalidOperationException("The temporary vanilla shotgun did not spawn."); } temporaryGun.transform.localScale = Vector3.one * 0.0001f; ItemGun gun = temporaryGun.GetComponent<ItemGun>(); PhysGrabObject phys = temporaryGun.GetComponent<PhysGrabObject>(); Rigidbody body = temporaryGun.GetComponent<Rigidbody>(); if (!Object.op_Implicit((Object)(object)gun) || !Object.op_Implicit((Object)(object)phys) || !Object.op_Implicit((Object)(object)body)) { throw new InvalidOperationException("Shotgun components are missing."); } ItemAttributes component = temporaryGun.GetComponent<ItemAttributes>(); if (Object.op_Implicit((Object)(object)component)) { ((Behaviour)component).enabled = false; } ((Behaviour)phys).enabled = false; Transform val2 = (Object.op_Implicit((Object)(object)gun.muzzleFlashPrefab) ? gun.muzzleFlashPrefab.transform : null); Renderer[] componentsInChildren = temporaryGun.GetComponentsInChildren<Renderer>(true); foreach (Renderer val3 in componentsInChildren) { if (!Object.op_Implicit((Object)(object)val2) || !((Component)val3).transform.IsChildOf(val2)) { val3.enabled = false; } } Collider[] componentsInChildren2 = temporaryGun.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].enabled = false; } body.useGravity = false; body.detectCollisions = false; body.isKinematic = true; lastGrabber.SetValue(phys, shooter); float readyAt = Time.unscaledTime + warmupSeconds.Value; float timeoutAt = readyAt + 5f; do { yield return null; if (!Object.op_Implicit((Object)(object)temporaryGun) || !Object.op_Implicit((Object)(object)shooter) || !CanFire()) { yield break; } posingArm.GrabberPoseOverride(0.25f); if (Time.unscaledTime >= timeoutAt) { throw new TimeoutException("Vanilla shotgun Start did not finish."); } } while (Time.unscaledTime < readyAt || gunPhys.GetValue(gun) == null); ((Behaviour)gun).enabled = false; gun.gunRecoilForce = 0f; body.isKinematic = false; ItemBattery component2 = temporaryGun.GetComponent<ItemBattery>(); if (Object.op_Implicit((Object)(object)component2)) { component2.SetBatteryLife(100); } if (!MoveEmitter(phys, aimCamera)) { yield break; } yield return null; if (!Object.op_Implicit((Object)(object)temporaryGun) || !CanFire()) { yield break; } if (SemiFunc.IsMultiplayer()) { int num = network.ViewId(((Component)posingGrabber).gameObject); remotePoseSent = true; network.Rpc(temporaryGun, "GrabLinkRPC", true, num, -1, gun.gunMuzzle.position, Vector3.forward, Vector3.up); network.Rpc(((Component)posingGrabber).gameObject, "PhysGrabBeamActivateRPC", true); } for (float raisedFor = 0f; raisedFor < raiseSeconds; raisedFor += Time.deltaTime) { if (!Object.op_Implicit((Object)(object)temporaryGun) || !Object.op_Implicit((Object)(object)posingArm) || !CanFire()) { yield break; } posingArm.GrabberPoseOverride(0.25f); if (!MoveEmitter(phys, aimCamera)) { yield break; } yield return null; } yield return (object)new WaitForEndOfFrame(); if (!Object.op_Implicit((Object)(object)temporaryGun) || !CanFire() || !MoveEmitter(phys, aimCamera)) { yield break; } posingArm.GrabberPoseOverride(0.25f); if (!ammo.TryConsume()) { yield break; } network.Rpc(temporaryGun, "ShootRPC", false); temporaryGunDestroyAt = Time.time + 2.5f; if (selfDamagePerShot.Value > 0) { shooter.playerHealth.Hurt(selfDamagePerShot.Value, false, -1, true); } float heldFor = 0f; float moveAt = Time.unscaledTime; for (; heldFor < holdSeconds; heldFor += Time.deltaTime) { if (!Object.op_Implicit((Object)(object)temporaryGun)) { break; } if (!Object.op_Implicit((Object)(object)shooter)) { break; } if (!Object.op_Implicit((Object)(object)posingGrabber)) { break; } if (!Object.op_Implicit((Object)(object)posingArm)) { break; } if (!RoleEnabled) { break; } if (posingGrabber.grabbed) { break; } if (Object.op_Implicit((Object)(object)posingGrabber.grabbedObjectTransform)) { break; } if ((bool)avatarDead.GetValue(shooter)) { break; } if ((bool)avatarTumbling.GetValue(shooter)) { break; } if (Object.op_Implicit((Object)(object)shooter.mapToolController) && (bool)mapActive.GetValue(shooter.mapToolController)) { break; } posingArm.GrabberPoseOverride(0.25f); if (Time.unscaledTime >= moveAt && Object.op_Implicit((Object)(object)aimCamera)) { if (!MoveEmitter(phys, aimCamera)) { break; } moveAt = Time.unscaledTime + 0.1f; } yield return null; } } internal bool TryObserverAim(PhysGrabber grabber, out Vector3 target) { //IL_0001: 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_0091: Expected O, but got Unknown //IL_00b9: 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_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_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) target = default(Vector3); if (!((Behaviour)this).isActiveAndEnabled || !RoleEnabled || !remotePoseSent || !Object.op_Implicit((Object)(object)temporaryGun) || !Object.op_Implicit((Object)(object)posingArm) || !Object.op_Implicit((Object)(object)shotShooter) || (Object)(object)grabber != (Object)(object)posingGrabber || (Object)(object)grabber != (Object)(object)PhysGrabber.instance || grabber.grabbed || Object.op_Implicit((Object)(object)grabber.grabbedObjectTransform) || !SemiFunc.IsMasterClientOrSingleplayer()) { return false; } Camera val = (Camera)grabCamera.GetValue(grabber); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)posingArm.grabberTransform)) { return false; } target = posingArm.grabberTransform.position + ((Component)val).transform.forward * 0.35f; return ShotGeometry.Finite(target); } private bool MoveEmitter(PhysGrabObject phys, Camera aimCamera) { //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_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_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_0076: 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_0086: 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_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_00ac: 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_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_00bf: 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_00e0: 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_00e9: 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_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_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) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0143: 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_0174: 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) //IL_0177: 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_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_01ac: 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_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: 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_01e1: 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) //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_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0202: 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) if (!Object.op_Implicit((Object)(object)posingArm) || !Object.op_Implicit((Object)(object)posingArm.grabberTransform) || !Object.op_Implicit((Object)(object)posingArm.rightArmParentTransform) || !Object.op_Implicit((Object)(object)aimCamera) || !Object.op_Implicit((Object)(object)shotShooter)) { return false; } Vector3 position = posingArm.grabberTransform.position; Vector3 position2 = posingArm.rightArmParentTransform.position; Vector3 forward = ((Component)aimCamera).transform.forward; if (ShotGeometry.Finite(position) && ShotGeometry.Finite(position2) && ShotGeometry.Finite(forward)) { Vector3 val = position - position2; if (!(((Vector3)(ref val)).sqrMagnitude > 36f)) { Vector3 val2 = ShotGeometry.MuzzlePosition(position, forward, handForwardOffset.Value); int num = LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct()); Ray val3 = aimCamera.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f)); if (!ShotGeometry.Finite(((Ray)(ref val3)).origin) || !ShotGeometry.Finite(((Ray)(ref val3)).direction)) { return false; } float distance = shotgunTemplate.gunRange + Vector3.Distance(((Ray)(ref val3)).origin, val2); Vector3 target = val2 + forward * shotgunTemplate.gunRange; if (RaycastWithoutShooter(((Ray)(ref val3)).origin, ((Ray)(ref val3)).direction, out var hit, distance, num | LayerMask.GetMask(new string[1] { "Enemy" }), (QueryTriggerInteraction)0)) { target = ((RaycastHit)(ref hit)).point; } Quaternion val4 = Quaternion.LookRotation(ShotGeometry.FiringDirection(val2, forward, target), ((Component)aimCamera).transform.up); Quaternion val5 = Quaternion.Inverse(((Component)shotgunTemplate).transform.rotation) * shotgunTemplate.gunMuzzle.rotation; Quaternion val6 = val4 * Quaternion.Inverse(val5); Vector3 val7 = ((Component)shotgunTemplate).transform.InverseTransformPoint(shotgunTemplate.gunMuzzle.position); phys.Teleport(val2 - val6 * (val7 * 0.0001f), val6); return true; } } return PlacementBlocked(); } private bool PlacementBlocked() { if (Time.unscaledTime >= nextPlacementWarning) { nextPlacementWarning = Time.unscaledTime + 2f; ((BaseUnityPlugin)this).Logger.LogWarning((object)"Right-hand muzzle pose is invalid. Shot canceled; waiting for a valid arm pose."); } return false; } private bool IgnoreCollider(Collider collider) { if (!Object.op_Implicit((Object)(object)collider)) { return true; } if (Object.op_Implicit((Object)(object)temporaryGun) && ((Component)collider).transform.IsChildOf(temporaryGun.transform)) { return true; } PlayerAvatar componentInParent = ((Component)collider).GetComponentInParent<PlayerAvatar>(); if (Object.op_Implicit((Object)(object)componentInParent)) { return (Object)(object)componentInParent == (Object)(object)shotShooter; } PlayerController componentInParent2 = ((Component)collider).GetComponentInParent<PlayerController>(); if (Object.op_Implicit((Object)(object)componentInParent2) && (Object)(object)componentInParent2.playerAvatarScript == (Object)(object)shotShooter) { return true; } PlayerAvatarVisuals componentInParent3 = ((Component)collider).GetComponentInParent<PlayerAvatarVisuals>(); if (Object.op_Implicit((Object)(object)componentInParent3) && (Object)(object)componentInParent3.playerAvatar == (Object)(object)shotShooter) { return true; } PlayerTumble componentInParent4 = ((Component)collider).GetComponentInParent<PlayerTumble>(); if (Object.op_Implicit((Object)(object)componentInParent4)) { return (Object)(object)componentInParent4.playerAvatar == (Object)(object)shotShooter; } return false; } internal bool RaycastWithoutShooter(Vector3 origin, Vector3 direction, out RaycastHit hit, float distance, int mask, QueryTriggerInteraction triggers) { //IL_0001: 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_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_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) hit = default(RaycastHit); bool result = false; float num = distance; RaycastHit[] array = Physics.RaycastAll(origin, direction, distance, mask, triggers); for (int i = 0; i < array.Length; i++) { RaycastHit val = array[i]; if (!IgnoreCollider(((RaycastHit)(ref val)).collider) && !(((RaycastHit)(ref val)).distance > num)) { result = true; num = ((RaycastHit)(ref val)).distance; hit = val; } } return result; } internal bool OwnsEmitter(ItemGun gun) { if (((Behaviour)this).enabled && Object.op_Implicit((Object)(object)shotShooter) && Object.op_Implicit((Object)(object)temporaryGun) && Object.op_Implicit((Object)(object)gun)) { return (Object)(object)((Component)gun).gameObject == (Object)(object)temporaryGun; } return false; } internal void ProtectShooter(ItemGun gun, HurtCollider hurt) { if (OwnsEmitter(gun) && Object.op_Implicit((Object)(object)hurt) && !hurt.ignorePlayers.Contains(shotShooter)) { hurt.ignorePlayers.Add(shotShooter); } } internal bool OwnsProxy(GameObject target) { if (Object.op_Implicit((Object)(object)target)) { if (!((Object)(object)target == (Object)(object)tumbleSmokeProxy) && !((Object)(object)target == (Object)(object)temporaryGun)) { return fadingGuns.Any((FadingGun gun) => Object.op_Implicit((Object)(object)gun.Target) && (Object)(object)gun.Target == (Object)(object)target); } return true; } return false; } internal void CancelProxyGrab(GameObject target) { if (!OwnsProxy(target)) { return; } if ((Object)(object)target == (Object)(object)tumbleSmokeProxy) { CleanupTumbleSmokeProxy(); return; } if (DestroyProxy(target)) { fadingGuns.RemoveAll((FadingGun gun) => (Object)(object)gun.Target == (Object)(object)target); } else { FadingGun fadingGun = fadingGuns.FirstOrDefault((FadingGun gun) => (Object)(object)gun.Target == (Object)(object)target); if (fadingGun != null) { fadingGun.DestroyAt = Time.time + 1f; } else { fadingGuns.Add(new FadingGun { Target = target, DestroyAt = Time.time + 1f }); } } if ((Object)(object)temporaryGun == (Object)(object)target) { temporaryGun = null; temporaryGunDestroyAt = 0f; } } private void CleanupShot(bool keepMuzzleEffects = true) { //IL_013f: 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) GameObject val = temporaryGun; float num = temporaryGunDestroyAt; PhysGrabber val2 = posingGrabber; PlayerAvatarRightArm val3 = posingArm; bool flag = remotePoseSent; temporaryGun = null; temporaryGunDestroyAt = 0f; posingGrabber = null; posingArm = null; shotShooter = null; remotePoseSent = false; try { if (Object.op_Implicit((Object)(object)val3)) { val3.GrabberPoseOverride(0f); } if (flag && Object.op_Implicit((Object)(object)val2) && !val2.grabbed && !Object.op_Implicit((Object)(object)val2.grabbedObjectTransform) && Object.op_Implicit((Object)(object)GameManager.instance) && SemiFunc.IsMultiplayer() && network.InRoom) { network.Rpc(((Component)val2).gameObject, "GrabClimbEndedRPC", true); network.Rpc(((Component)val2).gameObject, "PhysGrabBeamDeactivateRPC", true); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Temporary grab-pose cleanup failed: " + ex.Message)); } finally { if (Object.op_Implicit((Object)(object)val)) { if (keepMuzzleEffects && ((Behaviour)this).isActiveAndEnabled && RoleEnabled && num > Time.time) { Rigidbody component = val.GetComponent<Rigidbody>(); if (Object.op_Implicit((Object)(object)component)) { component.velocity = Vector3.zero; component.angularVelocity = Vector3.zero; component.isKinematic = true; } fadingGuns.Add(new FadingGun { Target = val, DestroyAt = num }); } else if (!DestroyProxy(val)) { fadingGuns.Add(new FadingGun { Target = val, DestroyAt = Time.time + 1f }); } } } } private void CleanupFadingGuns(bool force) { for (int num = fadingGuns.Count - 1; num >= 0; num--) { FadingGun fadingGun = fadingGuns[num]; if (!Object.op_Implicit((Object)(object)fadingGun.Target) || force || !(Time.time < fadingGun.DestroyAt)) { if (!Object.op_Implicit((Object)(object)fadingGun.Target) || DestroyProxy(fadingGun.Target)) { fadingGuns.RemoveAt(num); } else { fadingGun.DestroyAt = Time.time + 1f; } } } } private bool DestroyProxy(GameObject gun) { if (!Object.op_Implicit((Object)(object)gun)) { return true; } try { network.Destroy(gun); return true; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Temporary network gun cleanup failed: " + ex)); if (network == null || !network.InRoom) { Object.Destroy((Object)(object)gun); return true; } return false; } } private void StopAndCleanup() { CleanupDeathExplosion(); ResetSmokeTrail(); CleanupTumbleSmokeProxy(); ReleaseTumbleBonuses(); ClearControlDodge(); ((MonoBehaviour)this).StopAllCoroutines(); HideAmmoHud(); iconGate.Reset(); try { CleanupIconPrimer(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)ex); } CleanupShot(keepMuzzleEffects: false); CleanupFadingGuns(force: true); busy = false; } private void OnDisable() { StopAndCleanup(); } private void OnDestroy() { RoleMenu.Unregister("local.bei.hostveteransurvivor"); CleanupDeathExplosion(); ResetSmokeTrail(); CleanupTumbleSmokeProxy(); ReleaseTumbleBonuses(); DestroyAmmoHud(); iconGate.Reset(); try { CleanupIconPrimer(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)ex); } CleanupShot(keepMuzzleEffects: false); CleanupFadingGuns(force: true); if (Current == this) { Current = null; } Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } private void RegisterRole() { RoleMenu.Register("local.bei.hostveteransurvivor", "Veteran Survivor", "Shotgun, emergency dodge and extra jumps. Ammo and stage explosion use are kept when switching.", 0, (Func<bool>)(() => ((Behaviour)this).isActiveAndEnabled && modEnabled.Value), (Action<bool>)ApplyRole); } private void ApplyRole(bool active) { if (!active) { StopAndCleanup(); } } internal bool TumbleBenefitsFor(PlayerAvatar player) { if (!bonusFailed && ((Behaviour)this).isActiveAndEnabled && RoleEnabled && Object.op_Implicit((Object)(object)GameManager.instance) && SemiFunc.IsMasterClientOrSingleplayer() && !SemiFunc.MenuLevel() && Object.op_Implicit((Object)(object)player) && (Object)(object)player == (Object)(object)PlayerAvatar.instance && (Object)(object)bonusPlayer == (Object)(object)player) { return Object.op_Implicit((Object)(object)bonusTumble); } return false; } private void UpdateTumbleBonuses() { if (bonusFailed) { return; } try { PlayerAvatar instance = PlayerAvatar.instance; PlayerController instance2 = PlayerController.instance; if (!((Behaviour)this).isActiveAndEnabled || !RoleEnabled || !Object.op_Implicit((Object)(object)GameManager.instance) || !SemiFunc.IsMasterClientOrSingleplayer() || SemiFunc.MenuLevel() || !Object.op_Implicit((Object)(object)StatsManager.instance) || !Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)instance2) || (Object)(object)instance2.playerAvatarScript != (Object)(object)instance) { ReleaseTumbleBonuses(); return; } object? value = bonusAvatarTumble.GetValue(instance); PlayerTumble val = (PlayerTumble)((value is PlayerTumble) ? value : null); if (!Object.op_Implicit((Object)(object)val) || !(bool)bonusTumbleReady.GetValue(val) || !(bool)avatarSpawned.GetValue(instance)) { return; } if ((Object)(object)bonusPlayer != (Object)(object)instance || (Object)(object)bonusController != (Object)(object)instance2 || (Object)(object)bonusTumble != (Object)(object)val) { ReleaseTumbleBonuses(); bonusSteamId = SemiFunc.PlayerGetSteamID(instance); if (string.IsNullOrEmpty(bonusSteamId)) { return; } bonusPlayer = instance; bonusController = instance2; bonusTumble = val; } bonusLaunch.SetValue(val, 1); bonusJump.SetValue(instance2, 1); bonusJumpRemaining.SetValue(instance2, Math.Min((int)bonusJumpRemaining.GetValue(instance2), 1)); } catch (Exception ex) { bonusFailed = true; ((BaseUnityPlugin)this).Logger.LogError((object)("Initial tumble/jump bonus unavailable: " + ex)); ReleaseTumbleBonuses(); } } private void ReleaseTumbleBonuses() { try { if (Object.op_Implicit((Object)(object)bonusPlayer) && (Object)(object)bonusPlayer == (Object)(object)PlayerAvatar.instance && Object.op_Implicit((Object)(object)StatsManager.instance) && Object.op_Implicit((Object)(object)GameManager.instance) && SemiFunc.IsMasterClientOrSingleplayer() && !string.IsNullOrEmpty(bonusSteamId)) { StatsManager.instance.playerUpgradeLaunch.TryGetValue(bonusSteamId, out var value); StatsManager.instance.playerUpgradeExtraJump.TryGetValue(bonusSteamId, out var value2); if (Object.op_Implicit((Object)(object)bonusTumble)) { bonusLaunch.SetValue(bonusTumble, Math.Max(0, value)); } if (Object.op_Implicit((Object)(object)bonusController)) { bonusJump.SetValue(bonusController, Math.Max(0, value2)); bonusJumpRemaining.SetValue(bonusController, Math.Min((int)bonusJumpRemaining.GetValue(bonusController), Math.Max(0, value2))); } } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not restore purchased tumble/jump levels: " + ex)); } finally { bonusPlayer = null; bonusController = null; bonusTumble = null; bonusSteamId = null; } } internal void EnforceVeteranUpgradeCap(PlayerAvatar player) { if (Object.op_Implicit((Object)(object)player) && (Object)(object)player == (Object)(object)PlayerAvatar.instance) { UpdateTumbleBonuses(); } } internal bool SuppressPowerup(PlayerAvatarVisuals visuals) { if (Object.op_Implicit((Object)(object)visuals)) { return (Object)(object)visuals == (Object)(object)suppressedLaunchVisual; } return false; } internal PlayerAvatarVisuals BeginLaunchVisualScope(PlayerAvatar player) { PlayerAvatarVisuals result = suppressedLaunchVisual; suppressedLaunchVisual = player.playerAvatarVisuals; return result; } internal void EndLaunchVisualScope(PlayerAvatarVisuals old) { suppressedLaunchVisual = old; } private void ResetSmokeTrail() { smokeTrail.Reset(); smokeTrailPlayer = null; smokeTrailStage = null; } private void UpdateSmokeTrail() { //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_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) //IL_009e: 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_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_00b6: 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_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) if (!smokeTrail.Active) { return; } if (!Object.op_Implicit((Object)(object)smokeTrailPlayer) || !TumbleBenefitsFor(smokeTrailPlayer) || smokeTrailStage != LevelGenerator.Instance || (bool)avatarDead.GetValue(smokeTrailPlayer) || (bool)avatarDisabled.GetValue(smokeTrailPlayer)) { ResetSmokeTrail(); } else if (!(Time.timeScale <= 0f)) { Vector3 val = ((Component)smokeTrailPlayer).transform.position + Vector3.up * 0.3f; SmokeTrailRules smokeTrailRules = smokeTrail; double timeAsDouble = Time.timeAsDouble; Vector3 val2 = val - smokeTrailPosition; int num = smokeTrailRules.Tick(timeAsDouble, ((Vector3)(ref val2)).sqrMagnitude); if (num >= 0) { EmitSmokeCluster(val, num); smokeTrailPosition = val; } } } private void UpdateTumbleSmokeProxy() { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //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) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) if (!TumbleBenefitsFor(PlayerAvatar.instance) || !Object.op_Implicit((Object)(object)LevelGenerator.Instance) || !LevelGenerator.Instance.Generated) { CleanupTumbleSmokeProxy(); return; } try { object obj = (SemiFunc.IsMultiplayer() ? network.Room : RunManager.instance); if (tumbleSmokeStage != LevelGenerator.Instance || tumbleSmokeRoom != obj) { CleanupTumbleSmokeProxy(); tumbleSmokeStage = LevelGenerator.Instance; tumbleSmokeRoom = obj; } int num; if (!Object.op_Implicit((Object)(object)tumbleSmokeProxy)) { if (Time.unscaledTime < tumbleSmokeRetryAt) { return; } tumbleSmokeRetryAt = Time.unscaledTime + 3f; GameObject val = Resources.Load<GameObject>("Valuables/03 Medium/Valuable Manor Vase"); if (!Object.op_Implicit((Object)(object)val)) { throw new MissingMemberException("Smoke carrier resource missing: Valuables/03 Medium/Valuable Manor Vase"); } PrefabRef val2 = new PrefabRef(); ((PrefabRef<GameObject>)(object)val2).SetPrefab(val, "Valuables/03 Medium/Valuable Manor Vase"); PhysGrabObjectImpactDetector val3 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<PhysGrabObjectImpactDetector>() : null); if (!Object.op_Implicit((Object)(object)val3) || val3.particleDisable || val3.particleBreakSmokeDisable) { throw new InvalidOperationException("Smoke proxy prefab has no enabled break-smoke emitter."); } string[] array = (from c in val.GetComponentsInChildren<MonoBehaviour>(true) select (!Object.op_Implicit((Object)(object)c)) ? "<missing script>" : ((object)c).GetType().Name into name where !SmokeProxyRules.Allows(name) select name).Distinct().ToArray(); if (array.Length != 0) { throw new InvalidOperationException("Unsupported smoke proxy scripts: " + string.Join(", ", array)); } Vector3 val4 = (Vector3)disabledPosition.GetValue(AssetManager.instance); tumbleSmokeProxy = NetworkPrefabs.SpawnNetworkPrefab(val2, val4, Quaternion.identity, (byte)0, new object[3] { 0.0001f, 0.0001f, 0.0001f }); if (!Object.op_Implicit((Object)(object)tumbleSmokeProxy)) { throw new InvalidOperationException("Smoke proxy spawn failed."); } tumbleSmokeProxy.transform.localScale = Vector3.one * 0.0001f; ((Behaviour)tumbleSmokeProxy.GetComponent<ValuableObject>()).enabled = false; tumbleSmokePhys = tumbleSmokeProxy.GetComponent<PhysGrabObject>(); ((Behaviour)tumbleSmokePhys).enabled = false; Rigidbody component = tumbleSmokeProxy.GetComponent<Rigidbody>(); component.isKinematic = true; component.useGravity = false; component.detectCollisions = false; MeshRenderer[] componentsInChildren = tumbleSmokeProxy.GetComponentsInChildren<MeshRenderer>(true); for (num = 0; num < componentsInChildren.Length; num++) { ((Renderer)componentsInChildren[num]).enabled = false; } Collider[] componentsInChildren2 = tumbleSmokeProxy.GetComponentsInChildren<Collider>(true); for (num = 0; num < componentsInChildren2.Length; num++) { componentsInChildren2[num].enabled = false; } tumbleSmokeDetector = tumbleSmokeProxy.GetComponent<PhysGrabObjectImpactDetector>(); tumbleSmokeValueInitialized = false; tumbleSmokeReadyAt = Time.unscaledTime + 0.75f; ManualLogSource logger = ((BaseUnityPlugin)this).Logger; num = network.ViewId(tumbleSmokeProxy); logger.LogInfo((object)("[TumbleSmoke] Carrier spawned from Valuables/03 Medium/Valuable Manor Vase; view=" + num)); } string text = (SemiFunc.IsMultiplayer() ? network.Roster(out num) : "solo"); if (text != tumbleSmokeRoster) { tumbleSmokeRoster = text; tumbleSmokeReadyAt = Time.unscaledTime + 0.75f; tumbleSmokeValueInitialized = false; } if (Time.unscaledTime >= tumbleSmokeReadyAt && Object.op_Implicit((Object)(object)tumbleSmokeDetector) && Object.op_Implicit((Object)(object)tumbleSmokeDetector.particles) && !tumbleSmokeValueInitialized) { network.Rpc(tumbleSmokeProxy, "DollarValueSetRPC", false, 0f); tumbleSmokeValueInitialized = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)("[TumbleSmoke] Network smoke carrier ready; view=" + network.ViewId(tumbleSmokeProxy))); } } catch (Exception ex) { CleanupTumbleSmokeProxy(); tumbleSmokeRetryAt = Time.unscaledTime + 10f; ((BaseUnityPlugin)this).Logger.LogWarning((object)("Tumble smoke could not be prepared: " + ex)); } } private void EmitLocalTumbleSmoke(Vector3 position) { //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_0057: 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_00a2: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)localSmokePrefab)) { localSmokePrefab = Resources.Load<GameObject>("Phys Object Particles"); } if (!Object.op_Implicit((Object)(object)localSmokePrefab)) { throw new MissingMemberException("Phys Object Particles resource missing."); } GameObject obj = Object.Instantiate<GameObject>(localSmokePrefab, position, Quaternion.identity); Object.Destroy((Object)(object)obj, 3f); obj.transform.localScale = Vector3.one; obj.SetActive(true); PhysObjectParticles component = obj.GetComponent<PhysObjectParticles>(); if (!Object.op_Implicit((Object)(object)component)) { throw new MissingComponentException("PhysObjectParticles component missing."); } Renderer[] componentsInChildren = obj.GetComponentsInChildren<Renderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = true; } component.ImpactSmoke(5, position, 0.7f); } private PhysGrabObjectImpactDetector GetReadySmokeCarrier() { if (Object.op_Implicit((Object)(object)tumbleSmokeProxy) && Object.o