Decompiled source of Boom Goes the Dynamite v0.2.5
BepInEx/plugins/BoomGoesTheDynamite/BoomGoesTheDynamite.dll
Decompiled 3 weeks 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.Runtime.CompilerServices; using System.Text; using BepInEx; using FishNet; using FishNet.Broadcast; using FishNet.Connection; using FishNet.Managing; using FishNet.Managing.Object; using FishNet.Object; using FishNet.Serializing; using FishNet.Transporting; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json.Linq; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Networking; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BoomGoesTheDynamite { public enum DeviceKind : byte { Super, Nuke, Timer, Mine } [Serializable] public sealed class DeviceState { public int objectId; public int timer = 5; public byte kind; public bool deployed; public bool armed; public bool activationStarted; public bool countdownStarted; public float armAt; public float voiceEndsAt; public Vector3 position; public Vector3 normal = Vector3.up; } [Serializable] public sealed class DeviceCommand { public int sequence; public int objectId; public int timer; public int kind; public string action; public Vector3 position; public Vector3 normal; } [Serializable] public sealed class DeviceSnapshot { public List<DeviceState> devices = new List<DeviceState>(); } public struct CommandMessage : IBroadcast { public string json; } public struct StateMessage : IBroadcast { public string json; } public struct ReplyMessage : IBroadcast { public string text; } [Serializable] public sealed class DetonationEvent { public byte kind; public Vector3 position; public string sound; public float radius; } public struct NukeFlashMessage : IBroadcast { public string json; } [BepInPlugin("ponyfisher.howtofish.boomgoesthedynamite", "Boom goes the Dynamite", "0.2.5")] [DefaultExecutionOrder(29400)] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "ponyfisher.howtofish.boomgoesthedynamite"; public static Plugin Instance; public static readonly byte[] Ids = new byte[4] { 237, 236, 235, 234 }; public static readonly ushort[] Collections = new ushort[4] { 42433, 42434, 42435, 42436 }; public static readonly string[] Names = new string[4] { "Super Dynamite", "Nuke", "Time Bomb", "Proximity Mine" }; public static readonly int[] Prices = new int[4] { 100, 1000, 150, 200 }; public static readonly float[] DamageRadius = new float[4] { 13f, 250f, 8f, 7f }; public static readonly int[] Damage = new int[4] { 250, 15000, 100, 110 }; public static readonly Explosive[] Prefabs = (Explosive[])(object)new Explosive[4]; private static int vanillaDamage; private static float vanillaRadius; private static float vanillaSoundVolume; public static bool SuppressDrop; public readonly List<DeviceState> Devices = new List<DeviceState>(); private NetworkManager manager; private Harmony harmony; private bool registrationFailed; private bool menuOpen; private int sequence; private float nextState; private float nextTick; private float nextIcon; private float nextNukeAudio; private float holdFStarted; private float holdEStarted; private float nukeHoldStart; private float nukePickupStart; private bool fHolding; private bool eHolding; private bool holdEFired; private Item holdItem; private Item nukeTarget; private Item nukePickupTarget; private NPC vendor; private string status = ""; private float statusUntil; private readonly HashSet<int> detonatedNukes = new HashSet<int>(); private string currentWorld; private readonly Dictionary<int, int> lastSequence = new Dictionary<int, int>(); private Rect window = new Rect(0f, 0f, 610f, 460f); private bool windowReady; private int chosenTimer = 5; private GUIStyle titleStyle; private GUIStyle boxStyle; private GUIStyle buttonStyle; private GUIStyle warningStyle; private bool flashActive; private bool flashMuted; private float flashStart; private float oldListenerVolume; private AudioSource aftermathTone; private float nukeProgress; private float nukePickupProgress; private bool timerOpen; public bool MenuOpen => menuOpen; public void TryRegister() { if (!registrationFailed && (Object)(object)Prefabs[0] == (Object)null) { RegisterPrefabs(); } } public void ReportRegistration(Exception error) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Dynamite registration deferred: " + error.Message)); } private static string Json(object value) { return JsonUtility.ToJson(value); } private static T Parse<T>(string json) { return JsonUtility.FromJson<T>(json); } public static bool IsBoom(Item item) { if ((Object)(object)item != (Object)null && Array.IndexOf(Ids, item.ID) >= 0) { return (Object)(object)((Component)item).GetComponent<BoomVisual>() != (Object)null; } return false; } public static DeviceKind Kind(Item item) { return (DeviceKind)Array.IndexOf(Ids, item.ID); } public DeviceState Find(Item item) { if ((Object)(object)item == (Object)null) { return null; } NetworkObject net = ((Component)item).GetComponent<NetworkObject>(); if (!((Object)(object)net == (Object)null)) { return Devices.FirstOrDefault((DeviceState s) => s.objectId == net.ObjectId); } return null; } private static FieldInfo Field(Type type, string name) { return AccessTools.Field(type, name); } public static bool Activated(Explosive explosive) { if ((Object)(object)explosive != (Object)null) { return (bool)Field(typeof(Explosive), "_isActivated").GetValue(explosive); } return false; } public static float Remaining(Explosive explosive) { if (!((Object)(object)explosive == (Object)null)) { return (float)Field(typeof(Explosive), "_timeUntilExplosion").GetValue(explosive); } return 0f; } private void Awake() { //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Expected O, but got Unknown Instance = this; GenericWriter<CommandMessage>.SetWrite((Action<Writer, CommandMessage>)delegate(Writer w, CommandMessage v) { w.WriteString(v.json); }); GenericReader<CommandMessage>.SetRead((Func<Reader, CommandMessage>)((Reader r) => new CommandMessage { json = r.ReadStringAllocated() })); GenericWriter<StateMessage>.SetWrite((Action<Writer, StateMessage>)delegate(Writer w, StateMessage v) { w.WriteString(v.json); }); GenericReader<StateMessage>.SetRead((Func<Reader, StateMessage>)((Reader r) => new StateMessage { json = r.ReadStringAllocated() })); GenericWriter<ReplyMessage>.SetWrite((Action<Writer, ReplyMessage>)delegate(Writer w, ReplyMessage v) { w.WriteString(v.text); }); GenericReader<ReplyMessage>.SetRead((Func<Reader, ReplyMessage>)((Reader r) => new ReplyMessage { text = r.ReadStringAllocated() })); GenericWriter<NukeFlashMessage>.SetWrite((Action<Writer, NukeFlashMessage>)delegate(Writer w, NukeFlashMessage v) { w.WriteString(v.json); }); GenericReader<NukeFlashMessage>.SetRead((Func<Reader, NukeFlashMessage>)((Reader r) => new NukeFlashMessage { json = r.ReadStringAllocated() })); NukeAudio.EnsureLoaded((MonoBehaviour)(object)this); harmony = new Harmony("ponyfisher.howtofish.boomgoesthedynamite"); harmony.PatchAll(typeof(Plugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Boom goes the Dynamite 0.2.5 loaded."); } private void RegisterNetwork() { if ((Object)(object)manager != (Object)null) { manager.ServerManager.UnregisterBroadcast<CommandMessage>((Action<NetworkConnection, CommandMessage, Channel>)Receive); manager.ClientManager.UnregisterBroadcast<StateMessage>((Action<StateMessage, Channel>)ReceiveState); manager.ClientManager.UnregisterBroadcast<ReplyMessage>((Action<ReplyMessage, Channel>)ReceiveReply); manager.ClientManager.UnregisterBroadcast<NukeFlashMessage>((Action<NukeFlashMessage, Channel>)ReceiveFlash); } manager = InstanceFinder.NetworkManager; if (!((Object)(object)manager == (Object)null)) { manager.ServerManager.RegisterBroadcast<CommandMessage>((Action<NetworkConnection, CommandMessage, Channel>)Receive, true); manager.ClientManager.RegisterBroadcast<StateMessage>((Action<StateMessage, Channel>)ReceiveState); manager.ClientManager.RegisterBroadcast<ReplyMessage>((Action<ReplyMessage, Channel>)ReceiveReply); manager.ClientManager.RegisterBroadcast<NukeFlashMessage>((Action<NukeFlashMessage, Channel>)ReceiveFlash); } } private void Update() { if ((Object)(object)manager != (Object)(object)InstanceFinder.NetworkManager) { RegisterNetwork(); } if (!registrationFailed && (Object)(object)Prefabs[0] == (Object)null) { try { RegisterPrefabs(); } catch (Exception ex) { registrationFailed = true; ((BaseUnityPlugin)this).Logger.LogError((object)ex); Say("Dynamite registration failed; see BepInEx log."); } } if (Time.unscaledTime >= nextIcon) { nextIcon = Time.unscaledTime + 0.25f; BoomInventoryIcon.RefreshAll(); } if (Time.unscaledTime >= nextNukeAudio) { nextNukeAudio = Time.unscaledTime + 5f; NukeAudio.EnsureLoaded((MonoBehaviour)(object)this); } Player localPlayer = Player.LocalPlayer; vendor = FocusedVendor(localPlayer); Keyboard current = Keyboard.current; if (current != null) { bool flag = (Object)(object)localPlayer != (Object)null && ((IsBoom(localPlayer.Holding.HeldItem) && Kind(localPlayer.Holding.HeldItem) == DeviceKind.Nuke) || (Object)(object)RayNuke(localPlayer) != (Object)null); if ((Object)(object)vendor != (Object)null && !flag && !menuOpen && ((ButtonControl)current.fKey).wasPressedThisFrame) { fHolding = true; holdFStarted = Time.unscaledTime; } if (fHolding && ((ButtonControl)current.fKey).isPressed && (Object)(object)vendor != (Object)null && !flag && Time.unscaledTime - holdFStarted >= 0.8f) { fHolding = false; OpenMenu(); } if (!((ButtonControl)current.fKey).isPressed || (Object)(object)vendor == (Object)null || flag) { fHolding = false; } if (!menuOpen) { UpdateHeldInteraction(current, localPlayer); UpdateNukeActivation(current, localPlayer); UpdateNukePickup(current, localPlayer); } if (menuOpen && ((ButtonControl)current.escapeKey).wasPressedThisFrame) { CloseMenu(); } } UpdateFlash(); if (InstanceFinder.IsServerStarted) { string text = ((SaveManager.CurServerSave == null) ? null : SaveManager.CurServerSave.Name); if (currentWorld != text) { currentWorld = text; detonatedNukes.Clear(); Devices.Clear(); } if (Time.unscaledTime >= nextTick) { nextTick = Time.unscaledTime + 0.15f; ServerTick(); } if (Time.unscaledTime >= nextState) { nextState = Time.unscaledTime + 0.35f; Broadcast(); } } else if (currentWorld != null) { currentWorld = null; detonatedNukes.Clear(); Devices.Clear(); } } private static ExplosionInfo CopyExplosion(ExplosionInfo source) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ExplosionInfo val = new ExplosionInfo(); FieldInfo[] fields = typeof(ExplosionInfo).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (!fieldInfo.IsInitOnly) { fieldInfo.SetValue(val, fieldInfo.GetValue(source)); } } Field(typeof(ExplosionInfo), "<HasExploded>k__BackingField")?.SetValue(val, false); return val; } internal static void SetExplosion(Explosive item, DeviceKind kind) { ExplosionInfo val = CopyExplosion(((Item)item).GetExplosionInfo()); int num = ((kind == DeviceKind.Super) ? Math.Min(1073741823, ((vanillaDamage > 0) ? vanillaDamage : val.Damage) * 3) : Damage[(uint)kind]); float num2 = ((kind == DeviceKind.Super) ? (((vanillaRadius > 0f) ? vanillaRadius : val.DamageRadius) * 3f) : DamageRadius[(uint)kind]); Field(typeof(ExplosionInfo), "_damage").SetValue(val, num); Field(typeof(ExplosionInfo), "damageRadius").SetValue(val, num2); Field(typeof(ExplosionInfo), "_forceRadius").SetValue(val, num2 * 1.1f); if (kind == DeviceKind.Nuke) { Field(typeof(ExplosionInfo), "_explosionSoundVol").SetValue(val, Mathf.Max(1f, vanillaSoundVolume * 3f)); } Field(typeof(Explosive), "_explosionInfo").SetValue(item, val); Field(typeof(Explosive), "_forcedExplosionDelay").SetValue(item, kind switch { DeviceKind.Timer => 5f, DeviceKind.Mine => 0.5f, _ => 5f, }); Field(typeof(Explosive), "_activatedExplosionDelay").SetValue(item, kind switch { DeviceKind.Mine => 0.5f, DeviceKind.Nuke => 10f, _ => 5f, }); Field(typeof(Explosive), "_activatable").SetValue(item, kind == DeviceKind.Super); if (kind == DeviceKind.Super) { Field(typeof(Explosive), "_fuseLightPercent").SetValue(item, 0f); } } private void RegisterPrefabs() { //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)InstanceFinder.NetworkManager == (Object)null) { return; } Dictionary<byte, Item> dictionary = (Dictionary<byte, Item>)Field(typeof(GameInfo), "_idToSpawnable").GetValue(null); if (dictionary.Count == 0) { return; } Explosive val = (from e in dictionary.Values.OfType<Explosive>() where ((object)e).GetType() == typeof(Explosive) && (Object)(object)((Component)e).GetComponent<NetworkObject>() != (Object)null && (Object)(object)((Component)e).GetComponent<BoomVisual>() == (Object)null orderby ((Item)e).ID select e).FirstOrDefault(); if ((Object)(object)val == (Object)null) { return; } vanillaDamage = ((Item)val).GetExplosionInfo().Damage; vanillaRadius = ((Item)val).GetExplosionInfo().DamageRadius; vanillaSoundVolume = ((Item)val).GetExplosionInfo().ExplosionSoundVol; for (int num = 0; num < 4; num++) { if (dictionary.ContainsKey(Ids[num])) { throw new Exception("Item ID " + Ids[num] + " is occupied by another mod."); } } GameObject val2 = new GameObject("Boom Dynamite prefab storage"); val2.SetActive(false); Object.DontDestroyOnLoad((Object)(object)val2); for (int num2 = 0; num2 < 4; num2++) { DeviceKind deviceKind = (DeviceKind)num2; Explosive val3 = Object.Instantiate<Explosive>(val, val2.transform); ((Object)val3).name = Names[num2]; Field(typeof(Item), "_id").SetValue(val3, Ids[num2]); Field(typeof(Item), "_cost").SetValue(val3, Prices[num2]); Field(typeof(Item), "_worth").SetValue(val3, Prices[num2] / 2); Field(typeof(Item), "_ignoredByMoneyNPC").SetValue(val3, false); Field(typeof(Item), "_heldPos").SetValue(val3, (object)new Vector3(0.18f, -0.34f, 0.7f)); Field(typeof(Item), "_heldRot").SetValue(val3, (object)new Vector3(0f, 25f, 0f)); SetExplosion(val3, deviceKind); Renderer[] componentsInChildren = ((Component)val3).GetComponentsInChildren<Renderer>(true); for (int num3 = 0; num3 < componentsInChildren.Length; num3++) { componentsInChildren[num3].enabled = false; } BoomVisual boomVisual = ((Component)val3).gameObject.AddComponent<BoomVisual>(); boomVisual.Build(deviceKind); Field(typeof(Item), "_renderers").SetValue(val3, (from r in ((Component)boomVisual).GetComponentsInChildren<Renderer>(true) where r.enabled select r).ToList()); Field(typeof(Item), "_mesh").SetValue(val3, boomVisual.InventoryMesh); Field(typeof(Item), "_inventoryMeshScale").SetValue(val3, 0.7f); Field(typeof(Item), "_inventoryMeshPos").SetValue(val3, Vector3.zero); Field(typeof(Item), "_inventoryMeshRot").SetValue(val3, (object)new Vector3(20f, 35f, 0f)); NetworkObject component = ((Component)val3).GetComponent<NetworkObject>(); component.SetIsSpawnable(true); PrefabObjects prefabObjects = manager.GetPrefabObjects<SinglePrefabObjects>(Collections[num2], true); if (prefabObjects.GetObjectCount() != 0) { throw new Exception("Prefab collection " + Collections[num2] + " is occupied."); } prefabObjects.AddObject(component, false, true); dictionary.Add(Ids[num2], (Item)(object)val3); ((Dictionary<byte, Item>)Field(typeof(GameInfo), "_allItems").GetValue(null)).Add(Ids[num2], (Item)(object)val3); ((Dictionary<string, Item>)Field(typeof(GameInfo), "_nameToSpawnable").GetValue(null)).Add("boomdynamite_" + deviceKind.ToString().ToLowerInvariant(), (Item)(object)val3); Prefabs[num2] = val3; } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered four Boom Dynamite explosive items."); } private int OpenSlot(Player player) { int num = (int)AccessTools.Method(typeof(PlayerInventory), "GetTotalSlots", (Type[])null, (Type[])null).Invoke(player.Inventory, null); Item val = default(Item); for (byte b = 0; b < num; b++) { if (!player.Inventory._items.TryGetValue(b, ref val) || (Object)(object)val == (Object)null) { return b; } } return -1; } private void Receive(NetworkConnection connection, CommandMessage message, Channel channel) { if (!InstanceFinder.IsServerStarted || string.IsNullOrEmpty(message.json) || message.json.Length > 2000) { return; } try { DeviceCommand deviceCommand = Parse<DeviceCommand>(message.json); if (deviceCommand != null && deviceCommand.sequence > 0 && (!lastSequence.TryGetValue(connection.ClientId, out var value) || deviceCommand.sequence > value)) { lastSequence[connection.ClientId] = deviceCommand.sequence; Player val = ((IEnumerable<Player>)Object.FindObjectsByType<Player>()).FirstOrDefault((Func<Player, bool>)((Player p) => ((NetworkBehaviour)p).Owner == connection)); if ((Object)(object)val != (Object)null) { Execute(val, deviceCommand, connection); } } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Rejected dynamite request: " + ex.Message)); } } private void ReceiveState(StateMessage message, Channel channel) { if (InstanceFinder.IsServerStarted || string.IsNullOrEmpty(message.json)) { return; } DeviceSnapshot deviceSnapshot = Parse<DeviceSnapshot>(message.json); if (deviceSnapshot == null || deviceSnapshot.devices == null) { return; } Devices.Clear(); Devices.AddRange(deviceSnapshot.devices); foreach (DeviceState device in Devices) { if (device.kind == 2) { Item obj = FindItem(device.objectId); Explosive val = (Explosive)(object)((obj is Explosive) ? obj : null); if ((Object)(object)val != (Object)null) { Field(typeof(Explosive), "_forcedExplosionDelay").SetValue(val, (float)device.timer); } } } } private void ReceiveReply(ReplyMessage message, Channel channel) { Say(message.text); } private void ReceiveFlash(NukeFlashMessage message, Channel channel) { if (InstanceFinder.IsServerStarted || string.IsNullOrEmpty(message.json)) { return; } try { DetonationEvent detonationEvent = Parse<DetonationEvent>(message.json); if (detonationEvent != null) { ShowDetonation(detonationEvent); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Invalid detonation event: " + ex.Message)); } } private void Broadcast() { if ((Object)(object)manager != (Object)null) { manager.ServerManager.Broadcast<StateMessage>(new StateMessage { json = Json(new DeviceSnapshot { devices = Devices }) }, true, (Channel)0); } } private void Say(string message) { status = message; statusUntil = Time.unscaledTime + 4f; } private void Reply(NetworkConnection connection, string message) { if (connection == (NetworkConnection)null || connection.IsLocalClient) { Say(message); return; } manager.ServerManager.Broadcast<ReplyMessage>(connection, new ReplyMessage { text = message }, true, (Channel)0); } private void Send(string action, int kind = 0, Item item = null, Vector3 position = default(Vector3), Vector3 normal = default(Vector3), int timer = 5) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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) Player localPlayer = Player.LocalPlayer; if (!((Object)(object)localPlayer == (Object)null)) { NetworkObject val = (((Object)(object)item == (Object)null) ? null : ((Component)item).GetComponent<NetworkObject>()); DeviceCommand deviceCommand = new DeviceCommand { action = action, kind = kind, objectId = ((!((Object)(object)val == (Object)null)) ? val.ObjectId : 0), position = position, normal = normal, timer = timer, sequence = ++sequence }; if (InstanceFinder.IsServerStarted) { Execute(localPlayer, deviceCommand, null); } else if ((Object)(object)manager != (Object)null && InstanceFinder.IsClientStarted) { manager.ClientManager.Broadcast<CommandMessage>(new CommandMessage { json = Json(deviceCommand) }, (Channel)0); } } } private Item FindItem(int objectId) { return ((IEnumerable<Item>)Object.FindObjectsByType<Item>()).FirstOrDefault((Func<Item, bool>)delegate(Item i) { if (IsBoom(i)) { NetworkObject component = ((Component)i).GetComponent<NetworkObject>(); if (component == null) { return false; } return component.ObjectId == objectId; } return false; }); } private bool ValidSurface(Player player, DeviceCommand cmd, Item item) { //IL_0001: 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_0040: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) if (!Finite(cmd.position) || !Finite(cmd.normal) || ((Vector3)(ref cmd.normal)).sqrMagnitude < 0.5f || (Object)(object)player.CamObject == (Object)null || Vector3.Distance(player.CamObject.position, cmd.position) > 8.5f) { return false; } if (Kind(item) == DeviceKind.Nuke && ((Vector3)(ref cmd.normal)).normalized.y < Mathf.Cos((float)Math.PI / 6f)) { return false; } foreach (RaycastHit item2 in from h in Physics.RaycastAll(cmd.position + ((Vector3)(ref cmd.normal)).normalized * 0.25f, -((Vector3)(ref cmd.normal)).normalized, 0.55f, -1, (QueryTriggerInteraction)2) orderby ((RaycastHit)(ref h)).distance select h) { RaycastHit current = item2; if ((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Item>() != (Object)(object)item && (Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Player>() == (Object)null && Vector3.Dot(((RaycastHit)(ref current)).normal, ((Vector3)(ref cmd.normal)).normalized) > 0.7f) { return true; } } return false; } private static bool Finite(Vector3 v) { //IL_0000: 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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (!float.IsNaN(v.x) && !float.IsNaN(v.y) && !float.IsNaN(v.z) && !float.IsInfinity(v.x) && !float.IsInfinity(v.y)) { return !float.IsInfinity(v.z); } return false; } private void Execute(Player player, DeviceCommand cmd, NetworkConnection connection) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_0567: Unknown result type (might be due to invalid IL or missing references) //IL_056d: Unknown result type (might be due to invalid IL or missing references) //IL_0571: Unknown result type (might be due to invalid IL or missing references) //IL_0577: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_03cd: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_067f: Unknown result type (might be due to invalid IL or missing references) //IL_0684: Unknown result type (might be due to invalid IL or missing references) //IL_068c: Unknown result type (might be due to invalid IL or missing references) //IL_0693: Unknown result type (might be due to invalid IL or missing references) //IL_069d: Unknown result type (might be due to invalid IL or missing references) //IL_06a2: Unknown result type (might be due to invalid IL or missing references) //IL_06a7: Unknown result type (might be due to invalid IL or missing references) //IL_06c9: Unknown result type (might be due to invalid IL or missing references) //IL_06ce: Unknown result type (might be due to invalid IL or missing references) //IL_06d5: Unknown result type (might be due to invalid IL or missing references) //IL_06da: Unknown result type (might be due to invalid IL or missing references) //IL_06fd: Unknown result type (might be due to invalid IL or missing references) //IL_0710: Expected O, but got Unknown if (player.Dying.IsDead) { return; } try { if (cmd.action == "buy") { int kind = cmd.kind; if (kind < 0 || kind >= 4 || (Object)(object)Prefabs[kind] == (Object)null || !NearMoneyVendor(player)) { Reply(connection, "Stay near a shopkeeper to buy dynamite."); return; } int num = OpenSlot(player); if (num < 0) { Reply(connection, "Free an inventory slot first."); return; } if (!Wallet.Charge(player, Prices[kind])) { Reply(connection, "Not enough money."); return; } try { Explosive val = Object.Instantiate<Explosive>(Prefabs[kind], ((Component)player).transform.position + Vector3.up, Quaternion.identity, Server.Instance.DynamicObjectsHolder); ((Item)val).LoadFromSave(new SavedItem { Exists = true, ItemID = Ids[kind], BettingMultiplier = 1f, Weight = 1f, KillScoreMultiplier = 1f }); InstanceFinder.ServerManager.Spawn(((Component)val).gameObject, (NetworkConnection)null, default(Scene)); ((Item)val).SetSyncedHolder(player, true); player.Inventory.AddItem((byte)num, (Item)(object)val); if (!player.Inventory.HasItemInInventory((Item)(object)val)) { throw new Exception("Inventory rejected the item."); } Reply(connection, Names[kind] + " purchased for $" + Prices[kind] + "."); return; } catch { Wallet.Credit(player, Prices[kind]); throw; } } Item val2 = FindItem(cmd.objectId); if ((Object)(object)val2 == (Object)null) { Reply(connection, "Explosive unavailable."); return; } DeviceKind deviceKind = Kind(val2); DeviceState deviceState; Vector3 val3; if (cmd.action == "activate") { if (deviceKind != DeviceKind.Nuke) { return; } deviceState = Find(val2); bool flag = (Object)(object)val2.SyncedHolder == (Object)(object)player; if (deviceState == null && flag) { deviceState = new DeviceState { objectId = cmd.objectId, kind = 1 }; Devices.Add(deviceState); } if (deviceState == null || deviceState.activationStarted || (!deviceState.deployed && !flag)) { return; } if (!flag) { if (!((Object)(object)player.CamObject == (Object)null) && !(Vector3.Distance(player.CamObject.position, ((Component)val2).transform.position) > 5.5f)) { Vector3 forward = player.CamObject.forward; val3 = ((Component)val2).transform.position + Vector3.up * 0.45f - player.CamObject.position; if (!(Vector3.Dot(forward, ((Vector3)(ref val3)).normalized) < 0.75f)) { goto IL_02e9; } } Reply(connection, "Look at the deployed nuke from nearby."); return; } goto IL_02e9; } if (cmd.action == "pickup") { DeviceState deviceState2 = Find(val2); if (deviceKind != DeviceKind.Nuke || deviceState2 == null || !deviceState2.deployed || (Object)(object)val2.SyncedHolder != (Object)null) { Reply(connection, "That nuke is not deployed."); return; } if (!((Object)(object)player.CamObject == (Object)null) && !(Vector3.Distance(player.CamObject.position, ((Component)val2).transform.position) > 5.5f)) { Vector3 forward2 = player.CamObject.forward; val3 = ((Component)val2).transform.position + Vector3.up * 0.45f - player.CamObject.position; if (!(Vector3.Dot(forward2, ((Vector3)(ref val3)).normalized) < 0.75f)) { int num2 = OpenSlot(player); bool flag2 = (Object)(object)player.Holding.HeldItem == (Object)null && (Object)(object)player.Holding.UninitializedHeldItem == (Object)null && (Object)(object)player.Inventory.SyncedCurItem == (Object)null; if (num2 < 0 && !flag2) { Reply(connection, "Free an inventory slot or empty your hands first."); return; } deviceState2.deployed = false; val2.RigidbodySync.SetKinematic(false); int value = player.Inventory._syncedCurSlot.Value; val2.SetSyncedHolder(player, true); if (num2 >= 0) { player.Inventory.AddItem((byte)num2, val2); } val2.ReconcileLocalHolderWithSyncedHolder(); if (num2 >= 0) { player.Inventory.ServerSetSyncedCurSlot(value); } if (!deviceState2.activationStarted) { Devices.Remove(deviceState2); } Broadcast(); Reply(connection, "Nuke picked up."); return; } } Reply(connection, "Look at the deployed nuke from nearby."); } else if ((Object)(object)val2.SyncedHolder != (Object)(object)player || deviceKind == DeviceKind.Super) { Reply(connection, "Hold that explosive before placing it."); } else { if (!(cmd.action == "deploy")) { return; } if (!ValidSurface(player, cmd, val2)) { Reply(connection, (deviceKind == DeviceKind.Nuke) ? "Place the nuke on level ground or a slope under 30 degrees." : "Look at a surface within 8 metres."); return; } SuppressDrop = true; try { val2.SpawnFromInventory(); player.Inventory.RemoveItem(val2); if ((Object)(object)val2.Holder != (Object)null) { val3 = default(Vector3); Vector3 val4 = val3; val3 = default(Vector3); val2.Drop(false, val4, val3); } val2.SetSyncedHolder((Player)null, true); val2.ReconcileLocalHolderWithSyncedHolder(); if ((Object)(object)player.Holding.HeldItem == (Object)(object)val2) { player.Hands.DropItem(false, val2); player.Holding.DropItem(false, val2); player.Holding.SetHeldItem((Item)null); } if ((Object)(object)player.Holding.UninitializedHeldItem == (Object)(object)val2) { player.Holding.SetUninitializedHeldItem((Item)null); } } finally { SuppressDrop = false; } DeviceState deviceState3 = Find(val2); if (deviceState3 == null) { deviceState3 = new DeviceState { objectId = cmd.objectId, kind = (byte)deviceKind }; Devices.Add(deviceState3); } deviceState3.deployed = true; deviceState3.armed = false; if (deviceKind != DeviceKind.Nuke) { deviceState3.activationStarted = false; deviceState3.countdownStarted = false; } deviceState3.armAt = ((deviceKind == DeviceKind.Mine) ? (Time.unscaledTime + 1f) : 0f); deviceState3.timer = Mathf.Clamp(cmd.timer, 5, 20); deviceState3.normal = ((Vector3)(ref cmd.normal)).normalized; deviceState3.position = cmd.position + deviceState3.normal * 0.04f; val2.RigidbodySync.ServerSetSyncedSimulator(((NetworkBehaviour)Server.Instance).Owner); val2.RigidbodySync.TeleportToPosRot(deviceState3.position, Quaternion.FromToRotation(Vector3.up, deviceState3.normal), (float[])null, (Quaternion[])null); val2.RigidbodySync.SetKinematic(true); Broadcast(); if (deviceKind == DeviceKind.Timer) { Arm((Explosive)val2, deviceState3.timer, player); } Reply(connection, deviceKind switch { DeviceKind.Nuke => "Nuke deployed. Hold F to activate or hold E to pick it up.", DeviceKind.Timer => "Time Bomb deployed; " + deviceState3.timer + "-second timer started.", _ => "Proximity Mine deployed; arming for one second.", }); } return; IL_02e9: deviceState.activationStarted = true; deviceState.voiceEndsAt = Time.unscaledTime + NukeAudio.Duration; Broadcast(); Reply(connection, "Nuke activated. Get clear!"); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)ex); Reply(connection, "Dynamite action failed; check the BepInEx log."); } } public static void Arm(Explosive explosive, float seconds, Player player) { if (!((Object)(object)explosive == (Object)null) && ((NetworkBehaviour)explosive).IsServerInitialized && !Activated(explosive)) { Field(typeof(Explosive), "_forcedExplosionDelay").SetValue(explosive, seconds); explosive.ForceExplode(player, false); } } public bool CanArmNuke(Explosive item) { DeviceState deviceState = Find((Item)(object)item); if (deviceState != null && deviceState.activationStarted) { return deviceState.countdownStarted; } return false; } public void OnDetonation(Explosive explosive) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) if (!InstanceFinder.IsServerStarted || (Object)(object)explosive == (Object)null) { return; } DeviceKind deviceKind = Kind((Item)(object)explosive); if (deviceKind != DeviceKind.Nuke && deviceKind != DeviceKind.Super) { return; } NetworkObject component = ((Component)explosive).GetComponent<NetworkObject>(); int item = (((Object)(object)component == (Object)null) ? ((object)explosive).GetHashCode() : component.ObjectId); if (!detonatedNukes.Add(item)) { return; } DetonationEvent detonationEvent = new DetonationEvent { kind = (byte)deviceKind, position = ((Component)explosive).transform.position, sound = ((Item)explosive).GetExplosionInfo().ExplosionSoundName, radius = ((Item)explosive).GetExplosionInfo().DamageRadius }; if ((Object)(object)manager != (Object)null) { manager.ServerManager.Broadcast<NukeFlashMessage>(new NukeFlashMessage { json = Json(detonationEvent) }, true, (Channel)0); } if ((Object)(object)Player.LocalPlayer != (Object)null) { ShowDetonation(detonationEvent); } if (deviceKind != DeviceKind.Nuke) { return; } Creature[] array = Object.FindObjectsByType<Creature>(); foreach (Creature val in array) { if (!((Object)(object)val == (Object)null) && !val.IsDead) { val.ServerChangeHp(Mathf.Max(1, val.Hp)); if (!val.IsDead) { object obj = Field(typeof(Creature), "_hp")?.GetValue(val); (obj?.GetType().GetProperty("Value"))?.SetValue(obj, 0, null); } } } Player[] array2 = Object.FindObjectsByType<Player>(); foreach (Player val2 in array2) { if (!((Object)(object)val2 == (Object)null) && !val2.Dying.IsDead && !PlayerManager.InGodMode) { val2.Vitals.TakeDamage(1000000, Vector3.zero, detonationEvent.position, true); } } } private void ShowDetonation(DetonationEvent effect) { //IL_0009: 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_00b1: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) if (effect.kind == 0) { SuperBlastVisual.Spawn(effect.position, effect.radius); } else { if (effect.kind != 1) { return; } if (flashMuted) { AudioListener.volume = oldListenerVolume; if ((Object)(object)aftermathTone != (Object)null) { Object.Destroy((Object)(object)((Component)aftermathTone).gameObject); } aftermathTone = null; } flashActive = true; flashMuted = false; flashStart = Time.unscaledTime + 0.15f; if (!string.IsNullOrEmpty(effect.sound) && (Object)(object)Player.LocalPlayer != (Object)null) { Vector3 val = (((Object)(object)Player.LocalPlayer.CamObject == (Object)null) ? effect.position : Player.LocalPlayer.CamObject.position); AudioManager.PlayClipAt(effect.sound, val, false, (AudioDistance)3, 1f, 0.05f); AudioManager.PlayClipAt(effect.sound, val, false, (AudioDistance)3, 1f, 0.05f); } } } private void UpdateFlash() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown if (!flashActive || Time.unscaledTime < flashStart) { return; } if (!flashMuted) { oldListenerVolume = AudioListener.volume; flashMuted = true; AudioListener.volume = 0f; GameObject val = new GameObject("Nuke aftermath ringing"); aftermathTone = val.AddComponent<AudioSource>(); aftermathTone.clip = NukeAudio.Tinnitus; aftermathTone.loop = true; aftermathTone.spatialBlend = 0f; aftermathTone.ignoreListenerVolume = true; aftermathTone.volume = 0.18f; aftermathTone.Play(); } float num = Time.unscaledTime - flashStart; float num2 = Mathf.Clamp01((num - 2f) / 2.5f); AudioListener.volume = oldListenerVolume * num2; if ((Object)(object)aftermathTone != (Object)null) { aftermathTone.volume = 0.18f * (1f - num2); } if (num >= 4.5f) { AudioListener.volume = oldListenerVolume; flashActive = false; flashMuted = false; if ((Object)(object)aftermathTone != (Object)null) { Object.Destroy((Object)(object)((Component)aftermathTone).gameObject); } aftermathTone = null; } } private void ServerTick() { //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_0131: 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_0149: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown for (int num = Devices.Count - 1; num >= 0; num--) { DeviceState deviceState = Devices[num]; Item val = FindItem(deviceState.objectId); if ((Object)(object)val == (Object)null) { Devices.RemoveAt(num); } else if (deviceState.kind == 1) { if (deviceState.activationStarted && !deviceState.countdownStarted && Time.unscaledTime >= deviceState.voiceEndsAt) { deviceState.countdownStarted = true; Arm((Explosive)val, 10f, val.LastPlayer); Broadcast(); } } else { if (!deviceState.deployed) { continue; } if ((Object)(object)val.SyncedHolder != (Object)null) { Devices.RemoveAt(num); } else { if (deviceState.kind != 3 || Activated((Explosive)val)) { continue; } if (!deviceState.armed) { if (Time.unscaledTime < deviceState.armAt) { continue; } deviceState.armed = true; Broadcast(); } Creature[] array = Object.FindObjectsByType<Creature>(); foreach (Creature val2 in array) { if ((Object)(object)val2 != (Object)null && !val2.IsDead && Vector3.Distance(((Component)val2).transform.position, deviceState.position) <= 3.5f) { Arm((Explosive)val, 0.5f, val.LastPlayer); Broadcast(); break; } } } } } } private static bool IsMoneyVendor(NPC npc) { if ((Object)(object)npc == (Object)null) { return false; } if (Field(typeof(NPC), "_quests")?.GetValue(npc) is IEnumerable<NPCQuest> source) { return source.Any((NPCQuest q) => (Object)(object)q != (Object)null && (int)q.Type == 1); } return false; } private static Vector3 VendorInteractionPoint(NPC npc) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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) if (!((Object)(object)npc.MouthPosForItems != (Object)null)) { return ((Component)npc).transform.position + Vector3.up; } return npc.MouthPosForItems.position; } private bool NearMoneyVendor(Player player) { //IL_0036: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return false; } Vector3 val = (((Object)(object)player.CamObject != (Object)null) ? player.CamObject.position : (((Component)player).transform.position + Vector3.up)); NPC[] array = Object.FindObjectsByType<NPC>(); foreach (NPC npc in array) { if (IsMoneyVendor(npc) && Vector3.Distance(val, VendorInteractionPoint(npc)) <= 7f) { return true; } } return false; } private NPC FocusedVendor(Player player) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player.CamObject == (Object)null) { return null; } foreach (RaycastHit item in from h in Physics.RaycastAll(player.CamObject.position, player.CamObject.forward, 5.5f, -1, (QueryTriggerInteraction)2) orderby ((RaycastHit)(ref h)).distance select h) { RaycastHit current = item; if (!((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Player>() == (Object)(object)player)) { NPC componentInParent = ((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<NPC>(); if (IsMoneyVendor(componentInParent)) { return componentInParent; } if (!((RaycastHit)(ref current)).collider.isTrigger) { break; } } } NPC result = null; float num = 0.72f; NPC[] array = Object.FindObjectsByType<NPC>(); foreach (NPC val in array) { if (!IsMoneyVendor(val)) { continue; } Vector3 val2 = VendorInteractionPoint(val) - player.CamObject.position; float magnitude = ((Vector3)(ref val2)).magnitude; if (!(magnitude > 5.5f) && !(magnitude < 0.01f)) { float num3 = Vector3.Dot(player.CamObject.forward, val2 / magnitude); if (num3 > num) { result = val; num = num3; } } } return result; } private bool CrosshairSurface(Item held, out RaycastHit surface) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) surface = default(RaycastHit); Player localPlayer = Player.LocalPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)localPlayer.CamObject == (Object)null) { return false; } foreach (RaycastHit item in from h in Physics.RaycastAll(localPlayer.CamObject.position, localPlayer.CamObject.forward, 8f, -1, (QueryTriggerInteraction)2) orderby ((RaycastHit)(ref h)).distance select h) { RaycastHit current = item; if (!((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Player>() == (Object)(object)localPlayer) && !((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Item>() == (Object)(object)held)) { surface = current; return true; } } return false; } private void UpdateHeldInteraction(Keyboard kb, Player player) { //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: 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) if ((Object)(object)player == (Object)null || player.BlockInputs || player.Dying.IsDead) { eHolding = false; holdItem = null; return; } Item val = (((Object)(object)player == (Object)null) ? null : player.Holding.HeldItem); if (((ButtonControl)kb.eKey).wasPressedThisFrame && IsBoom(val) && (Kind(val) == DeviceKind.Timer || Kind(val) == DeviceKind.Mine || Kind(val) == DeviceKind.Nuke)) { holdItem = val; eHolding = true; holdEFired = false; holdEStarted = Time.unscaledTime; } if (eHolding && (Object)(object)holdItem != (Object)null && ((ButtonControl)kb.eKey).isPressed && !holdEFired && Kind(holdItem) != DeviceKind.Nuke && Time.unscaledTime - holdEStarted >= 0.8f) { holdEFired = true; if ((Object)(object)holdItem == (Object)null || (Object)(object)holdItem != (Object)(object)val) { return; } if (!CrosshairSurface(holdItem, out var surface)) { Say("Look at a surface within 8 metres."); return; } Send("deploy", 0, holdItem, ((RaycastHit)(ref surface)).point, ((RaycastHit)(ref surface)).normal, chosenTimer); } if (((ButtonControl)kb.eKey).wasReleasedThisFrame && eHolding && !holdEFired && (Object)(object)holdItem == (Object)(object)val && Kind(val) == DeviceKind.Timer) { OpenTimer(); } if (((ButtonControl)kb.eKey).wasReleasedThisFrame && eHolding && !holdEFired && (Object)(object)holdItem == (Object)(object)val && Kind(val) == DeviceKind.Nuke && Time.unscaledTime - holdEStarted < 0.8f) { if (CrosshairSurface(val, out var surface2)) { Send("deploy", 0, val, ((RaycastHit)(ref surface2)).point, ((RaycastHit)(ref surface2)).normal, chosenTimer); } else { Say("Look at level ground to place the nuke."); } } if (!((ButtonControl)kb.eKey).isPressed) { eHolding = false; holdItem = null; } } private Item RayNuke(Player player) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player.CamObject == (Object)null) { return null; } foreach (RaycastHit item in from h in Physics.RaycastAll(player.CamObject.position, player.CamObject.forward, 5f, -1, (QueryTriggerInteraction)2) orderby ((RaycastHit)(ref h)).distance select h) { RaycastHit current = item; if ((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Player>() == (Object)(object)player) { continue; } Item componentInParent = ((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Item>(); if (IsBoom(componentInParent) && Kind(componentInParent) == DeviceKind.Nuke) { DeviceState deviceState = Find(componentInParent); if (deviceState != null && deviceState.deployed && (Object)(object)componentInParent.SyncedHolder == (Object)null) { return componentInParent; } } if (!((RaycastHit)(ref current)).collider.isTrigger) { break; } } return null; } public bool LookingAtNuke() { return (Object)(object)RayNuke(Player.LocalPlayer) != (Object)null; } private void UpdateNukeActivation(Keyboard kb, Player player) { //IL_0136: 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_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || player.BlockInputs || player.Dying.IsDead) { nukeTarget = null; nukeHoldStart = 0f; nukeProgress = 0f; return; } Item heldItem = player.Holding.HeldItem; Item val = ((IsBoom(heldItem) && Kind(heldItem) == DeviceKind.Nuke && (Find(heldItem) == null || !Find(heldItem).activationStarted)) ? heldItem : RayNuke(player)); if ((Object)(object)val != (Object)null) { DeviceState deviceState = Find(val); if (deviceState != null && deviceState.activationStarted) { val = null; } } if ((Object)(object)val != (Object)(object)nukeTarget) { nukeTarget = val; nukeHoldStart = 0f; nukeProgress = 0f; } if ((Object)(object)val == (Object)null) { return; } if (((ButtonControl)kb.fKey).wasPressedThisFrame) { nukeHoldStart = Time.unscaledTime; } if (((ButtonControl)kb.fKey).isPressed && nukeHoldStart > 0f) { nukeProgress = Mathf.Clamp01((Time.unscaledTime - nukeHoldStart) / 5f); if (nukeProgress >= 1f) { Send("activate", 0, val); nukeHoldStart = 0f; nukeProgress = 0f; nukeTarget = null; } } if (((ButtonControl)kb.fKey).wasReleasedThisFrame) { nukeHoldStart = 0f; nukeProgress = 0f; } } private void UpdateNukePickup(Keyboard kb, Player player) { //IL_00df: 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_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || player.BlockInputs || player.Dying.IsDead) { nukePickupTarget = null; nukePickupStart = 0f; nukePickupProgress = 0f; return; } Item val = RayNuke(player); if ((Object)(object)val != (Object)(object)nukePickupTarget) { nukePickupTarget = val; nukePickupStart = 0f; nukePickupProgress = 0f; } if ((Object)(object)val == (Object)null) { return; } if (((ButtonControl)kb.eKey).wasPressedThisFrame) { nukePickupStart = Time.unscaledTime; } if (((ButtonControl)kb.eKey).isPressed && nukePickupStart > 0f) { nukePickupProgress = Mathf.Clamp01((Time.unscaledTime - nukePickupStart) / 1f); if (nukePickupProgress >= 1f) { Send("pickup", 0, val); nukePickupStart = 0f; nukePickupProgress = 0f; nukePickupTarget = null; } } if (((ButtonControl)kb.eKey).wasReleasedThisFrame) { nukePickupStart = 0f; nukePickupProgress = 0f; } } private void OpenMenu() { menuOpen = true; timerOpen = false; SetWindow(); Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; PlayerCamera.ToggleMouse(true); } private void OpenTimer() { menuOpen = true; timerOpen = true; SetWindow(); Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; PlayerCamera.ToggleMouse(true); } private void SetWindow() { if (!windowReady) { ((Rect)(ref window)).x = ((float)Screen.width - ((Rect)(ref window)).width) / 2f; ((Rect)(ref window)).y = ((float)Screen.height - ((Rect)(ref window)).height) / 2f; windowReady = true; } } private void CloseMenu() { menuOpen = false; timerOpen = false; PlayerCamera.ToggleMouse(false); Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; } private void OnGUI() { //IL_01b2: 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_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Expected O, but got Unknown //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_03f4: Unknown result type (might be due to invalid IL or missing references) //IL_0400: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Expected O, but got Unknown //IL_041f: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_048c: Unknown result type (might be due to invalid IL or missing references) //IL_04a2: Unknown result type (might be due to invalid IL or missing references) //IL_04c2: Unknown result type (might be due to invalid IL or missing references) InitStyles(); if ((Object)(object)vendor != (Object)null && !menuOpen && (Object)(object)nukeTarget == (Object)null && (Object)(object)nukePickupTarget == (Object)null) { float num = (fHolding ? Mathf.Clamp01((Time.unscaledTime - holdFStarted) / 0.8f) : 0f); GUI.Box(new Rect((float)Screen.width * 0.5f - 240f, (float)Screen.height * 0.68f, 480f, 35f), "Hold F for Boom Dynamite Shop" + (fHolding ? (" " + num.ToString("P0")) : ""), boxStyle); } Item item = (((Object)(object)Player.LocalPlayer == (Object)null) ? null : Player.LocalPlayer.Holding.HeldItem); if (!menuOpen && IsBoom(item)) { string text = ((Kind(item) == DeviceKind.Timer) ? ("Tap E to set timer (" + chosenTimer + "s) | Hold E to deploy") : ((Kind(item) == DeviceKind.Nuke) ? "Tap E to place Nuke | Hold F 5 seconds to activate" : ((Kind(item) == DeviceKind.Mine) ? "Hold E to deploy Proximity Mine" : "Click Mouse1 to light fuse, then throw"))); GUI.Box(new Rect((float)Screen.width * 0.5f - 320f, (float)Screen.height * 0.76f, 640f, 35f), text, boxStyle); } if (!menuOpen && (Object)(object)nukeTarget != (Object)null) { GUIStyle val = new GUIStyle(GUI.skin.box) { fontSize = 23, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; val.normal.textColor = new Color(1f, 0.12f, 0.1f); float num2 = (float)Screen.width * 0.5f - 270f; float num3 = (float)Screen.height * 0.7f; GUI.Box(new Rect(num2, num3, 540f, 52f), "HOLD F TO ACTIVATE NUKE " + Mathf.RoundToInt(nukeProgress * 100f) + "%", val); Color color = GUI.color; GUI.color = new Color(1f, 0.06f, 0.04f); GUI.DrawTexture(new Rect(num2 + 8f, num3 + 45f, 524f * nukeProgress, 6f), (Texture)(object)Texture2D.whiteTexture); GUI.color = color; } if (!menuOpen && (Object)(object)nukePickupTarget != (Object)null) { float num4 = (float)Screen.width * 0.5f - 270f; float num5 = (float)Screen.height * 0.78f; GUI.Box(new Rect(num4, num5, 540f, 35f), "Hold E to pick up Nuke " + Mathf.RoundToInt(nukePickupProgress * 100f) + "%", boxStyle); } if (Time.unscaledTime < statusUntil) { GUI.Box(new Rect((float)Screen.width * 0.5f - 260f, (float)Screen.height * 0.79f, 520f, 32f), status, boxStyle); } if (menuOpen) { ((Rect)(ref window)).x = Mathf.Clamp(((Rect)(ref window)).x, 0f, Mathf.Max(0f, (float)Screen.width - ((Rect)(ref window)).width)); ((Rect)(ref window)).y = Mathf.Clamp(((Rect)(ref window)).y, 0f, Mathf.Max(0f, (float)Screen.height - ((Rect)(ref window)).height)); window = GUI.Window(1112493901, window, new WindowFunction(DrawWindow), timerOpen ? "TIME BOMB TIMER" : "BOOM GOES THE DYNAMITE", boxStyle); } if (flashActive && Time.unscaledTime >= flashStart) { float num6 = Time.unscaledTime - flashStart; float num7 = ((num6 <= 2f) ? 1f : (1f - Mathf.Clamp01((num6 - 2f) / 2.5f))); int depth = GUI.depth; GUI.depth = -10000; Color color2 = GUI.color; GUI.color = new Color(1f, 1f, 1f, num7); GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)Texture2D.whiteTexture); GUI.color = color2; GUI.depth = depth; } } private void InitStyles() { //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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00b9: 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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Expected O, but got Unknown //IL_0100: Unknown result type (might be due to invalid IL or missing references) if (boxStyle == null) { boxStyle = new GUIStyle(GUI.skin.box) { fontSize = 16, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; boxStyle.normal.textColor = Color.white; buttonStyle = new GUIStyle(GUI.skin.button) { fontSize = 16, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; titleStyle = new GUIStyle(GUI.skin.label) { fontSize = 21, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; titleStyle.normal.textColor = new Color(1f, 0.25f, 0.2f); warningStyle = new GUIStyle(GUI.skin.label) { fontSize = 14, fontStyle = (FontStyle)1, alignment = (TextAnchor)4, wordWrap = true }; warningStyle.normal.textColor = Color.white; } } private void DrawWindow(int id) { //IL_0000: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Invalid comparison between Unknown and I4 //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: 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_032e: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) Color color = GUI.color; GUI.color = new Color(0.16f, 0.02f, 0.025f, 0.97f); GUI.DrawTexture(new Rect(4f, 4f, ((Rect)(ref window)).width - 8f, ((Rect)(ref window)).height - 8f), (Texture)(object)Texture2D.whiteTexture); GUI.color = color; GUI.Label(new Rect(15f, 32f, ((Rect)(ref window)).width - 30f, 34f), timerOpen ? "Choose the time bomb fuse" : "CHOOSE YOUR EXPLOSIVE", titleStyle); if (timerOpen) { chosenTimer = Mathf.RoundToInt(GUI.HorizontalSlider(new Rect(70f, 120f, ((Rect)(ref window)).width - 140f, 26f), (float)chosenTimer, 5f, 20f)); GUI.Label(new Rect(60f, 153f, ((Rect)(ref window)).width - 120f, 35f), "Timer: " + chosenTimer + " seconds", titleStyle); if (GUI.Button(new Rect(90f, 222f, ((Rect)(ref window)).width - 180f, 50f), "SAVE TIMER", buttonStyle)) { CloseMenu(); } } else { for (int i = 0; i < 4; i++) { float num = 78 + i * 78; Texture2D val = BoomVisual.Icon((DeviceKind)i); if ((Object)(object)val != (Object)null) { GUI.DrawTexture(new Rect(26f, num, 62f, 62f), (Texture)(object)val, (ScaleMode)2, true); } GUI.Label(new Rect(103f, num + 7f, 270f, 48f), Names[i], titleStyle); if (GUI.Button(new Rect(((Rect)(ref window)).width - 184f, num + 9f, 155f, 44f), "BUY $" + Prices[i], buttonStyle)) { Send("buy", i); } } } if (GUI.Button(new Rect(((Rect)(ref window)).width - 47f, 10f, 34f, 26f), "X", buttonStyle)) { CloseMenu(); } GUI.Label(new Rect(((Rect)(ref window)).width - 28f, ((Rect)(ref window)).height - 30f, 24f, 24f), "↘", warningStyle); Event current = Event.current; if ((int)current.type == 3) { Rect val2 = new Rect(((Rect)(ref window)).width - 36f, ((Rect)(ref window)).height - 38f, 36f, 38f); if (((Rect)(ref val2)).Contains(current.mousePosition)) { ((Rect)(ref window)).width = Mathf.Clamp(((Rect)(ref window)).width + current.delta.x, 500f, (float)Mathf.Max(500, Screen.width)); ((Rect)(ref window)).height = Mathf.Clamp(((Rect)(ref window)).height + current.delta.y, 400f, (float)Mathf.Max(400, Screen.height)); current.Use(); } } GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref window)).width - 55f, 30f)); } private void OnDestroy() { if (flashMuted) { AudioListener.volume = oldListenerVolume; } if ((Object)(object)aftermathTone != (Object)null) { Object.Destroy((Object)(object)((Component)aftermathTone).gameObject); } if (harmony != null) { harmony.UnpatchSelf(); } Instance = null; } } internal static class Wallet { private static Type WalletType => Type.GetType("NoSharedMoney.Wallets, NoSharedMoney", throwOnError: false); public static bool Charge(Player player, int amount) { Type walletType = WalletType; if (walletType != null) { if ((int)AccessTools.Method(walletType, "Get", new Type[1] { typeof(Player) }, (Type[])null).Invoke(null, new object[1] { player }) < amount) { return false; } AccessTools.Method(walletType, "Remove", new Type[2] { typeof(Player), typeof(int) }, (Type[])null).Invoke(null, new object[2] { player, amount }); return true; } if ((Object)(object)MoneyManager.Instance == (Object)null || !MoneyManager.CanAfford(amount)) { return false; } MoneyManager.RemoveMoney(amount, player); return true; } public static void Credit(Player player, int amount) { Type walletType = WalletType; if (walletType != null) { AccessTools.Method(walletType, "Add", new Type[2] { typeof(Player), typeof(int) }, (Type[])null).Invoke(null, new object[2] { player, amount }); } else { MoneyManager.AddMoney(amount, player); } } } [HarmonyPatch(typeof(Item), "GetName")] internal static class BoomName { private static bool Prefix(Item __instance, ref string __result) { if (!Plugin.IsBoom(__instance)) { return true; } __result = Plugin.Names[(uint)Plugin.Kind(__instance)]; return false; } } public static class Beep { private static AudioClip shortClip; private static AudioClip loudClip; private static AudioClip Clip { get { if ((Object)(object)shortClip != (Object)null) { return shortClip; } int num = 1874; float[] array = new float[num]; for (int i = 0; i < num; i++) { float num2 = (float)i / 22050f; float num3 = Mathf.Sin((float)Math.PI * (float)i / (float)num); array[i] = Mathf.Sin(num2 * 2f * (float)Math.PI * 900f) * num3 * 0.22f; } shortClip = AudioClip.Create("Boom Dynamite Beep", num, 1, 22050, false); shortClip.SetData(array, 0); return shortClip; } } public static void Play(Vector3 at, int count = 1) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < count; i++) { AudioSource.PlayClipAtPoint(Clip, at, 0.27f); } } public static void PlayLoud(Vector3 at) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)loudClip == (Object)null) { int num = 4189; float[] array = new float[num]; for (int i = 0; i < num; i++) { float num2 = (float)i / 22050f; float num3 = Mathf.Sin((float)Math.PI * (float)i / (float)num); array[i] = Mathf.Sin(num2 * 2f * (float)Math.PI * 850f) * num3 * 0.65f; } loudClip = AudioClip.Create("Boom Dynamite Loud Beep", num, 1, 22050, false); loudClip.SetData(array, 0); } AudioSource.PlayClipAtPoint(loudClip, at, 0.85f); } } public sealed class BoomVisual : MonoBehaviour { private static readonly Texture2D[] icons = (Texture2D[])(object)new Texture2D[4]; private static readonly string[] iconFiles = new string[4] { "super-dynamite.png", "nuke.png", "time-bomb.png", "proximity-mine.png" }; private static Material red; private static Material dark; private static Material yellow; private static Material orange; private static Material white; private static Material glass; private static Material bubbleMaterial; private Mesh inventoryMesh; private Renderer bubble; private DeviceKind kind; private Item item; private Explosive explosive; private bool lastDeployed; private bool lastActivated; private int lastBeepSecond = int.MaxValue; private float nextAlarm; private float voiceLocalEnd; public Mesh InventoryMesh => inventoryMesh; public static Texture2D Icon(DeviceKind kind) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown if ((int)kind < 0 || (int)kind >= 4) { return null; } if ((Object)(object)icons[(uint)kind] != (Object)null) { return icons[(uint)kind]; } using Stream stream = typeof(BoomVisual).Assembly.GetManifestResourceStream("BoomDynamite." + iconFiles[(uint)kind]); if (stream == null) { return null; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); ImageConversion.LoadImage(val, memoryStream.ToArray()); ((Texture)val).wrapMode = (TextureWrapMode)1; icons[(uint)kind] = val; return val; } private static Material Material(Color color) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown return new Material(Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard")) { color = color }; } private static Transform Part(Transform parent, string name, PrimitiveType type, Vector3 pos, Vector3 scale, Material mat, Vector3 rotation) { //IL_0000: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) GameObject obj = GameObject.CreatePrimitive(type); ((Object)obj).name = name; obj.transform.SetParent(parent, false); obj.transform.localPosition = pos; obj.transform.localEulerAngles = rotation; obj.transform.localScale = scale; Object.DestroyImmediate((Object)(object)obj.GetComponent<Collider>()); obj.GetComponent<Renderer>().sharedMaterial = mat; return obj.transform; } public void Build(DeviceKind choice) { //IL_0134: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Expected O, but got Unknown //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Unknown result type (might be due to invalid IL or missing references) //IL_03ce: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_040d: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_044c: Unknown result type (might be due to invalid IL or missing references) //IL_0456: Unknown result type (might be due to invalid IL or missing references) //IL_0477: Unknown result type (might be due to invalid IL or missing references) //IL_048b: Unknown result type (might be due to invalid IL or missing references) //IL_04a4: Unknown result type (might be due to invalid IL or missing references) //IL_0875: Unknown result type (might be due to invalid IL or missing references) //IL_0886: Unknown result type (might be due to invalid IL or missing references) //IL_0890: Unknown result type (might be due to invalid IL or missing references) //IL_0742: Unknown result type (might be due to invalid IL or missing references) //IL_0756: Unknown result type (might be due to invalid IL or missing references) //IL_0760: Unknown result type (might be due to invalid IL or missing references) //IL_0794: Unknown result type (might be due to invalid IL or missing references) //IL_07a8: Unknown result type (might be due to invalid IL or missing references) //IL_07b2: Unknown result type (might be due to invalid IL or missing references) //IL_07d3: Unknown result type (might be due to invalid IL or missing references) //IL_07e7: Unknown result type (might be due to invalid IL or missing references) //IL_07f1: Unknown result type (might be due to invalid IL or missing references) //IL_0812: Unknown result type (might be due to invalid IL or missing references) //IL_0826: Unknown result type (might be due to invalid IL or missing references) //IL_0830: Unknown result type (might be due to invalid IL or missing references) //IL_0574: Unknown result type (might be due to invalid IL or missing references) //IL_0588: Unknown result type (might be due to invalid IL or missing references) //IL_0592: Unknown result type (might be due to invalid IL or missing references) //IL_05c6: Unknown result type (might be due to invalid IL or missing references) //IL_05da: Unknown result type (might be due to invalid IL or missing references) //IL_05e4: Unknown result type (might be due to invalid IL or missing references) //IL_0605: Unknown result type (might be due to invalid IL or missing references) //IL_0619: Unknown result type (might be due to invalid IL or missing references) //IL_0632: Unknown result type (might be due to invalid IL or missing references) //IL_0653: Unknown result type (might be due to invalid IL or missing references) //IL_0667: Unknown result type (might be due to invalid IL or missing references) //IL_0680: Unknown result type (might be due to invalid IL or missing references) //IL_06a1: Unknown result type (might be due to invalid IL or missing references) //IL_06b5: Unknown result type (might be due to invalid IL or missing references) //IL_06ce: Unknown result type (might be due to invalid IL or missing references) //IL_06ef: Unknown result type (might be due to invalid IL or missing references) //IL_0703: Unknown result type (might be due to invalid IL or missing references) //IL_071c: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_031d: 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) //IL_0948: Unknown result type (might be due to invalid IL or missing references) //IL_04ca: Unknown result type (might be due to invalid IL or missing references) //IL_04de: Unknown result type (might be due to invalid IL or missing references) //IL_04f8: Unknown result type (might be due to invalid IL or missing references) //IL_0524: 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_0542: Unknown result type (might be due to invalid IL or missing references) //IL_0932: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_09bf: Unknown result type (might be due to invalid IL or missing references) //IL_091c: Unknown result type (might be due to invalid IL or missing references) //IL_0906: Unknown result type (might be due to invalid IL or missing references) //IL_09a9: Unknown result type (might be due to invalid IL or missing references) //IL_0993: Unknown result type (might be due to invalid IL or missing references) //IL_097d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)((Component)this).transform.Find("BoomDeviceModel") != (Object)null) { return; } kind = choice; item = ((Component)this).GetComponent<Item>(); explosive = ((Component)this).GetComponent<Explosive>(); if ((Object)(object)red == (Object)null) { red = Material(new Color(0.75f, 0.06f, 0.045f)); dark = Material(new Color(0.11f, 0.12f, 0.15f)); yellow = Material(new Color(1f, 0.67f, 0.035f)); orange = Material(new Color(0.93f, 0.28f, 0.03f)); white = Material(new Color(0.9f, 0.88f, 0.8f)); glass = Material(new Color(0.23f, 0.75f, 0.85f)); bubbleMaterial = new Material(Shader.Find("Sprites/Default")) { color = new Color(1f, 0.035f, 0.035f, 0.2f) }; } Transform transform = new GameObject("BoomDeviceModel").transform; transform.SetParent(((Component)this).transform, false); if (kind == DeviceKind.Mine) { transform.localScale = Vector3.one * 0.7f; } Transform val = null; try { val = GlbModel.Create(transform, kind); } catch (Exception ex) { Debug.LogWarning((object)("Dynamite GLB import failed for " + kind.ToString() + ": " + ex.Message)); } if ((Object)(object)val != (Object)null) { inventoryMesh = ((Component)val).GetComponent<MeshFilter>().sharedMesh; } else if (kind == DeviceKind.Super) { for (int i = 0; i < 2; i++) { for (int j = -1; j <= 1; j++) { Transform val2 = Part(transform, "RedDynamiteStick", (PrimitiveType)2, new Vector3((float)j * 0.18f, (float)i * 0.15f, 0f), new Vector3(0.1f, 0.38f, 0.1f), red, new Vector3(90f, 0f, 0f)); if ((Object)(object)inventoryMesh == (Object)null) { inventoryMesh = ((Component)val2).GetComponent<MeshFilter>().sharedMesh; } } } Part(transform, "SteelStrapA", (PrimitiveType)3, new Vector3(0f, 0.08f, -0.24f), new Vector3(0.57f, 0.08f, 0.09f), dark, Vector3.zero); Part(transform, "SteelStrapB", (PrimitiveType)3, new Vector3(0f, 0.08f, 0.24f), new Vector3(0.57f, 0.08f, 0.09f), dark, Vector3.zero); Part(transform, "Fuse", (PrimitiveType)2, new Vector3(0f, 0.34f, 0f), new Vector3(0.035f, 0.16f, 0.035f), yellow, new Vector3(0f, 0f, -30f)); } else if (kind == DeviceKind.Nuke) { Transform val3 = Part(transform, "NukeCanister", (PrimitiveType)2, new Vector3(0f, 0.38f, 0f), new Vector3(0.36f, 0.45f, 0.36f), dark, Vector3.zero); inventoryMesh = ((Component)val3).GetComponent<MeshFilter>().sharedMesh; Part(transform, "TopBand", (PrimitiveType)2, new Vector3(0f, 0.73f, 0f), new Vector3(0.37f, 0.055f, 0.37f), yellow, Vector3.zero); Part(transform, "BottomBand", (PrimitiveType)2, new Vector3(0f, 0.08f, 0f), new Vector3(0.37f, 0.055f, 0.37f), yellow, Vector3.zero); Part(transform, "HazardBadge", (PrimitiveType)3, new Vector3(0f, 0.42f, 0.365f), new Vector3(0.35f, 0.28f, 0.03f), yellow, Vector3.zero); Part(transform, "HazardCenter", (PrimitiveType)2, new Vector3(0f, 0.42f, 0.389f), new Vector3(0.06f, 0.012f, 0.06f), dark, new Vector3(90f, 0f, 0f)); for (int k = 0; k < 3; k++) { Part(transform, "HazardRay", (PrimitiveType)3, new Vector3(0f, 0.42f, 0.39f), new Vector3(0.045f, 0.12f, 0.015f), dark, new Vector3(0f, 0f, (float)(k * 120))); } Part(transform, "NukeFuseCap", (PrimitiveType)2, new Vector3(0f, 0.86f, 0f), new Vector3(0.09f, 0.07f, 0.09f), orange, Vector3.zero); } else if (kind == DeviceKind.Timer) { Transform val4 = Part(transform, "TimerBlock", (PrimitiveType)3, new Vector3(0f, 0.25f, 0f), new Vector3(0.72f, 0.47f, 0.52f), orange, Vector3.zero); inventoryMesh = ((Component)val4).GetComponent<MeshFilter>().sharedMesh; Part(transform, "TimerBand", (PrimitiveType)3, new Vector3(0f, 0.25f, 0f), new Vector3(0.75f, 0.1f, 0.55f), dark, Vector3.zero); Part(transform, "ClockFace", (PrimitiveType)2, new Vector3(0f, 0.29f, 0.275f), new Vector3(0.22f, 0.02f, 0.22f), white, new Vector3(90f, 0f, 0f)); Part(transform, "ClockHand", (PrimitiveType)3, new Vector3(0.03f, 0.34f, 0.3f), new Vector3(0.025f, 0.14f, 0.014f), red, new Vector3(0f, 0f, 25f)); Part(transform, "WireLeft", (PrimitiveType)2, new Vector3(-0.16f, 0.58f, 0f), new Vector3(0.025f, 0.12f, 0.025f), red, new Vector3(0f, 0f, -20f)); Part(transform, "WireRight", (PrimitiveType)2, new Vector3(0.16f, 0.58f, 0f), new Vector3(0.025f, 0.12f, 0.025f), glass, new Vector3(0f, 0f, 20f)); } else { Transform val5 = Part(transform, "MineBody", (PrimitiveType)2, new Vector3(0f, 0.1f, 0f), new Vector3(0.6f, 0.12f, 0.6f), red, Vector3.zero); inventoryMesh = ((Component)val5).GetComponent<MeshFilter>().sharedMesh; Part(transform, "MineRim", (PrimitiveType)2, new Vector3(0f, 0.09f, 0f), new Vector3(0.62f, 0.075f, 0.62f), dark, Vector3.zero); Part(transform, "PressurePad", (PrimitiveType)2, new Vector3(0f, 0.18f, 0f), new Vector3(0.36f, 0.035f, 0.36f), dark, Vector3.zero); Part(transform, "RedSensor", (PrimitiveType)0, new Vector3(0f, 0.22f, 0.3f), new Vector3(0.1f, 0.06f, 0.1f), red, Vector3.zero); } if (kind == DeviceKind.Mine) { GameObject val6 = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)val6).name = "MineDetectionBubble"; val6.transform.SetParent(((Component)this).transform, false); val6.transform.localPosition = Vector3.zero; val6.transform.localScale = Vector3.one * 7f; Object.DestroyImmediate((Object)(object)val6.GetComponent<Collider>()); bubble = val6.GetComponent<Renderer>(); bubble.sharedMaterial = bubbleMaterial; bubble.enabled = false; } BoxCollider val7 = ((Component)transform).gameObject.AddComponent<BoxCollider>(); val7.center = ((kind == DeviceKind.Nuke) ? new Vector3(0f, 0.43f, 0f) : ((kind == DeviceKind.Timer) ? new Vector3(0f, 0.29f, 0f) : ((kind == DeviceKind.Mine) ? new Vector3(0f, 0.12f, 0f) : new Vector3(0f, 0.12f, 0f)))); val7.size = ((kind == DeviceKind.Nuke) ? new Vector3(0.76f, 0.9f, 0.76f) : ((kind == DeviceKind.Timer) ? new Vector3(0.76f, 0.65f, 0.56f) : ((kind == DeviceKind.Mine) ? new Vector3(1.22f, 0.28f, 1.22f) : new Vector3(0.68f, 0.52f, 0.85f)))); FieldInfo fieldInfo = AccessTools.Field(typeof(Item), "_worldColliders"); fieldInfo.SetValue(value: new List<Collider>((IEnumerable<Collider>)(((object)(fieldInfo.GetValue(item) as Collider[])) ?? ((object)new Collider[0]))) { (Collider)(object)val7 }.ToArray(), obj: item); } private void Awake() { item = ((Component)this).GetComponent<Item>(); explosive = ((Component)this).GetComponent<Explosive>(); if ((Object)(object)item != (Object)null && Plugin.IsBoom(item)) { kind = Plugin.Kind(item); Plugin.SetExplosion(explosive, kind); } Transform val = ((Component)this).transform.Find("MineDetectionBubble"); if ((Object)(object)val != (Object)null) { bubble = ((Component)val).GetComponent<Renderer>(); } } private void Update() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: 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_0188: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)item == (Object)null || (Object)(object)explosive == (Object)null || (Object)(object)Plugin.Instance == (Object)null) { return; } DeviceState deviceState = Plugin.Instance.Find(item); bool flag = deviceState?.deployed ?? false; if (flag) { ((Component)this).transform.SetPositionAndRotation(deviceState.position, Quaternion.FromToRotation(Vector3.up, deviceState.normal)); } bool flag2 = Plugin.Activated(explosive); if ((Object)(object)bubble != (Object)null) { bubble.enabled = flag && kind == DeviceKind.Mine && deviceState.armed && !flag2; } if (kind == DeviceKind.Mine && flag && !deviceState.armed && Time.unscaledTime >= nextAlarm) { nextAlarm = Time.unscaledTime + 0.25f; Beep.Play(((Component)this).transform.position); } if (kind == DeviceKind.Nuke && deviceState != null && deviceState.activationStarted && !lastActivated) { if (!deviceState.countdownStarted) { NukeAudio.PlayActivation(((Component)this).transform.position); voiceLocalEnd = Time.unscaledTime + NukeAudio.Duration; } else { voiceLocalEnd = Time.unscaledTime; } } if (flag2) { float num = Plugin.Remaining(explosive); if (kind == DeviceKind.Timer) { if (num > 1f) { int num2 = Mathf.CeilToInt(num); if (num2 < lastBeepSecond) { lastBeepSecond = num2; Beep.PlayLoud(((Component)this).transform.position); } } else if (Time.unscaledTime >= nextAlarm) { nextAlarm = Time.unscaledTime + 0.11f; Beep.PlayLoud(((Component)this).transform.position); } } else if (kind == DeviceKind.Mine && Time.unscaledTime >= nextAlarm) { nextAlarm = Time.unscaledTime + 0.14f; Beep.Play(((Component)this).transform.position); } else if (kind == DeviceKind.Nuke && Time.unscaledTime >= voiceLocalEnd && Time.unscaledTime >= nextAlarm) { float num3 = Mathf.Clamp01((10f - num) / 10f); nextAlarm = Time.unscaledTime + Mathf.Lerp(1f, 0.12f, num3 * num3); Beep.PlayLoud(((Component)this).transform.position); } } else { lastBeepSecond = int.MaxValue; } lastDeployed = flag; lastActivated = ((kind != DeviceKind.Nuke) ? flag2 : (deviceState?.activationStarted ?? false)); } } public sealed class SuperBlastVisual : MonoBehaviour { private float born; private float diameter; private Renderer shell; public static void Spawn(Vector3 position, float radius) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown GameObject obj = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)obj).name = "Super Dynamite Expanded Blast"; obj.transform.position = position; Object.Destroy((Object)(object)obj.GetComponent<Collider>()); Material sharedMaterial = new Material(Shader.Find("Sprites/Default")) { color = new Color(1f, 0.38f, 0.06f, 0.19f) }; obj.GetComponent<Renderer>().sharedMaterial = sharedMaterial; obj.AddComponent<SuperBlastVisual>().diameter = Mathf.Max(1f, radius * 2f); Object.Destroy((Object)(object)obj, 1.1f); } private void Awake() { born = Time.unscaledTime; shell = ((Component)this).GetComponent<Renderer>(); } private void Update() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp01((Time.unscaledTime - born) / 0.75f); ((Component)this).transform.localScale = Vector3.one * Mathf.Lerp(0.5f, diameter, num); if ((Object)(object)shell != (Object)null) { Color color = shell.material.color; color.a = 0.19f * (1f - num); shell.material.color = color; } } } [HarmonyPatch(typeof(GameInfo), "Awake")] internal static class RegisterBoomItems { private static void Postfix() { try { Plugin.Instance?.TryRegister(); } catch (Exception error) { Plugin.Instance?.ReportRegistration(error); } } } [HarmonyPatch(typeof(Player), "get_BlockInputs")] internal static class BlockBoomMenuInputs { private static void Postfix(Player __instance, ref bool __result) { if ((Object)(object)Plugin.Instance != (Object)null && Plugin.Instance.MenuOpen && (Object)(object)__instance == (Object)(object)Player.LocalPlayer) { __result = true; } } } [HarmonyPatch] internal static class BlockBoomCamera { private static IEnumerable<MethodBase> TargetMethods() { string[] array = new string[3] { "MouseInput", "ControllerRotation", "ApplyAimAssist" }; foreach (string text in array) { yield return AccessTools.Method(typeof(PlayerCamera), text, (Type[])null, (Type[])null); } } private static bool Prefix() { if (!((Object)(object)Plugin.Instance == (Object)null)) { return !Plugin.Instance.MenuOpen; } return true; } } [HarmonyPatch(typeof(PlayerHolding), "PickUpInput")] internal static class KeepBoomEForPlacement { private static bool Prefix() { Player localPlayer = Player.LocalPlayer; Item item = (((Object)(object)localPlayer == (Object)null) ? null : localPlayer.Holding.HeldItem); if (!Plugin.IsBoom(item) || (Plugin.Kind(item) != DeviceKind.Timer && Plugin.Kind(item) != DeviceKind.Mine && Plugin.Kind(item) != DeviceKind.Nuke)) { if ((Object)(object)Plugin.Instance != (Object)null) { return !Plugin.Instance.LookingAtNuke(); } return true; } return false; } } [HarmonyPatch(typeof(Explosive), "ForceExplode")] internal static class NukeMustBeActivated { private static bool Prefix(Explosive __instance) { if (!((Object)(object)Plugin.Instance == (Object)null) && Plugin.IsBoom((Item)(object)__instance) && Plugin.Kind((Item)(object)__instance) == DeviceKind.Nuke) { return Plugin.Instance.CanArmNuke(__instance); } return true; } } [HarmonyPatch(typeof(Explosive), "ServerExplode")] internal static class BoomDetonation { private static bool Prefix(Explosive __instance) { if ((Object)(object)Plugin.Instance == (Object)null || !Plugin.IsBoom((Item)(object)__instance)) { return true; } if (Plugin.Kind((Item)(object)__instance) == DeviceKind.Nuke && !Plugin.Instance.CanArmNuke(__instance)) { return false; } Plugin.Instance.OnDetonation(__instance); return true; } } [HarmonyPatch(typeof(Explosive), "AnimateLighterAndFuse")] internal static class SilentNukeFuse { private static bool Prefix(Explosive __instance) { if (Plugin.IsBoom((Item)(object)__instance)) { return Plugin.Kind((Item)(object)__instance) != DeviceKind.Nuke; } return true; } } public sealed class BoomSlotIcon : MonoBehaviour { private InventorySlot slot; private Renderer preview; private GameObject overlay; private bool wasEnabled; private bool applied; public void Apply(InventorySlot target) { //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0116: 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_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing