Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ShotgunAmmoBox v0.1.0
ShotgunAmmoBox.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LethalLib.Modules; using Microsoft.CodeAnalysis; using ShotgunAmmoBox.NetcodePatcher; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ShotgunAmmoBox")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+5f2b7a105f106256fb45d7b26364f5ff7ead9b17")] [assembly: AssemblyProduct("ShotgunAmmoBox")] [assembly: AssemblyTitle("ShotgunAmmoBox")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] 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 ShotgunAmmoBox { public class AmmoBoxItem : GrabbableObject { private const int GrabMask = 1073742656; private const int SaveCountBits = 7; private readonly NetworkVariable<int> netShells = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private readonly NetworkVariable<int> netValue = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private readonly NetworkVariable<int> netCapacity = new NetworkVariable<int>(20, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); public int Shells => netShells.Value; public int Capacity => netCapacity.Value; public static string[] Tips(int shells, int capacity) { return new string[3] { $"Shells: {shells}/{capacity}", "Pack shells : [LMB]", "Take shell : [Q]" }; } public override void OnNetworkSpawn() { ((NetworkBehaviour)this).OnNetworkSpawn(); if (((NetworkBehaviour)this).IsServer) { netCapacity.Value = Plugin.Cfg.Capacity.Value; } NetworkVariable<int> obj = netShells; obj.OnValueChanged = (OnValueChangedDelegate<int>)(object)Delegate.Combine((Delegate?)(object)obj.OnValueChanged, (Delegate?)(object)(OnValueChangedDelegate<int>)delegate { Refresh(); }); NetworkVariable<int> obj2 = netCapacity; obj2.OnValueChanged = (OnValueChangedDelegate<int>)(object)Delegate.Combine((Delegate?)(object)obj2.OnValueChanged, (Delegate?)(object)(OnValueChangedDelegate<int>)delegate { Refresh(); }); Refresh(); } private void Refresh() { ScanNodeProperties componentInChildren = ((Component)this).GetComponentInChildren<ScanNodeProperties>(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.subText = $"Shells: {Shells}/{Capacity}"; } if (((NetworkBehaviour)this).IsOwner && base.isHeld && !base.isPocketed && (Object)(object)base.playerHeldBy == (Object)(object)GameNetworkManager.Instance.localPlayerController) { ((GrabbableObject)this).SetControlTipsForItem(); } } public override void SetControlTipsForItem() { HUDManager.Instance.ChangeControlTipMultiple(Tips(Shells, Capacity), true, base.itemProperties); } public override void EquipItem() { ((GrabbableObject)this).EquipItem(); if ((Object)(object)base.playerHeldBy != (Object)null) { base.playerHeldBy.equippedUsableItemQE = true; } } public override void PocketItem() { if ((Object)(object)base.playerHeldBy != (Object)null) { base.playerHeldBy.equippedUsableItemQE = false; } ((GrabbableObject)this).PocketItem(); } public override void DiscardItem() { if ((Object)(object)base.playerHeldBy != (Object)null) { base.playerHeldBy.equippedUsableItemQE = false; } ((GrabbableObject)this).DiscardItem(); } public override void ItemActivate(bool used, bool buttonDown = true) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) if (!buttonDown || (Object)(object)base.playerHeldBy == (Object)null || !((NetworkBehaviour)this).IsOwner) { return; } if (Shells >= Capacity) { HUDManager.Instance.DisplayTip("Ammo box", "It's full.", false, false, "LC_Tip1"); return; } Transform transform = ((Component)base.playerHeldBy.gameplayCamera).transform; RaycastHit val = default(RaycastHit); if (Physics.Raycast(new Ray(transform.position, transform.forward), ref val, base.playerHeldBy.grabDistance, 1073742656)) { GunAmmo componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<GunAmmo>(); if (IsShotgunShell(componentInParent) && !((GrabbableObject)componentInParent).isHeld) { StoreShellServerRpc(NetworkObjectReference.op_Implicit(((NetworkBehaviour)componentInParent).NetworkObject)); return; } } PackInventory(base.playerHeldBy); } private void PackInventory(PlayerControllerB player) { int num = Capacity - Shells; int num2 = 0; int num3 = 0; for (int i = 0; i < player.ItemSlots.Length; i++) { if (num2 >= num) { break; } GrabbableObject obj = player.ItemSlots[i]; GunAmmo val = (GunAmmo)(object)((obj is GunAmmo) ? obj : null); if (val != null && IsShotgunShell(val)) { num3 += ((GrabbableObject)val).scrapValue; num2++; player.DestroyItemInSlotAndSync(i); } } if (num2 == 0) { HUDManager.Instance.DisplayTip("Ammo box", "Look at a shotgun shell, or carry some, to pack them.", false, false, "LC_Tip1"); } else { AddShellsServerRpc(num2, num3); } } public override void ItemInteractLeftRight(bool right) { ((GrabbableObject)this).ItemInteractLeftRight(right); if (!right && !((Object)(object)base.playerHeldBy == (Object)null) && ((NetworkBehaviour)this).IsOwner) { if (Shells <= 0) { HUDManager.Instance.DisplayTip("Ammo box", "It's empty.", false, false, "LC_Tip1"); } else { TakeShellServerRpc((int)base.playerHeldBy.playerClientId); } } } public void ConsumeForReload() { ConsumeServerRpc(); } [ServerRpc(RequireOwnership = false)] private void StoreShellServerRpc(NetworkObjectReference shellRef) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Invalid comparison between Unknown and I4 //IL_005f: 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_007d: 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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val2 = default(ServerRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(3993543699u, val2, (RpcDelivery)0); ((FastBufferWriter)(ref val)).WriteValueSafe<NetworkObjectReference>(ref shellRef, default(ForNetworkSerializable)); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 3993543699u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost)) { return; } ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; NetworkObject val3 = default(NetworkObject); if (((NetworkObjectReference)(ref shellRef)).TryGet(ref val3, (NetworkManager)null)) { GunAmmo component = ((Component)val3).GetComponent<GunAmmo>(); if (component != null && !((GrabbableObject)component).isHeld && Shells < Capacity) { NetworkVariable<int> obj = netShells; int value = obj.Value; obj.Value = value + 1; NetworkVariable<int> obj2 = netValue; obj2.Value += ((GrabbableObject)component).scrapValue; val3.Despawn(true); ClinkClientRpc(); } } } [ServerRpc(RequireOwnership = false)] private void AddShellsServerRpc(int count, int value) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Invalid comparison between Unknown and I4 //IL_005f: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val2 = default(ServerRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(1353140141u, val2, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, count); BytePacker.WriteValueBitPacked(val, value); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 1353140141u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; netShells.Value = Mathf.Min(Shells + count, Capacity); NetworkVariable<int> obj = netValue; obj.Value += value; ClinkClientRpc(); } } } [ServerRpc(RequireOwnership = false)] private void ConsumeServerRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_005f: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val2 = default(ServerRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(2104233644u, val2, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 2104233644u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; TakeOne(); } } } [ServerRpc(RequireOwnership = false)] private void TakeShellServerRpc(int playerId) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val2 = default(ServerRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(1000598417u, val2, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, playerId); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 1000598417u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; if (Shells > 0 && !((Object)(object)BoxRegistry.ShellItem == (Object)null)) { int num = TakeOne(); PlayerControllerB val3 = StartOfRound.Instance.allPlayerScripts[playerId]; Vector3 val4 = Vector3.ProjectOnPlane(((Component)val3.gameplayCamera).transform.forward, Vector3.up); Vector3 normalized = ((Vector3)(ref val4)).normalized; Vector3 val5 = ((Component)val3).transform.position + normalized * 0.6f + Vector3.up * 0.8f; bool flag = val3.isInHangarShipRoom || val3.isInElevator; Transform val6 = (flag ? StartOfRound.Instance.elevatorTransform : RoundManager.Instance.spawnedScrapContainer); GameObject obj = Object.Instantiate<GameObject>(BoxRegistry.ShellItem.spawnPrefab, val5, Quaternion.identity, val6); GrabbableObject component = obj.GetComponent<GrabbableObject>(); component.fallTime = 0f; component.isInElevator = flag; component.isInShipRoom = val3.isInHangarShipRoom; component.isInFactory = val3.isInsideFactory; NetworkObject component2 = obj.GetComponent<NetworkObject>(); component2.Spawn(false); RoundManager.Instance.SyncScrapValuesClientRpc((NetworkObjectReference[])(object)new NetworkObjectReference[1] { NetworkObjectReference.op_Implicit(component2) }, new int[1] { num }); ClinkClientRpc(); } } } private int TakeOne() { if (Shells <= 0) { return 0; } int num = netValue.Value / Shells; NetworkVariable<int> obj = netShells; int value = obj.Value; obj.Value = value - 1; NetworkVariable<int> obj2 = netValue; obj2.Value -= num; return num; } [ClientRpc] private void ClinkClientRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_005f: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val2 = default(ClientRpcParams); FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(349424556u, val2, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendClientRpc(ref val, 349424556u, val2, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; AudioClip val3 = (((Object)(object)BoxRegistry.ShellItem != (Object)null) ? BoxRegistry.ShellItem.grabSFX : null); if ((Object)(object)val3 != (Object)null) { ((Component)this).GetComponent<AudioSource>().PlayOneShot(val3); } } } public override int GetItemDataToSave() { return Shells | (netValue.Value << 7); } public override void LoadItemSaveData(int saveData) { if (!((NetworkBehaviour)this).IsSpawned || ((NetworkBehaviour)this).IsServer) { netShells.Value = saveData & 0x7F; netValue.Value = saveData >> 7; } } public static bool IsShotgunShell(GunAmmo ammo) { if ((Object)(object)ammo != (Object)null) { return ammo.ammoType == BoxRegistry.ShellAmmoType; } return false; } protected override void __initializeVariables() { if (netShells == null) { throw new Exception("AmmoBoxItem.netShells cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)netShells).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)netShells, "netShells"); ((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)netShells); if (netValue == null) { throw new Exception("AmmoBoxItem.netValue cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)netValue).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)netValue, "netValue"); ((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)netValue); if (netCapacity == null) { throw new Exception("AmmoBoxItem.netCapacity cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)netCapacity).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)netCapacity, "netCapacity"); ((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)netCapacity); ((GrabbableObject)this).__initializeVariables(); } protected override void __initializeRpcs() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown ((NetworkBehaviour)this).__registerRpc(3993543699u, new RpcReceiveHandler(__rpc_handler_3993543699), "StoreShellServerRpc"); ((NetworkBehaviour)this).__registerRpc(1353140141u, new RpcReceiveHandler(__rpc_handler_1353140141), "AddShellsServerRpc"); ((NetworkBehaviour)this).__registerRpc(2104233644u, new RpcReceiveHandler(__rpc_handler_2104233644), "ConsumeServerRpc"); ((NetworkBehaviour)this).__registerRpc(1000598417u, new RpcReceiveHandler(__rpc_handler_1000598417), "TakeShellServerRpc"); ((NetworkBehaviour)this).__registerRpc(349424556u, new RpcReceiveHandler(__rpc_handler_349424556), "ClinkClientRpc"); ((GrabbableObject)this).__initializeRpcs(); } private static void __rpc_handler_3993543699(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_005e: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { NetworkObjectReference shellRef = default(NetworkObjectReference); ((FastBufferReader)(ref reader)).ReadValueSafe<NetworkObjectReference>(ref shellRef, default(ForNetworkSerializable)); target.__rpc_exec_stage = (__RpcExecStage)1; ((AmmoBoxItem)(object)target).StoreShellServerRpc(shellRef); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_1353140141(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int count = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref count); int value = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref value); target.__rpc_exec_stage = (__RpcExecStage)1; ((AmmoBoxItem)(object)target).AddShellsServerRpc(count, value); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2104233644(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { target.__rpc_exec_stage = (__RpcExecStage)1; ((AmmoBoxItem)(object)target).ConsumeServerRpc(); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_1000598417(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int playerId = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref playerId); target.__rpc_exec_stage = (__RpcExecStage)1; ((AmmoBoxItem)(object)target).TakeShellServerRpc(playerId); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_349424556(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { target.__rpc_exec_stage = (__RpcExecStage)1; ((AmmoBoxItem)(object)target).ClinkClientRpc(); target.__rpc_exec_stage = (__RpcExecStage)0; } } protected internal override string __getTypeName() { return "AmmoBoxItem"; } } internal static class BoxAssets { public static GameObject BoxModel; public static void Load(string path) { if (!File.Exists(path)) { Plugin.Log.LogWarning((object)("No asset bundle at " + path + "; using a placeholder box.")); return; } AssetBundle val = AssetBundle.LoadFromFile(path); BoxModel = (((Object)(object)val != (Object)null) ? val.LoadAsset<GameObject>("AmmoBox") : null); Plugin.Log.LogInfo((object)$"Loaded ammo box model: {(Object)(object)BoxModel != (Object)null}"); } } internal class BoxConfig { public readonly ConfigEntry<int> ShellPrice; public readonly ConfigEntry<int> BoxPrice; public readonly ConfigEntry<int> Capacity; public BoxConfig(ConfigFile cfg) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown ShellPrice = cfg.Bind<int>("Store", "ShellPrice", 100, new ConfigDescription("Credits per shotgun shell in the terminal store ('buy ammo'). Requires restart.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10000), Array.Empty<object>())); BoxPrice = cfg.Bind<int>("Store", "BoxPrice", 400, new ConfigDescription("Credits for an ammo box in the terminal store ('buy ammo box'). Requires restart.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10000), Array.Empty<object>())); Capacity = cfg.Bind<int>("Box", "Capacity", 20, new ConfigDescription("Shells one box holds. The host's value is used in multiplayer.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 99), Array.Empty<object>())); } } internal static class BoxRegistry { public static int ShellAmmoType = 1410; private const int PropsLayer = 6; private const int ScanNodeLayer = 22; public static Item BoxItem; public static GameObject Prefab; public static Item ShellItem; private static bool shellsRegistered; private static readonly string[] ShellAliases = new string[3] { "shotgun", "shell", "shells" }; private static bool litDone; public static void Register() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: 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_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) Prefab = NetworkPrefabs.CreateNetworkPrefab("ShotgunAmmoBox"); Prefab.GetComponent<NetworkObject>().AutoObjectParentSync = false; Prefab.tag = "PhysicsProp"; Prefab.layer = 6; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(0.304f, 0.224f, 0.142f); GameObject obj = (((Object)(object)BoxAssets.BoxModel != (Object)null) ? Object.Instantiate<GameObject>(BoxAssets.BoxModel, Prefab.transform) : Placeholder(val)); ((Object)obj).name = "Model"; obj.transform.SetParent(Prefab.transform, false); Transform[] componentsInChildren = obj.GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.layer = 6; } BoxCollider obj2 = Prefab.AddComponent<BoxCollider>(); obj2.center = new Vector3(0f, val.y / 2f, 0f); obj2.size = val; AudioSource obj3 = Prefab.AddComponent<AudioSource>(); obj3.playOnAwake = false; obj3.spatialBlend = 1f; obj3.rolloffMode = (AudioRolloffMode)1; obj3.minDistance = 1f; obj3.maxDistance = 20f; GameObject val2 = new GameObject("ScanNode") { layer = 22 }; val2.transform.SetParent(Prefab.transform, false); val2.transform.localPosition = new Vector3(0f, val.y / 2f, 0f); BoxCollider obj4 = val2.AddComponent<BoxCollider>(); ((Collider)obj4).isTrigger = true; obj4.size = Vector3.one * 0.4f; ScanNodeProperties obj5 = val2.AddComponent<ScanNodeProperties>(); obj5.maxRange = 13; obj5.minRange = 1; obj5.requiresLineOfSight = true; obj5.headerText = "Ammo box"; obj5.subText = "Shells: 0"; obj5.nodeType = 0; Item val3 = ScriptableObject.CreateInstance<Item>(); ((Object)val3).name = "ShotgunAmmoBoxItem"; val3.itemName = "Ammo box"; val3.spawnPrefab = Prefab; val3.isScrap = false; val3.minValue = (val3.maxValue = 0); val3.creditsWorth = Plugin.Cfg.BoxPrice.Value; val3.weight = 1.05f; val3.twoHanded = false; val3.twoHandedAnimation = false; val3.canBeGrabbedBeforeGameStart = true; val3.itemSpawnsOnGround = true; val3.requiresBattery = false; val3.saveItemVariable = true; val3.syncUseFunction = false; val3.syncInteractLRFunction = false; val3.isConductiveMetal = true; val3.canBeInspected = false; val3.restingRotation = Vector3.zero; val3.verticalOffset = 0.05f; val3.positionOffset = new Vector3(-0.04f, 0.06f, -0.12f); val3.rotationOffset = new Vector3(0f, 90f, 0f); val3.toolTips = AmmoBoxItem.Tips(0, Plugin.Cfg.Capacity.Value); val3.meshVariants = (Mesh[])(object)new Mesh[0]; val3.materialVariants = (Material[])(object)new Material[0]; val3.clinkAudios = (AudioClip[])(object)new AudioClip[0]; BoxItem = val3; AmmoBoxItem ammoBoxItem = Prefab.AddComponent<AmmoBoxItem>(); ((GrabbableObject)ammoBoxItem).itemProperties = val3; ((GrabbableObject)ammoBoxItem).grabbable = true; ((GrabbableObject)ammoBoxItem).grabbableToEnemies = true; TerminalNode val4 = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)val4).name = "AmmoBoxInfoNode"; val4.clearPreviousText = true; val4.maxCharactersToType = 25; val4.displayText = $"A steel ammo can that holds up to {Plugin.Cfg.Capacity.Value} shotgun shells.\n\n" + "Hold it and press [LMB] while looking at a shell to pack it, or with no shell in sight to pack every shell you're carrying. [Q] takes one out. A shotgun reloads straight from a box in your inventory.\n\n"; Items.RegisterShopItem(val3, (TerminalNode)null, (TerminalNode)null, val4, Plugin.Cfg.BoxPrice.Value); } private static GameObject Placeholder(Vector3 size) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(); GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3); Object.DestroyImmediate((Object)(object)obj.GetComponent<Collider>()); ((Object)obj).name = "Placeholder"; obj.transform.SetParent(val.transform, false); obj.transform.localPosition = new Vector3(0f, size.y / 2f, 0f); obj.transform.localScale = size; return val; } public static void RegisterShellShop(IEnumerable<GameObject> prefabs, string where) { if (!shellsRegistered) { GunAmmo val = FindShell(prefabs, where); if (!((Object)(object)val == (Object)null)) { shellsRegistered = true; ShellItem = ((GrabbableObject)val).itemProperties; ShellAmmoType = val.ammoType; ShellItem.itemName = "Shotgun shell"; TerminalNode val2 = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)val2).name = "ShotgunShellInfoNode"; val2.clearPreviousText = true; val2.maxCharactersToType = 25; val2.displayText = "A single 12-gauge shell for the shotgun.\n\n"; Items.RegisterShopItem(ShellItem, (TerminalNode)null, (TerminalNode)null, val2, Plugin.Cfg.ShellPrice.Value); Plugin.Log.LogInfo((object)$"Shotgun shells in the store for {Plugin.Cfg.ShellPrice.Value} credits (found at {where}, ammo type {ShellAmmoType})"); } } } public static void AddShellAliases(Terminal terminal) { //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Expected O, but got Unknown //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Expected O, but got Unknown if ((Object)(object)ShellItem == (Object)null) { return; } List<TerminalKeyword> list = terminal.terminalNodes.allKeywords.ToList(); TerminalKeyword val = ((IEnumerable<TerminalKeyword>)list).FirstOrDefault((Func<TerminalKeyword, bool>)((TerminalKeyword k) => k.word == "buy")); TerminalKeyword val2 = ((IEnumerable<TerminalKeyword>)list).FirstOrDefault((Func<TerminalKeyword, bool>)((TerminalKeyword k) => k.word == "info")); string word = ShellItem.itemName.ToLowerInvariant().Replace(" ", "-"); CompatibleNoun val3 = ((IEnumerable<CompatibleNoun>)val?.compatibleNouns).FirstOrDefault((Func<CompatibleNoun, bool>)((CompatibleNoun n) => (Object)(object)n.noun != (Object)null && n.noun.word == word)); if (val3 == null) { Plugin.Log.LogWarning((object)("No '" + word + "' buy keyword in the terminal; shell aliases skipped.")); return; } CompatibleNoun val4 = ((IEnumerable<CompatibleNoun>)val2?.compatibleNouns).FirstOrDefault((Func<CompatibleNoun, bool>)((CompatibleNoun n) => (Object)(object)n.noun != (Object)null && n.noun.word == word)); string[] shellAliases = ShellAliases; foreach (string alias in shellAliases) { if (!list.Any((TerminalKeyword k) => k.word == alias)) { TerminalKeyword val5 = TerminalUtils.CreateTerminalKeyword(alias, false, (CompatibleNoun[])null, (TerminalNode)null, val, false); list.Add(val5); val.compatibleNouns = val.compatibleNouns.Append(new CompatibleNoun(val5, val3.result)).ToArray(); if (val4 != null) { val2.compatibleNouns = val2.compatibleNouns.Append(new CompatibleNoun(val5, val4.result)).ToArray(); } } } terminal.terminalNodes.allKeywords = list.ToArray(); } public static IEnumerable<GameObject> MenuPrefabs(NetworkManager nm) { List<GameObject> list = new List<GameObject>(); if ((Object)(object)nm != (Object)null) { list.AddRange(nm.NetworkConfig.Prefabs.Prefabs.Select((NetworkPrefab p) => p.Prefab)); foreach (NetworkPrefabsList networkPrefabsList in nm.NetworkConfig.Prefabs.NetworkPrefabsLists) { if ((Object)(object)networkPrefabsList != (Object)null) { list.AddRange(networkPrefabsList.PrefabList.Select((NetworkPrefab p) => p.Prefab)); } } } list.AddRange(from a in Resources.FindObjectsOfTypeAll<GunAmmo>() select ((Component)a).gameObject); list.AddRange(from g in Resources.FindObjectsOfTypeAll<ShotgunItem>() select ((Component)g).gameObject); return list; } private static GunAmmo FindShell(IEnumerable<GameObject> prefabs, string where) { List<GameObject> list = prefabs.Where((GameObject p) => (Object)(object)p != (Object)null).Distinct().ToList(); List<GunAmmo> source = (from p in list select p.GetComponentInChildren<GunAmmo>(true) into a where (Object)(object)a != (Object)null && (Object)(object)((GrabbableObject)a).itemProperties != (Object)null select a).Distinct().ToList(); ShotgunItem gun = list.Select((GameObject p) => p.GetComponentInChildren<ShotgunItem>(true)).FirstOrDefault((Func<ShotgunItem, bool>)((ShotgunItem g) => (Object)(object)g != (Object)null)); Plugin.Log.LogInfo((object)(string.Format("[{0}] {1} prefabs, ammo: {2}; ", where, list.Count, string.Join(", ", source.Select((GunAmmo a) => $"{((Object)a).name}/'{((GrabbableObject)a).itemProperties.itemName}' type {a.ammoType}"))) + "shotgun takes " + (((Object)(object)gun != (Object)null) ? gun.gunCompatibleAmmoID.ToString() : "?"))); GunAmmo? obj = (((Object)(object)gun != (Object)null) ? ((IEnumerable<GunAmmo>)source).FirstOrDefault((Func<GunAmmo, bool>)((GunAmmo a) => a.ammoType == gun.gunCompatibleAmmoID)) : null) ?? source.FirstOrDefault(); if ((Object)(object)obj == (Object)null) { Plugin.Log.LogWarning((object)("[" + where + "] no shotgun shell found yet")); } return obj; } public static void FixupFromGame(StartOfRound sor) { RegisterShellShop(from i in sor.allItemsList.itemsList where (Object)(object)i != (Object)null select i.spawnPrefab, "StartOfRound.Awake"); UseLitMaterials(); Item shellItem = ShellItem; if ((Object)(object)shellItem == (Object)null) { Plugin.Log.LogWarning((object)"No vanilla shotgun shell found to borrow sounds and animations from."); return; } BoxItem.grabAnim = shellItem.grabAnim; BoxItem.grabAnimationTime = shellItem.grabAnimationTime; BoxItem.grabSFX = shellItem.grabSFX; BoxItem.dropSFX = shellItem.dropSFX; BoxItem.pocketSFX = shellItem.pocketSFX; Item boxItem = BoxItem; if (boxItem.itemIcon == null) { boxItem.itemIcon = shellItem.itemIcon; } AudioSource componentInChildren = shellItem.spawnPrefab.GetComponentInChildren<AudioSource>(); if ((Object)(object)componentInChildren != (Object)null) { Prefab.GetComponent<AudioSource>().outputAudioMixerGroup = componentInChildren.outputAudioMixerGroup; } } public static void KeepBoxLast(StartOfRound sor) { List<Item> itemsList = sor.allItemsList.itemsList; if (itemsList.Remove(BoxItem)) { itemsList.Add(BoxItem); } } private static void UseLitMaterials() { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) Shader val = Shader.Find("HDRP/Lit"); if ((Object)(object)val == (Object)null || litDone) { return; } litDone = true; MeshRenderer[] componentsInChildren = Prefab.GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val2 in componentsInChildren) { Material[] sharedMaterials = ((Renderer)val2).sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { Material val3 = sharedMaterials[j]; bool flag = (Object)(object)val3 == (Object)null || ((Object)val2).name == "Placeholder"; bool flag2 = !flag && ((Object)val3).name.Contains("Metal"); Material val4 = new Material(val) { name = (flag ? "AmmoBoxPlaceholder" : ((Object)val3).name) + " (Lit)" }; val4.SetColor("_BaseColor", (Color)(flag ? new Color(0.13f, 0.15f, 0.07f) : (val3.HasProperty("_Color") ? val3.color : Color.grey))); val4.SetFloat("_Smoothness", flag2 ? 0.5f : 0.3f); if (flag2) { val4.SetFloat("_Metallic", 0.8f); } sharedMaterials[j] = val4; } ((Renderer)val2).sharedMaterials = sharedMaterials; } } } [HarmonyPatch] internal static class Patches { private const int BoxSlotBase = 1000000; private const int BeltMarker = 999999; [HarmonyPatch(typeof(GameNetworkManager), "Start")] [HarmonyPostfix] private static void AfterGameNetworkManagerStart(GameNetworkManager __instance) { BoxRegistry.RegisterShellShop(BoxRegistry.MenuPrefabs(((Component)__instance).GetComponent<NetworkManager>()), "main menu"); } [HarmonyPatch(typeof(StartOfRound), "Awake")] [HarmonyPostfix] private static void AfterStartOfRoundAwake(StartOfRound __instance) { BoxRegistry.FixupFromGame(__instance); } [HarmonyPatch(typeof(Terminal), "Awake")] [HarmonyPostfix] private static void AfterTerminalAwake(Terminal __instance) { BoxRegistry.AddShellAliases(__instance); } [HarmonyPatch(typeof(StartOfRound), "Start")] [HarmonyPrefix] private static void BeforeStartOfRoundStart(StartOfRound __instance) { BoxRegistry.KeepBoxLast(__instance); } [HarmonyPatch(typeof(ShotgunItem), "FindAmmoInInventory")] [HarmonyPostfix] private static void ReloadFromBox(ShotgunItem __instance, ref int __result) { if (__result != -1 || (Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)null) { return; } PlayerControllerB playerHeldBy = ((GrabbableObject)__instance).playerHeldBy; for (int i = 0; i < playerHeldBy.ItemSlots.Length; i++) { if (playerHeldBy.ItemSlots[i] is AmmoBoxItem { Shells: >0 }) { __result = 1000000 + i; return; } } if (playerHeldBy.ItemOnlySlot is AmmoBoxItem { Shells: >0 }) { __result = 999999; } } [HarmonyPatch(typeof(PlayerControllerB), "DestroyItemInSlotAndSync")] [HarmonyPrefix] private static bool DrawFromBox(PlayerControllerB __instance, int itemSlot) { if (itemSlot < 999999) { return true; } int num = itemSlot - 1000000; if (((itemSlot == 999999) ? __instance.ItemOnlySlot : ((num < __instance.ItemSlots.Length) ? __instance.ItemSlots[num] : null)) is AmmoBoxItem ammoBoxItem) { ammoBoxItem.ConsumeForReload(); } return false; } } [BepInPlugin("ShotgunAmmoBox", "ShotgunAmmoBox", "0.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Log; internal static BoxConfig Cfg; private void Awake() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Cfg = new BoxConfig(((BaseUnityPlugin)this).Config); InitNetcodePatcher(); BoxAssets.Load(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "shotgunammobox")); BoxRegistry.Register(); new Harmony("ShotgunAmmoBox").PatchAll(); Log.LogInfo((object)"ShotgunAmmoBox 0.1.0 loaded."); } private static void InitNetcodePatcher() { Type[] types = Assembly.GetExecutingAssembly().GetTypes(); for (int i = 0; i < types.Length; i++) { MethodInfo[] methods = types[i].GetMethods(BindingFlags.Static | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length != 0) { methodInfo.Invoke(null, null); } } } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "ShotgunAmmoBox"; public const string PLUGIN_NAME = "ShotgunAmmoBox"; public const string PLUGIN_VERSION = "0.1.0"; } } namespace __GEN { internal class NetworkVariableSerializationHelper { [RuntimeInitializeOnLoadMethod] internal static void InitializeSerialization() { } } } namespace ShotgunAmmoBox.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }