Decompiled source of PeakShotgun v1.0.6
plugins/PeakShotgun.dll
Decompiled 5 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using PEAKLib.Core; using PEAKLib.Items; using Peak.Afflictions; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using Zorro.Core; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Arman Ossi Loko")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright (c) 2026 Fake Game Developers")] [assembly: AssemblyDescription("A shotgun built from PEAK's blowgun. Blasts flip zombies harder than a coconut and dose them with drowsy.")] [assembly: AssemblyFileVersion("1.0.6.0")] [assembly: AssemblyInformationalVersion("1.0.6+cf3e69b2d322cb050858854695bb9880224c645e")] [assembly: AssemblyProduct("PeakShotgun")] [assembly: AssemblyTitle("PeakShotgun")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.6.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [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 BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace Peak.Shotgun { public class Action_Ammo : ItemAction { public bool consumeOnFullyUsed; [PunRPC] public void RequestSpendRPC() { if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient) { return; } if (!((ItemActionBase)this).item.HasData((DataEntryKey)2)) { EnsureHostMagazine(); } OptionableIntItemData data = ((ItemActionBase)this).item.GetData<OptionableIntItemData>((DataEntryKey)2); if (!data.HasData) { EnsureHostMagazine(); data = ((ItemActionBase)this).item.GetData<OptionableIntItemData>((DataEntryKey)2); } if (!data.HasData || data.Value <= 0) { BroadcastUses(0); return; } OptionableIntItemData obj = data; obj.Value--; BroadcastUses(data.Value); if (data.Value == 0 && consumeOnFullyUsed && Object.op_Implicit((Object)(object)((ItemActionBase)this).character) && ((ItemActionBase)this).character.IsLocal && (Object)(object)((ItemActionBase)this).character.data.currentItem == (Object)(object)((ItemActionBase)this).item) { ((MonoBehaviour)((ItemActionBase)this).item).StartCoroutine(((ItemActionBase)this).item.ConsumeDelayed(false)); } } internal void EnsureHostMagazine() { if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient) { return; } int shotCount = Plugin.ShotCount; ((ItemActionBase)this).item.totalUses = shotCount; OptionableIntItemData data = ((ItemActionBase)this).item.GetData<OptionableIntItemData>((DataEntryKey)2); if (!data.HasData || data.Value < 0) { data.HasData = true; data.Value = shotCount; ((ItemActionBase)this).item.SetUseRemainingPercentage(1f); if (PhotonNetwork.InRoom && (Object)(object)((MonoBehaviourPun)((ItemActionBase)this).item).photonView != (Object)null) { ((MonoBehaviourPun)((ItemActionBase)this).item).photonView.RPC("ApplyUsesRPC", (RpcTarget)0, new object[2] { data.Value, shotCount }); } } } private void BroadcastUses(int remaining) { int num = Mathf.Max(((ItemActionBase)this).item.totalUses, Plugin.ShotCount); ((ItemActionBase)this).item.totalUses = num; if (!PhotonNetwork.InRoom) { ApplyUsesRPC(remaining, num); return; } ((MonoBehaviourPun)((ItemActionBase)this).item).photonView.RPC("ApplyUsesRPC", (RpcTarget)0, new object[2] { remaining, num }); } [PunRPC] public void ApplyUsesRPC(int remaining, int capacity) { ((ItemActionBase)this).item.totalUses = Mathf.Max(1, capacity); OptionableIntItemData data = ((ItemActionBase)this).item.GetData<OptionableIntItemData>((DataEntryKey)2); data.HasData = true; data.Value = Mathf.Max(0, remaining); if (((ItemActionBase)this).item.totalUses > 0) { ((ItemActionBase)this).item.SetUseRemainingPercentage((float)data.Value / (float)((ItemActionBase)this).item.totalUses); } SyncHolderSlotUses(data.Value); ShotgunAmmoUI.Refresh(); } private void SyncHolderSlotUses(int remaining) { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Expected O, but got Unknown Character val = (((Object)(object)((ItemActionBase)this).character != (Object)null) ? ((ItemActionBase)this).character : ((ItemActionBase)this).item.holderCharacter); if ((Object)(object)val == (Object)null || (Object)(object)val.player == (Object)null || (Object)(object)val.refs?.items == (Object)null || !val.refs.items.currentSelectedSlot.IsSome) { return; } ItemSlot itemSlot = val.player.GetItemSlot(val.refs.items.currentSelectedSlot.Value); if (((itemSlot != null) ? itemSlot.data : null) != null) { OptionableIntItemData val2 = default(OptionableIntItemData); if (itemSlot.data.TryGetDataEntry<OptionableIntItemData>((DataEntryKey)2, ref val2)) { val2.HasData = true; val2.Value = remaining; return; } OptionableIntItemData val3 = new OptionableIntItemData { HasData = true, Value = remaining }; itemSlot.data.RegisterEntry<OptionableIntItemData>((DataEntryKey)2, val3); } } } public class Action_Gun : ItemAction { public float maxDistance = 40f; public float pelletRadius = 0.2f; public float fireRate = 0.85f; public float spread = 0.07f; public int pelletCount = 8; [SerializeReference] public Affliction[] afflictionsOnHit = Array.Empty<Affliction>(); public Transform? spawnTransform; public SFX_Instance? shotSFX; public Action? OnShoot; private float lastShootTime = float.NegativeInfinity; public override void RunAction() { if (!(Time.time <= lastShootTime + fireRate) && HasAmmo()) { lastShootTime = Time.time; Fire(); } } private bool HasAmmo() { if (!((ItemActionBase)this).item.HasData((DataEntryKey)2)) { return ((ItemActionBase)this).item.totalUses <= 0; } OptionableIntItemData data = ((ItemActionBase)this).item.GetData<OptionableIntItemData>((DataEntryKey)2); if (!data.HasData) { return ((ItemActionBase)this).item.totalUses <= 0; } if (data.Value >= 0) { return data.Value > 0; } return true; } private void Fire() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)spawnTransform == (Object)null)) { ((MonoBehaviourPun)((ItemActionBase)this).item).photonView.RPC("RequestSpendRPC", (RpcTarget)2, Array.Empty<object>()); OnShoot?.Invoke(); Vector3 position = spawnTransform.position; Vector3 forward = ((Component)MainCamera.instance).transform.forward; Vector3 val = Vector3.Cross(Vector3.up, forward); if (((Vector3)(ref val)).sqrMagnitude < 0.001f) { val = Vector3.right; } ((Vector3)(ref val)).Normalize(); Vector3 val2 = Vector3.Cross(forward, val); if (Plugin.Recoil > 0f) { ((ItemActionBase)this).character.AddForce(-forward * (Plugin.Recoil / Time.fixedDeltaTime), 1f, 1f); } HashSet<int> struck = new HashSet<int>(); for (int i = 0; i < pelletCount; i++) { Vector2 val3 = PelletOffset(i, pelletCount, spread); Vector3 val4 = forward + val * val3.x + val2 * val3.y; Vector3 normalized = ((Vector3)(ref val4)).normalized; TryPellet(position, normalized, struck); } ((MonoBehaviourPun)this).photonView.RPC("RPC_ShotgunBlastFX", (RpcTarget)0, new object[2] { position, forward }); } } private void TryPellet(Vector3 origin, Vector3 direction, HashSet<int> struck) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) float distance = maxDistance; RaycastHit val = default(RaycastHit); if (Physics.Raycast(origin, direction, ref val, maxDistance, LayerMask.op_Implicit(HelperFunctions.terrainMapMask), (QueryTriggerInteraction)1)) { distance = ((RaycastHit)(ref val)).distance; } RaycastHit[] array = Physics.SphereCastAll(origin, pelletRadius, direction, distance, LayerMask.op_Implicit(HelperFunctions.CharacterAndDefaultMask), (QueryTriggerInteraction)2); Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance)); RaycastHit[] array2 = array; for (int num = 0; num < array2.Length; num++) { RaycastHit val2 = array2[num]; if (Object.op_Implicit((Object)(object)((RaycastHit)(ref val2)).collider)) { int instanceID = ((Object)((Component)((RaycastHit)(ref val2)).collider).transform.root).GetInstanceID(); if (!struck.Contains(instanceID) && ShotgunCombat.TryHit(((RaycastHit)(ref val2)).collider, ((ItemActionBase)this).character, this, ((RaycastHit)(ref val2)).point, direction)) { struck.Add(instanceID); break; } } } } [PunRPC] public void RPC_GunImpact(Player? hitPlayer, Vector3 endpoint, Vector3 direction) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (hitPlayer == null || !hitPlayer.IsLocal) { return; } Character localCharacter = Character.localCharacter; ((Component)localCharacter).GetComponent<GunCharacterLaunch>().Blast(direction, endpoint); if (ShotgunCombat.FriendlyFire) { Affliction[] array = afflictionsOnHit; foreach (Affliction val in array) { localCharacter.refs.afflictions.AddAffliction(val, false); } } } [PunRPC] public void RPC_HostDestroyView(int viewId) { if (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient) { PhotonView val = PhotonView.Find(viewId); if ((Object)(object)val != (Object)null) { PhotonNetwork.Destroy(((Component)val).gameObject); } } } [PunRPC] public void RPC_HostBreakFungus(int viewId) { if (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient) { PhotonView val = PhotonView.Find(viewId); CloudFungus val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<CloudFungus>() : null); if (val2 != null) { val2.Break(); } } } [PunRPC] private void RPC_ShotgunBlastFX(Vector3 origin, Vector3 forward) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) SFX_Instance? obj = shotSFX; if (obj != null) { obj.Play(origin); } ((Component)this).GetComponent<ShotgunVFX>()?.Play(origin, forward); GamefeelHandler.instance.AddPerlinShakeProximity(origin + forward * 3f, 12f, 0.2f, 15f, 10f); } private static Vector2 PelletOffset(int index, int count, float radius) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) if (index <= 0) { return Vector2.zero; } float num = (float)index * 137.5f * (MathF.PI / 180f); float num2 = radius * (0.4f + 0.6f * ((float)index / (float)Mathf.Max(1, count - 1))); return new Vector2(Mathf.Cos(num), Mathf.Sin(num)) * num2; } } public class GunCharacterLaunch : MonoBehaviour { private static readonly Type? ZombieType = AccessToolsType("MushroomZombie"); private const float BlastRagdollSeconds = 3f; private const float ShoveAcceleration = 36f; private const float ShoveSeconds = 0.3f; private const float ZombieDrowsyDamage = 0.5f; private const int HitsToKnockDown = 2; private int shotgunHits; private bool heldDown; private float shoveTime; private Vector3 shoveDirection; internal bool Silenced { get; private set; } public static bool IsZombie(Character character) { if (ZombieType != null) { return (Object)(object)((Component)character).GetComponent(ZombieType) != (Object)null; } return false; } [PunRPC] public void RPC_ShotgunBlast(Vector3 direction, Vector3 point) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) Blast(direction, point); } public void Blast(Vector3 direction, Vector3 point) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown Character component = ((Component)this).GetComponent<Character>(); if ((Object)(object)component == (Object)null || !((MonoBehaviourPun)component).photonView.IsMine || component.data.dead) { return; } Vector3 val = ((Vector3)(ref direction)).normalized + Vector3.up * 0.45f; Vector3 normalized = ((Vector3)(ref val)).normalized; component.Fall(3f, 0f); shoveDirection = normalized; shoveTime = 0.3f; if (IsZombie(component)) { shotgunHits++; if (shotgunHits >= 2) { KnockDown(component); } else { component.refs.afflictions.AddAffliction((Affliction)new Affliction_AdjustStatus((STATUSTYPE)6, 0.5f, 1f), false); } } } private void Update() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) if (!(shoveTime <= 0f)) { Character component = ((Component)this).GetComponent<Character>(); if ((Object)(object)component == (Object)null || !((MonoBehaviourPun)component).photonView.IsMine) { shoveTime = 0f; return; } shoveTime -= Time.deltaTime; component.AddForce(shoveDirection * 36f, 1f, 1f); } } private void LateUpdate() { if (!heldDown) { return; } Character component = ((Component)this).GetComponent<Character>(); if (!((Object)(object)component == (Object)null) && ((MonoBehaviourPun)component).photonView.IsMine) { if (component.data.dead) { heldDown = false; } else { HoldDown(component); } } } private void KnockDown(Character character) { heldDown = true; character.PassOutInstantly(); HoldDown(character); ((MonoBehaviourPun)character).photonView.RPC("RPC_SilenceZombie", (RpcTarget)0, Array.Empty<object>()); } [PunRPC] public void RPC_SilenceZombie() { if (!Silenced) { Silenced = true; AudioSource[] componentsInChildren = ((Component)this).GetComponentsInChildren<AudioSource>(true); foreach (AudioSource val in componentsInChildren) { val.Stop(); val.mute = true; } } } private static void HoldDown(Character character) { character.refs.afflictions.SetStatus((STATUSTYPE)6, 1f, false); character.data.passedOut = true; character.data.fullyPassedOut = true; if (character.data.fallSeconds < 1f) { character.data.fallSeconds = 5f; } } private static Type? AccessToolsType(string name) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { Type type = assembly.GetType(name); if (type != null) { return type; } } return null; } } [HarmonyPatch(typeof(Character), "Awake")] internal static class GunPatch { [HarmonyPostfix] private static void AddLaunch(Character __instance) { ((Component)__instance).gameObject.AddComponent<GunCharacterLaunch>(); } } internal sealed class HostShotSync : MonoBehaviour, IInRoomCallbacks, IMatchmakingCallbacks { internal const string RoomShotsKey = "PeakShotgun_Shots"; private static int? hostShots; internal static int ShotCount { get { if (hostShots.HasValue) { return Mathf.Max(1, hostShots.Value); } return Plugin.LocalConfiguredShots; } } private void OnEnable() { PhotonNetwork.AddCallbackTarget((object)this); } private void OnDisable() { PhotonNetwork.RemoveCallbackTarget((object)this); } internal static void SyncFromLocalRole(string reason) { if (!PhotonNetwork.InRoom) { hostShots = Plugin.LocalConfiguredShots; Plugin.ApplyShotCountConfig(); Plugin.Log.LogInfo((object)$"Shots (offline/local) = {ShotCount} ({reason})."); } else if (PhotonNetwork.IsMasterClient) { PublishHostShots(reason); } else if (!TryApplyRoomShots()) { Plugin.Log.LogInfo((object)("Waiting for host Shots room property (" + reason + ").")); } } private static void PublishHostShots(string reason) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0033: Expected O, but got Unknown int localConfiguredShots = Plugin.LocalConfiguredShots; hostShots = localConfiguredShots; Room currentRoom = PhotonNetwork.CurrentRoom; Hashtable val = new Hashtable(); ((Dictionary<object, object>)val).Add((object)"PeakShotgun_Shots", (object)localConfiguredShots); currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); Plugin.ApplyShotCountConfig(); Plugin.Log.LogInfo((object)$"Host published Shots = {localConfiguredShots} ({reason})."); } private static bool TryApplyRoomShots() { Room currentRoom = PhotonNetwork.CurrentRoom; if (((currentRoom != null) ? ((RoomInfo)currentRoom).CustomProperties : null) == null || !((Dictionary<object, object>)(object)((RoomInfo)currentRoom).CustomProperties).TryGetValue((object)"PeakShotgun_Shots", out object value) || !(value is int num)) { return false; } int num2 = Mathf.Max(1, num); if (hostShots == num2) { return true; } hostShots = num2; Plugin.ApplyShotCountConfig(); Plugin.Log.LogInfo((object)$"Client applied host Shots = {num2}."); return true; } private static void ClearHostShots() { hostShots = null; } public void OnJoinedRoom() { SyncFromLocalRole("joined room"); } public void OnLeftRoom() { ClearHostShots(); } public void OnMasterClientSwitched(Player newMasterClient) { if (PhotonNetwork.IsMasterClient) { PublishHostShots("became host"); } } public void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged) { if (propertiesThatChanged != null && ((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"PeakShotgun_Shots")) { TryApplyRoomShots(); } } public void OnPlayerEnteredRoom(Player newPlayer) { } public void OnPlayerLeftRoom(Player otherPlayer) { } public void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps) { } public void OnFriendListUpdate(List<FriendInfo> friendList) { } public void OnCreatedRoom() { } public void OnCreateRoomFailed(short returnCode, string message) { } public void OnJoinRoomFailed(short returnCode, string message) { } public void OnJoinRandomFailed(short returnCode, string message) { } } [HarmonyPatch(typeof(Luggage), "OffsetSpawn")] internal static class LuggageShotgunOffsetPatch { [HarmonyPostfix] private static void SitFlatOnFloor(Luggage __instance, Item item) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)item == (Object)null || !item.offsetLuggageSpawn || __instance is RespawnChest || (Object)(object)((Component)item).GetComponent<ShotgunInstanceSetup>() == (Object)null) { return; } Transform val = item.transform.Find("ShotgunVisual"); MeshFilter val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<MeshFilter>() : null); Mesh val3 = (((Object)(object)val2 != (Object)null) ? val2.sharedMesh : null); if ((Object)(object)val == (Object)null || (Object)(object)val3 == (Object)null) { return; } Vector3 up = ((Component)__instance).transform.up; Renderer mainRenderer = item.mainRenderer; Vector3 val4; if (!((Object)(object)mainRenderer != (Object)null)) { val4 = item.transform.position - ((Component)__instance).transform.rotation * item.offsetLuggagePosition; } else { Bounds bounds = mainRenderer.bounds; val4 = ((Bounds)(ref bounds)).center - ((Component)__instance).transform.rotation * item.offsetLuggagePosition; } Vector3 val5 = val4; float num = Vector3.Dot(val5, up); Transform transform = item.transform; transform.position -= ((Component)__instance).transform.rotation * item.offsetLuggagePosition; Quaternion localRotation = Plugin.LuggageVisualRotation(item.transform, up); Vector3 localPosition = default(Vector3); ((Vector3)(ref localPosition))..ctor(Plugin.RestPosX, Plugin.RestPosY, Plugin.RestPosZ); val.localPosition = localPosition; val.localRotation = localRotation; ShotgunLuggageRest shotgunLuggageRest = ((Component)val).GetComponent<ShotgunLuggageRest>() ?? ((Component)val).gameObject.AddComponent<ShotgunLuggageRest>(); shotgunLuggageRest.LocalPosition = localPosition; shotgunLuggageRest.LocalRotation = localRotation; shotgunLuggageRest.Armed = true; float num2 = MinMeshAlongUp(val, val3, up); float num3 = num - num2 + Plugin.LuggageLiftExtra; Transform transform2 = item.transform; transform2.position += up * num3; Rigidbody component = ((Component)item).GetComponent<Rigidbody>(); if ((Object)(object)component != (Object)null) { if (!component.isKinematic) { component.angularVelocity = Vector3.zero; component.linearVelocity = Vector3.zero; } component.useGravity = false; component.isKinematic = true; component.constraints = (RigidbodyConstraints)126; } ((Component)item).GetComponent<ShotgunPhysics>()?.Apply(); item.ForceSyncForFrames(10); Plugin.Log.LogInfo((object)$"Luggage seat yaw={Plugin.LuggageYaw:0.#}° Δ={num3:0.###} (spawn-spot, liftExtra={Plugin.LuggageLiftExtra:0.###})."); } private static float MinMeshAlongUp(Transform visual, Mesh mesh, Vector3 up) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_002b: Unknown result type (might be due to invalid IL or missing references) Vector3[] vertices = mesh.vertices; Matrix4x4 localToWorldMatrix = visual.localToWorldMatrix; float num = float.PositiveInfinity; for (int i = 0; i < vertices.Length; i++) { Vector3 val = ((Matrix4x4)(ref localToWorldMatrix)).MultiplyPoint3x4(vertices[i]); num = Mathf.Min(num, Vector3.Dot(val, up)); } return num; } } internal static class ObjMeshLoader { internal static Mesh? Load(Stream stream, string meshName) { //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0236: 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_0245: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Expected O, but got Unknown //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) List<Vector3> list = new List<Vector3>(); List<Vector2> list2 = new List<Vector2>(); List<Vector3> list3 = new List<Vector3>(); List<Vector3> list4 = new List<Vector3>(); List<Vector2> list5 = new List<Vector2>(); List<Vector3> outNormals = new List<Vector3>(); List<int> list6 = new List<int>(); Dictionary<(int, int, int), int> vertexKey = new Dictionary<(int, int, int), int>(); using StreamReader streamReader = new StreamReader(stream); string text; while ((text = streamReader.ReadLine()) != null) { if (text.Length == 0 || text[0] == '#') { continue; } string[] array = text.Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries); if (array.Length == 0) { continue; } switch (array[0]) { case "v": if (array.Length >= 4) { list.Add(new Vector3(0f - Parse(array[1]), Parse(array[2]), Parse(array[3]))); } break; case "vt": if (array.Length >= 3) { list2.Add(new Vector2(Parse(array[1]), Parse(array[2]))); } break; case "vn": if (array.Length >= 4) { list3.Add(new Vector3(0f - Parse(array[1]), Parse(array[2]), Parse(array[3]))); } break; case "f": if (array.Length >= 4) { int item = AddFaceVertex(array[1], list, list2, list3, list4, list5, outNormals, vertexKey); int item2 = AddFaceVertex(array[2], list, list2, list3, list4, list5, outNormals, vertexKey); for (int i = 3; i < array.Length; i++) { int num = AddFaceVertex(array[i], list, list2, list3, list4, list5, outNormals, vertexKey); list6.Add(item); list6.Add(num); list6.Add(item2); item2 = num; } } break; } } if (list4.Count == 0 || list6.Count == 0) { return null; } Vector3 val = list4[0]; Vector3 val2 = list4[0]; for (int j = 1; j < list4.Count; j++) { Vector3 val3 = list4[j]; val = Vector3.Min(val, val3); val2 = Vector3.Max(val2, val3); } Vector3 val4 = (val + val2) * 0.5f; float num2 = 0f; for (int k = 0; k < list4.Count; k++) { Vector3 val5 = (list4[k] -= val4); num2 = Mathf.Max(new float[4] { num2, Mathf.Abs(val5.x), Mathf.Abs(val5.y), Mathf.Abs(val5.z) }); } if (num2 > 0.0001f) { float num3 = 1f / num2; for (int l = 0; l < list4.Count; l++) { List<Vector3> list7 = list4; int index = l; list7[index] *= num3; } } Mesh val7 = new Mesh { name = meshName }; if (list4.Count > 65535) { val7.indexFormat = (IndexFormat)1; } val7.SetVertices(list4); if (list5.Count == list4.Count) { val7.SetUVs(0, list5); } val7.SetTriangles(list6, 0); val7.RecalculateNormals(); val7.RecalculateBounds(); val7.RecalculateTangents(); return val7; } private static int AddFaceVertex(string token, List<Vector3> positions, List<Vector2> uvs, List<Vector3> normals, List<Vector3> outPositions, List<Vector2> outUvs, List<Vector3> outNormals, Dictionary<(int, int, int), int> vertexKey) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) string[] array = token.Split('/'); int num = ParseIndex(array[0], positions.Count); int num2 = ((array.Length > 1 && array[1].Length > 0) ? ParseIndex(array[1], uvs.Count) : (-1)); int num3 = ((array.Length > 2 && array[2].Length > 0) ? ParseIndex(array[2], normals.Count) : (-1)); (int, int, int) key = (num, num2, num3); if (vertexKey.TryGetValue(key, out var value)) { return value; } int count = outPositions.Count; outPositions.Add(positions[num]); outUvs.Add((num2 >= 0) ? uvs[num2] : Vector2.zero); outNormals.Add((num3 >= 0) ? normals[num3] : Vector3.up); vertexKey[key] = count; return count; } private static int ParseIndex(string raw, int count) { int num = int.Parse(raw, CultureInfo.InvariantCulture); if (num >= 0) { return num - 1; } return count + num; } private static float Parse(string raw) { return float.Parse(raw, CultureInfo.InvariantCulture); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("PeakShotgun", "PeakShotgun", "1.0.6")] public class Plugin : BaseUnityPlugin { private static ConfigEntry<int>? shots; private static ConfigEntry<bool>? recoilEnabled; private static ConfigEntry<float>? recoil; private static ConfigEntry<bool>? debugMode; private static ConfigEntry<bool>? canSpawnOnAnyBiome; internal const int GuaranteedLuggageShotguns = 2; internal const int MaxShotgunsPerBiome = 4; internal static readonly SpawnPool AllLuggagePools = (SpawnPool)1963064320; private static ConfigEntry<float>? poseRight; private static ConfigEntry<float>? poseUp; private static ConfigEntry<float>? poseForward; private static ConfigEntry<float>? poseLeftHandLeft; private static ConfigEntry<float>? poseRightWristTilt; private static ConfigEntry<float>? poseToeIn; private static ConfigEntry<float>? poseMuzzleUp; private DateTime lastConfigWriteUtc; private float nextConfigCheck; internal static readonly Quaternion HeldBaseRotation = Quaternion.Inverse(Quaternion.LookRotation(Vector3.left, Vector3.forward)); private bool reportedMissingBlowgun; private Coroutine? shoreSpawnRoutine; private bool buildingShotgun; public const string Id = "PeakShotgun"; internal static ManualLogSource Log { get; private set; } = null; internal static Plugin Instance { get; private set; } = null; internal static GameObject? ShotgunPrefab { get; private set; } internal static int LocalConfiguredShots => Mathf.Max(1, shots?.Value ?? 5); internal static int ShotCount => HostShotSync.ShotCount; internal static float ModelScale { get; private set; } = 0.015f; internal static float Recoil { get { ConfigEntry<bool>? obj = recoilEnabled; if (obj != null && !obj.Value) { return 0f; } return recoil?.Value ?? 5f; } } internal static bool DebugMode => debugMode?.Value ?? false; internal static bool CanSpawnOnAnyBiome => canSpawnOnAnyBiome?.Value ?? false; internal static SpawnPool ShotgunLuggagePools { get { //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (!CanSpawnOnAnyBiome) { return (SpawnPool)67108864; } return AllLuggagePools; } } internal static float LeftHandLeft => poseLeftHandLeft?.Value ?? 0.09f; internal static float RightWristTilt => poseRightWristTilt?.Value ?? 30f; internal static Vector3 HeldDefaultPos => new Vector3(poseRight?.Value ?? 0.5f, poseUp?.Value ?? (-0.4f), poseForward?.Value ?? 1.15f); internal static float HeldToeIn => poseToeIn?.Value ?? (-6f); internal static float HeldMuzzleUp => poseMuzzleUp?.Value ?? 8f; internal static int PoseVersion { get; private set; } internal static float ModelRotX { get; private set; } internal static float ModelRotY { get; private set; } internal static float ModelRotZ { get; private set; } internal static float RestPosX { get; private set; } internal static float RestPosY { get; private set; } internal static float RestPosZ { get; private set; } internal static float RestRotX { get; private set; } internal static float RestRotY { get; private set; } internal static float RestRotZ { get; private set; } internal static float LuggageYaw { get; private set; } internal static float RestMeshLift { get; private set; } internal static float LuggageLiftExtra { get; private set; } internal static Vector3 GripMeshPoint { get; private set; } internal static Vector3 ForendMeshPoint { get; private set; } internal static Quaternion HeldAim => Quaternion.Euler(ModelRotX - HeldMuzzleUp, ModelRotY - HeldToeIn, ModelRotZ); internal static Quaternion HeldLocalRotation => HeldAim * HeldBaseRotation; internal static Vector3 HeldLocalPosition => -(HeldLocalRotation * (GripMeshPoint * ModelScale)); internal static Vector3 RestLocalPosition => new Vector3(RestPosX, RestPosY + RestMeshLift, RestPosZ); internal static Quaternion RestLocalRotation => Quaternion.Euler(RestRotX, RestRotY, RestRotZ); internal static Vector3 MuzzleMeshPoint { get; private set; } public static string Name => "PeakShotgun"; public static string Version => "1.0.6"; internal static void UpdateMeshAnchors(Mesh mesh) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: 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_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = mesh.bounds; Vector3[] vertices = mesh.vertices; Bounds val = SliceBounds(vertices, bounds, 0.64f, 0.72f); Bounds val2 = SliceBounds(vertices, bounds, 0.18f, 0.3f); GripMeshPoint = ((Bounds)(ref val)).center; ForendMeshPoint = new Vector3(((Bounds)(ref val2)).center.x, ((Bounds)(ref val2)).center.y, ((Bounds)(ref val2)).min.z); Bounds val3 = SliceBounds(vertices, bounds, 0f, 0.02f); MuzzleMeshPoint = new Vector3(((Bounds)(ref bounds)).min.x, ((Bounds)(ref val3)).center.y, ((Bounds)(ref val3)).center.z); RestMeshLift = 0f - MinRestYInItemSpace(mesh.vertices, new Vector3(RestPosX, RestPosY, RestPosZ)); ManualLogSource log = Log; if (log != null) { log.LogInfo((object)$"Mesh anchors: grip={GripMeshPoint}, forend={ForendMeshPoint}, muzzle={MuzzleMeshPoint}, restLift={RestMeshLift:0.###}."); } } private static Bounds SliceBounds(Vector3[] vertices, Bounds whole, float t0, float t1) { //IL_0002: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: 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_00ca: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Lerp(((Bounds)(ref whole)).min.x, ((Bounds)(ref whole)).max.x, t0); float num2 = Mathf.Lerp(((Bounds)(ref whole)).min.x, ((Bounds)(ref whole)).max.x, t1); Vector3 val = Vector3.positiveInfinity; Vector3 val2 = Vector3.negativeInfinity; foreach (Vector3 val3 in vertices) { if (val3.x >= num && val3.x <= num2) { val = Vector3.Min(val, val3); val2 = Vector3.Max(val2, val3); } } if (val.x > val2.x) { return new Bounds(new Vector3((num + num2) * 0.5f, ((Bounds)(ref whole)).center.y, ((Bounds)(ref whole)).center.z), Vector3.zero); } Bounds result = default(Bounds); ((Bounds)(ref result)).SetMinMax(val, val2); return result; } internal static void ConfigureLuggageSpawn(Item item, Mesh mesh) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_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) Vector3 restLocalPosition = RestLocalPosition; float num = MinRestYInItemSpace(mesh.vertices, restLocalPosition); float num2 = MaxRestYInItemSpace(mesh.vertices, restLocalPosition); float num3 = (num + num2) * 0.5f; float num4 = num3 - num; item.offsetLuggageSpawn = true; item.offsetLuggageRotation = Vector3.zero; item.offsetLuggagePosition = new Vector3(0f, num4 + LuggageLiftExtra, 0f); ManualLogSource log = Log; if (log != null) { log.LogInfo((object)$"Luggage spawn offset Y={item.offsetLuggagePosition.y:0.###} (rest Y {num:0.###}..{num2:0.###}, LuggageYaw={LuggageYaw})."); } } internal static Quaternion LuggageVisualRotation(Transform itemRoot, Vector3 luggageWorldUp) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) Vector3 val = itemRoot.InverseTransformDirection(luggageWorldUp); if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.up; } ((Vector3)(ref val)).Normalize(); Vector3 val2 = Vector3.ProjectOnPlane(Vector3.right, val); if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { val2 = Vector3.ProjectOnPlane(Vector3.forward, val); } Vector3 val3 = Quaternion.AngleAxis(LuggageYaw, val) * ((Vector3)(ref val2)).normalized; return Quaternion.LookRotation(val3, val) * HeldBaseRotation; } private static float MinRestYInItemSpace(Vector3[] vertices, Vector3 visualLocalPos) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) float num = float.MaxValue; Quaternion restLocalRotation = RestLocalRotation; float modelScale = ModelScale; foreach (Vector3 val in vertices) { float y = (visualLocalPos + restLocalRotation * (val * modelScale)).y; if (y < num) { num = y; } } return num; } private static float MaxRestYInItemSpace(Vector3[] vertices, Vector3 visualLocalPos) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) float num = float.MinValue; Quaternion restLocalRotation = RestLocalRotation; float modelScale = ModelScale; foreach (Vector3 val in vertices) { float y = (visualLocalPos + restLocalRotation * (val * modelScale)).y; if (y > num) { num = y; } } return num; } private void Awake() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_03e4: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; shots = ((BaseUnityPlugin)this).Config.Bind<int>("Shotgun", "Shots", 5, new ConfigDescription("Shots in each shotgun. Host's value is used in multiplayer. Save the .cfg and start a new map (no need to quit PEAK).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 999), Array.Empty<object>())); recoilEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Shotgun", "EnableRecoil", true, "Push the shooter back on each shot. Strength is Recoil."); recoil = ((BaseUnityPlugin)this).Config.Bind<float>("Shotgun", "Recoil", 5f, new ConfigDescription("Metres per second the shooter is pushed back, opposite the aim, on each shot. Used when EnableRecoil is true.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); canSpawnOnAnyBiome = ((BaseUnityPlugin)this).Config.Bind<bool>("Shotgun", "CanSpawnOnAnyBiome", false, "If false (default), shotguns only appear in Roots luggage. If true, they can also roll in luggage in other biomes. Roots always forces two random suitcases to contain a shotgun either way."); ShotgunCombat.Bind(((BaseUnityPlugin)this).Config); debugMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableDebugMode", false, "Host spawns test zombies, a shotgun and luggage near the player at the Airport and on the Shore. Off = spawn nothing."); ModelScale = ((BaseUnityPlugin)this).Config.Bind<float>("Model", "Scale", 0.5f, "Uniform scale of the custom shotgun mesh (mesh is unit-normalized). Keep ≤0.55 so standing over it does not hit the camera near-clip.").Value; poseRight = ((BaseUnityPlugin)this).Config.Bind<float>("HoldPose", "Right", 0.5f, "Item.defaultPos.x: how far right of the head the gun and both hands are held. 0 = centred."); poseUp = ((BaseUnityPlugin)this).Config.Bind<float>("HoldPose", "Up", -0.4f, "Item.defaultPos.y: height relative to the head bone. The blowgun uses 0.33 (mouth). Bigger = higher on screen."); poseForward = ((BaseUnityPlugin)this).Config.Bind<float>("HoldPose", "Forward", 1.15f, "Item.defaultPos.z: metres in front of the head the gun is pulled toward (vanilla items use 1). The arms stop it at their reach, so past that it mostly changes how hard it is pulled."); poseLeftHandLeft = ((BaseUnityPlugin)this).Config.Bind<float>("HoldPose", "LeftHandLeft", 0.09f, "Metres the left hand sits left of the pump centre. Negative = right."); poseRightWristTilt = ((BaseUnityPlugin)this).Config.Bind<float>("HoldPose", "RightWristTiltDegrees", 30f, "Degrees the right hand's fingers tip up on the grip. Bigger = right elbow lower. 0 = the vanilla RopeShooter grip."); poseToeIn = ((BaseUnityPlugin)this).Config.Bind<float>("HoldPose", "ToeInDegrees", -6f, "Degrees the barrel turns left toward the crosshair. Negative = barrel turns right. 0 = parallel to the aim."); poseMuzzleUp = ((BaseUnityPlugin)this).Config.Bind<float>("HoldPose", "MuzzleUpDegrees", 8f, "Degrees the gun pitches about the grip: muzzle up and stock down. 0 = level with the aim. Negative = stock up."); ModelRotX = ((BaseUnityPlugin)this).Config.Bind<float>("Model", "RotX", 0f, "Extra held local X euler on top of barrel-forward alignment.").Value; ModelRotY = ((BaseUnityPlugin)this).Config.Bind<float>("Model", "RotY", 0f, "Extra held local Y euler on top of barrel-forward alignment.").Value; ModelRotZ = ((BaseUnityPlugin)this).Config.Bind<float>("Model", "RotZ", 0f, "Extra held local Z euler on top of barrel-forward alignment.").Value; RestPosX = ((BaseUnityPlugin)this).Config.Bind<float>("Model", "RestPosX", 0f, "Rest (luggage/ground) local X offset of the custom mesh.").Value; RestPosY = ((BaseUnityPlugin)this).Config.Bind<float>("Model", "RestPosY", 0f, "Extra padding above the floor after auto-sitting the mesh on its lowest point.").Value; RestPosZ = ((BaseUnityPlugin)this).Config.Bind<float>("Model", "RestPosZ", 0f, "Rest (luggage/ground) local Z offset of the custom mesh.").Value; RestRotX = ((BaseUnityPlugin)this).Config.Bind<float>("Model", "RestRotX", 0f, "Rest (luggage/ground) local X euler rotation of the custom mesh.").Value; RestRotY = ((BaseUnityPlugin)this).Config.Bind<float>("Model", "RestRotY", 0f, "Rest local Y euler. Leave 0 — non-zero tips the barrel at the sky in luggage.").Value; RestRotZ = ((BaseUnityPlugin)this).Config.Bind<float>("Model", "RestRotZ", 0f, "Rest (luggage/ground) local Z euler rotation of the custom mesh.").Value; LuggageYaw = ((BaseUnityPlugin)this).Config.Bind<float>("Model", "LuggageYaw", 45f, "Luggage-only yaw around the suitcase floor normal (degrees). Flip sign if diagonal goes the wrong way.").Value; LuggageLiftExtra = ((BaseUnityPlugin)this).Config.Bind<float>("Model", "LuggageFloorPad", 0.025f, "Extra padding above the luggage floor after snapping the mesh bottom onto the suitcase lining.").Value; new Harmony(Name ?? "PeakShotgun").PatchAll(); ((Component)this).gameObject.AddComponent<ShotgunCameraNearClip>(); ((Component)this).gameObject.AddComponent<HostShotSync>(); ((MonoBehaviour)this).StartCoroutine(WaitForBlowgun()); shoreSpawnRoutine = ((MonoBehaviour)this).StartCoroutine(ShoreTestSpawns.WhenTheShoreIsReady()); SceneManager.sceneLoaded += OnSceneLoaded; lastConfigWriteUtc = SafeConfigWriteTime(); LogPose("Held pose at startup"); Log.LogInfo((object)("Plugin " + Name + " is loaded.")); } private DateTime SafeConfigWriteTime() { try { return File.GetLastWriteTimeUtc(((BaseUnityPlugin)this).Config.ConfigFilePath); } catch (Exception) { return DateTime.MinValue; } } private static void LogPose(string prefix) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) Log.LogInfo((object)$"{prefix}: defaultPos={HeldDefaultPos}, toeIn={HeldToeIn:0.#}°, muzzleUp={HeldMuzzleUp:0.#}°."); } private void Update() { if (!(Time.unscaledTime < nextConfigCheck)) { nextConfigCheck = Time.unscaledTime + 0.5f; DateTime dateTime = SafeConfigWriteTime(); if (!(dateTime == lastConfigWriteUtc)) { ReloadConfigFromDisk("cfg changed"); } } } private void ReloadConfigFromDisk(string reason) { try { lastConfigWriteUtc = SafeConfigWriteTime(); ((BaseUnityPlugin)this).Config.Reload(); PoseVersion++; ApplyLuggageSpawnConfig(); HostShotSync.SyncFromLocalRole(reason); LogPose("Config reloaded (" + reason + "); held pose now"); Log.LogInfo((object)$"Config reloaded ({reason}); shots per shotgun now {ShotCount}."); } catch (Exception ex) { Log.LogWarning((object)("Config reload failed (" + reason + "): " + ex.Message)); } } internal static void ApplyShotCountConfig() { int shotCount = ShotCount; if ((Object)(object)ShotgunPrefab != (Object)null) { Item component = ShotgunPrefab.GetComponent<Item>(); if ((Object)(object)component != (Object)null) { component.totalUses = shotCount; } } foreach (ShotgunInstanceSetup item in ShotgunInstanceSetup.Active) { if (!((Object)(object)item?.Item == (Object)null)) { item.Item.totalUses = shotCount; } } ShotgunAmmoUI.Refresh(); } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { ReloadConfigFromDisk("map load"); if (shoreSpawnRoutine != null) { ((MonoBehaviour)this).StopCoroutine(shoreSpawnRoutine); } shoreSpawnRoutine = ((MonoBehaviour)this).StartCoroutine(ShoreTestSpawns.WhenTheShoreIsReady()); RootsLuggagePatch.ResetGuarantees(); } private IEnumerator WaitForBlowgun() { WaitForSecondsRealtime wait = new WaitForSecondsRealtime(0.5f); while ((Object)(object)ShotgunPrefab == (Object)null) { try { CreateFromBlowgun(); } catch (Exception ex) { Log.LogWarning((object)("Could not create the shotgun yet: " + ex.Message)); } if ((Object)(object)ShotgunPrefab != (Object)null) { break; } yield return wait; } } internal void CreateFromBlowgun() { if ((Object)(object)ShotgunPrefab != (Object)null || buildingShotgun) { return; } ItemDatabase instance = SingletonAsset<ItemDatabase>.Instance; if (((DatabaseAsset<ItemDatabase, Item>)(object)instance)?.Objects == null || ((DatabaseAsset<ItemDatabase, Item>)(object)instance).Objects.Count == 0) { return; } Item val = FindBlowgun(instance); if ((Object)(object)val == (Object)null) { if (!reportedMissingBlowgun) { reportedMissingBlowgun = true; Log.LogError((object)$"The item catalog has {((DatabaseAsset<ItemDatabase, Item>)(object)instance).Objects.Count} items, and none is the blowgun."); } return; } buildingShotgun = true; try { BuildShotgunFromBlowgun(val, instance); } finally { buildingShotgun = false; } } private void BuildShotgunFromBlowgun(Item blowgun, ItemDatabase database) { //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Expected O, but got Unknown //IL_02a4: Unknown result type (might be due to invalid IL or missing references) Log.LogInfo((object)("Building the shotgun from " + ((Object)blowgun).name + ".")); bool activeSelf = ((Component)blowgun).gameObject.activeSelf; if (activeSelf) { ((Component)blowgun).gameObject.SetActive(false); } GameObject val = Object.Instantiate<GameObject>(((Component)blowgun).gameObject); if (activeSelf) { ((Component)blowgun).gameObject.SetActive(true); } ((Object)val).name = "Shotgun"; val.SetActive(false); Object.DontDestroyOnLoad((Object)(object)val); Action_RaycastDart component = val.GetComponent<Action_RaycastDart>(); Transform val2 = (((Object)(object)component != (Object)null) ? component.spawnTransform : val.transform); SFX_Instance val3 = (((Object)(object)component != (Object)null) ? component.shotSFX : null); ItemAction[] components = val.GetComponents<ItemAction>(); foreach (ItemAction val4 in components) { Object.DestroyImmediate((Object)(object)val4); } ParticleSystem[] componentsInChildren = val.GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem val5 in componentsInChildren) { Object.DestroyImmediate((Object)(object)val5); } Transform val6 = ShotgunModelSwap.Apply(val, database); if ((Object)(object)val6 != (Object)null) { val2 = val6; } Item component2 = val.GetComponent<Item>(); component2.usingTimePrimary = 0f; component2.showUseProgress = true; component2.totalUses = ShotCount; component2.UIData.itemName = "Shotgun"; ApplyIcon(component2); component2.UIData.hideFuel = false; component2.UIData.hasMainInteract = true; component2.UIData.mainInteractPrompt = "SHOOT"; if ((Object)(object)val2 == (Object)null) { val2 = val.transform; } Action_Gun action_Gun = val.AddComponent<Action_Gun>(); action_Gun.maxDistance = 40f; action_Gun.pelletRadius = 0.2f; action_Gun.fireRate = 0.85f; action_Gun.spread = 0.07f; action_Gun.pelletCount = 8; ((ItemAction)action_Gun).OnHeld = true; action_Gun.spawnTransform = val2; action_Gun.shotSFX = PlaceholderShot() ?? val3; ItemUseFeedback val7 = default(ItemUseFeedback); if (val.TryGetComponent<ItemUseFeedback>(ref val7)) { val7.sfxUsed = null; } GameObject val8 = ShotgunVFX.FindSmoke(); if ((Object)(object)val8 == (Object)null) { Log.LogWarning((object)"No PEAK smoke effect was found. The shot will only flash a light."); } else { Log.LogInfo((object)("Muzzle smoke uses " + ((Object)val8).name + ".")); } val.AddComponent<ShotgunVFX>().Build(val2, val8); action_Gun.afflictionsOnHit = (Affliction[])(object)new Affliction[1] { (Affliction)new Affliction_AdjustStatus((STATUSTYPE)0, 0.35f, 1f) }; val.AddComponent<Action_Ammo>(); LootData val9 = val.GetComponent<LootData>() ?? val.AddComponent<LootData>(); val9.banInSolo = false; val9.rarityOverrides.Clear(); ApplyLuggageSpawnConfig(val9); LootData.AllSpawnWeightData = null; new ItemContent(component2).Register(ModDefinition.GetOrCreate(((BaseUnityPlugin)this).Info)); ShotgunPrefab = val; Log.LogInfo((object)(CanSpawnOnAnyBiome ? $"Registered the shotgun for all biomes' luggage ({2} random Roots suitcases always forced)." : $"Registered the shotgun for Roots luggage only ({2} random suitcases always forced).")); } internal static void ApplyLuggageSpawnConfig(LootData? loot = null) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)loot == (Object)null && (Object)(object)ShotgunPrefab != (Object)null) { loot = ShotgunPrefab.GetComponent<LootData>(); } if (!((Object)(object)loot == (Object)null)) { loot.spawnLocations = ShotgunLuggagePools; loot.Rarity = (Rarity)(CanSpawnOnAnyBiome ? 6 : 2); LootData.AllSpawnWeightData = null; RootsLuggagePatch.ResetGuarantees(); } } private static void ApplyIcon(Item item) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Peak.Shotgun.icons.ShotgunIcon.png"); if (stream == null) { Log.LogWarning((object)"Shotgun icon resource was not found."); return; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, memoryStream.ToArray())) { Log.LogWarning((object)"Shotgun icon could not be decoded."); return; } ((Object)val).name = "Shotgun"; ((Texture)val).wrapMode = (TextureWrapMode)1; item.UIData.icon = val; } private static SFX_Instance? PlaceholderShot() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown AudioClip val = LoadWav("Peak.Shotgun.sounds.shotgun_fire_01.wav"); if ((Object)(object)val == (Object)null) { Log.LogWarning((object)"Shotgun fire sound was not found. Using the blowgun sound."); return null; } SFX_Instance val2 = ScriptableObject.CreateInstance<SFX_Instance>(); val2.clips = (AudioClip[])(object)new AudioClip[1] { val }; val2.settings = new SFX_Settings { volume = 0.85f, volume_Variation = 0.05f, pitch = 1f, pitch_Variation = 0.04f, spatialBlend = 1f, range = 80f, cooldown = 0.05f }; return val2; } private static AudioClip? LoadWav(string resourceName) { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName); if (stream == null) { return null; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); byte[] array = memoryStream.ToArray(); if (array.Length < 44 || array[0] != 82 || array[1] != 73 || array[2] != 70 || array[3] != 70) { return null; } int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 12; while (num6 + 8 <= array.Length) { string text = Encoding.ASCII.GetString(array, num6, 4); int num7 = BitConverter.ToInt32(array, num6 + 4); int num8 = num6 + 8; if (text == "fmt " && num7 >= 16) { num = BitConverter.ToInt16(array, num8 + 2); num2 = BitConverter.ToInt32(array, num8 + 4); num3 = BitConverter.ToInt16(array, num8 + 14); } else if (text == "data") { num4 = num8; num5 = num7; break; } num6 = num8 + num7 + num7 % 2; } if (num <= 0 || num2 <= 0 || num3 != 16 || num4 == 0 || num4 + num5 > array.Length) { Log.LogWarning((object)"Shotgun fire sound is not 16-bit PCM."); return null; } int num9 = num5 / 2; float[] array2 = new float[num9]; for (int i = 0; i < num9; i++) { short num10 = BitConverter.ToInt16(array, num4 + i * 2); array2[i] = (float)num10 / 32768f; } AudioClip val = AudioClip.Create("shotgun_fire_01", num9 / num, num, num2, false); val.SetData(array2, 0); return val; } private static Item? FindBlowgun(ItemDatabase database) { Item val = null; for (int i = 0; i < ((DatabaseAsset<ItemDatabase, Item>)(object)database).Objects.Count; i++) { Item val2 = ((DatabaseAsset<ItemDatabase, Item>)(object)database).Objects[i]; if (!((Object)(object)val2 == (Object)null)) { string text = ((val2.UIData != null) ? (val2.UIData.itemName ?? "") : ""); bool flag = ((Object)val2).name.IndexOf("Blowgun", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)val2).name.IndexOf("HealingDart", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Blowgun", StringComparison.OrdinalIgnoreCase) >= 0; bool flag2 = (Object)(object)((Component)val2).GetComponent<Action_RaycastDart>() != (Object)null; if (flag2 && flag) { return val2; } if (flag2 && (Object)(object)val == (Object)null) { val = val2; } } } return val; } } [HarmonyPatch(typeof(ItemDatabase), "OnLoaded")] internal static class ItemDatabasePatch { [HarmonyPostfix] private static void CreateShotgun() { Plugin.Instance?.CreateFromBlowgun(); } } [HarmonyPatch(typeof(Spawner), "GetObjectsToSpawn")] internal static class SpawnerLootContextPatch { [HarmonyPrefix] private static void Begin(Spawner __instance) { RootsLuggagePatch.BeginSpawn(__instance); } [HarmonyPostfix] private static void End() { RootsLuggagePatch.EndSpawn(); } } [HarmonyPatch(typeof(LootData), "GetRandomItems")] internal static class RootsLuggagePatch { private static Spawner? currentSpawner; private static HashSet<int>? chosenLuggageIds; private static bool assignedThisRun; private static readonly Dictionary<SpawnPool, int> spawnedPerBiome = new Dictionary<SpawnPool, int>(); internal static void ResetGuarantees() { assignedThisRun = false; chosenLuggageIds = null; currentSpawner = null; spawnedPerBiome.Clear(); } internal static void BeginSpawn(Spawner spawner) { currentSpawner = spawner; } internal static void EndSpawn() { currentSpawner = null; } [HarmonyPostfix] private static void AfterLootRoll(SpawnPool spawnPool, ref List<GameObject>? __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) TryGuaranteeRootsShotgun(spawnPool, ref __result); EnforcePerBiomeCap(spawnPool, ref __result); } private static void TryGuaranteeRootsShotgun(SpawnPool spawnPool, ref List<GameObject>? __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) if ((spawnPool & 0x4000000) == 0) { return; } Spawner? obj = currentSpawner; Luggage val = (Luggage)(object)((obj is Luggage) ? obj : null); if (val == null) { return; } EnsureRandomLuggagePicked(val); if (chosenLuggageIds == null || !chosenLuggageIds.Contains(((Object)val).GetInstanceID())) { return; } GameObject shotgunPrefab = Plugin.ShotgunPrefab; if ((Object)(object)shotgunPrefab == (Object)null) { return; } if (__result == null) { __result = new List<GameObject>(); } for (int i = 0; i < __result.Count; i++) { if ((Object)(object)__result[i] == (Object)(object)shotgunPrefab) { return; } } __result.Insert(0, shotgunPrefab); Plugin.Log.LogInfo((object)("Forced shotgun into random Roots luggage '" + ((Object)val).name + "' " + $"({chosenLuggageIds.Count} marked this run).")); } private static void EnforcePerBiomeCap(SpawnPool spawnPool, ref List<GameObject>? __result) { //IL_0056: 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_0062: 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_0110: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) GameObject shotgunPrefab = Plugin.ShotgunPrefab; if (__result == null || (Object)(object)shotgunPrefab == (Object)null || !(currentSpawner is Luggage)) { return; } int num = 0; for (int i = 0; i < __result.Count; i++) { if ((Object)(object)__result[i] == (Object)(object)shotgunPrefab) { num++; } } if (num == 0) { return; } SpawnPool val = LuggageBiomeKey(currentSpawner, spawnPool); spawnedPerBiome.TryGetValue(val, out var value); int num2 = Mathf.Max(0, 4 - value); if (num2 <= 0) { RemoveAllShotguns(__result, shotgunPrefab); Plugin.Log.LogInfo((object)($"Blocked shotgun in '{((Object)currentSpawner).name}' — biome {val} already hit cap " + $"{4} this run.")); return; } int num3 = 0; int num4 = 0; while (num4 < __result.Count) { if ((Object)(object)__result[num4] != (Object)(object)shotgunPrefab) { num4++; } else if (num3 < num2) { num3++; num4++; } else { __result.RemoveAt(num4); } } if (num3 > 0) { spawnedPerBiome[val] = value + num3; Plugin.Log.LogInfo((object)($"Luggage '{((Object)currentSpawner).name}' biome {val}: +{num3} shotgun " + $"({spawnedPerBiome[val]}/{4} this run).")); } } private static void RemoveAllShotguns(List<GameObject> result, GameObject shotgun) { for (int num = result.Count - 1; num >= 0; num--) { if ((Object)(object)result[num] == (Object)(object)shotgun) { result.RemoveAt(num); } } } private static SpawnPool LuggageBiomeKey(Spawner spawner, SpawnPool rolledPool) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) SpawnPool spawnPool; try { spawnPool = spawner.GetSpawnPool(); } catch { spawnPool = spawner.spawnPool; } SpawnPool val = (SpawnPool)(spawnPool & Plugin.AllLuggagePools); if ((int)val == 0) { val = (SpawnPool)(rolledPool & Plugin.AllLuggagePools); } if ((int)val != 0) { return val; } return rolledPool; } private static void EnsureRandomLuggagePicked(Luggage opening) { if (assignedThisRun) { return; } assignedThisRun = true; List<Luggage> list = new List<Luggage>(); foreach (Luggage item in Luggage.ALL_LUGGAGE) { if (UsesRootsPool((Spawner)(object)item)) { list.Add(item); } } if (UsesRootsPool((Spawner)(object)opening) && !list.Contains(opening)) { list.Add(opening); } chosenLuggageIds = new HashSet<int>(); if (list.Count == 0) { Plugin.Log.LogWarning((object)"No Roots luggage found to mark for shotgun spawns."); return; } for (int num = list.Count - 1; num > 0; num--) { int num2 = Random.Range(0, num + 1); List<Luggage> list2 = list; int index = num; int index2 = num2; Luggage value = list[num2]; Luggage value2 = list[num]; list2[index] = value; list[index2] = value2; } int num3 = Mathf.Min(2, list.Count); for (int i = 0; i < num3; i++) { chosenLuggageIds.Add(((Object)list[i]).GetInstanceID()); } Plugin.Log.LogInfo((object)$"Marked {num3} random Roots luggage for a shotgun (of {list.Count} candidates)."); } private static bool UsesRootsPool(Spawner spawner) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_0014: 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_0020: Invalid comparison between Unknown and I4 try { return (spawner.GetSpawnPool() & 0x4000000) > 0; } catch { return (spawner.spawnPool & 0x4000000) > 0; } } } internal static class ShoreTestSpawns { private const int ZombieCount = 3; private static readonly string[] LuggagePrefabNames = new string[4] { "LuggageBig", "Luggage", "LuggageSmall", "LuggageEpic" }; internal static IEnumerator WhenTheShoreIsReady() { if (!Plugin.DebugMode) { yield break; } WaitForSecondsRealtime wait = new WaitForSecondsRealtime(1f); bool spawnedShore = false; bool spawnedAirport = false; while (!spawnedShore || !spawnedAirport) { yield return wait; if (!PhotonNetwork.InRoom || !PhotonNetwork.IsMasterClient || LoadingScreenHandler.loading) { continue; } Character localCharacter = Character.localCharacter; if (!((Object)(object)localCharacter == (Object)null) && !((Object)(object)Plugin.ShotgunPrefab == (Object)null)) { if (!spawnedAirport && IsAirport()) { SpawnShotgun(localCharacter, "Airport"); SpawnLuggage(localCharacter, "Airport"); spawnedAirport = true; } else if (!spawnedShore && MapHandler.ExistsAndInitialized && (int)Singleton<MapHandler>.Instance.GetCurrentBiome() == 0) { SpawnNear(localCharacter); SpawnShotgun(localCharacter, "Shore"); spawnedShore = true; } } } } private static bool IsAirport() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); return ((Scene)(ref activeScene)).name == "Airport"; } private static void SpawnShotgun(Character player, string place) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) GameObject shotgunPrefab = Plugin.ShotgunPrefab; if ((Object)(object)shotgunPrefab == (Object)null) { return; } Vector3 val = GroundPoint(player.Center + ((Component)player).transform.forward * 4f); try { PhotonNetwork.InstantiateItemRoom(((Object)shotgunPrefab).name, val, Quaternion.identity, false); Plugin.Log.LogInfo((object)("Spawned a test shotgun at the " + place + ".")); } catch (Exception ex) { Plugin.Log.LogError((object)("Could not spawn the " + place + " test shotgun: " + ex.Message)); } } private static void SpawnLuggage(Character player, string place) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) Vector3 val = GroundPoint(player.Center + ((Component)player).transform.forward * 4f - ((Component)player).transform.right * 2f); Quaternion val2 = Quaternion.Euler(0f, ((Component)player).transform.eulerAngles.y, 0f); string[] luggagePrefabNames = LuggagePrefabNames; foreach (string text in luggagePrefabNames) { try { GameObject val3 = PhotonNetwork.Instantiate(text, val, val2, (byte)0, (object[])null); if (!((Object)(object)val3 == (Object)null)) { Luggage component = val3.GetComponent<Luggage>(); if (!((Object)(object)component == (Object)null)) { ((Spawner)component).spawnPool = (SpawnPool)67108864; component.OpenImmediatelyNoNotify(); Plugin.Log.LogInfo((object)("Spawned test luggage '" + text + "' at the " + place + ".")); return; } Plugin.Log.LogWarning((object)("Spawned '" + text + "' at the " + place + " but it has no Luggage component.")); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not spawn luggage prefab '" + text + "' at the " + place + ": " + ex.Message)); } } Plugin.Log.LogError((object)("Could not spawn any luggage prefab at the " + place + ".")); } private static Vector3 GroundPoint(Vector3 point) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) Vector3 val = point + Vector3.up * 30f; RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(val, Vector3.down, ref val2, 80f, LayerMask.op_Implicit(HelperFunctions.terrainMapMask), (QueryTriggerInteraction)1)) { return ((RaycastHit)(ref val2)).point + Vector3.up * 0.08f; } return point; } private static void SpawnNear(Character player) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) Vector3 center = player.Center; int num = 0; RaycastHit val4 = default(RaycastHit); for (int i = 0; i < 3; i++) { float num2 = (float)i * 120f; Vector3 val = Quaternion.Euler(0f, num2, 0f) * (((Component)player).transform.forward * 14f); Vector3 val2 = center + val; Vector3 val3 = val2 + Vector3.up * 30f; if (Physics.Raycast(val3, Vector3.down, ref val4, 80f, LayerMask.op_Implicit(HelperFunctions.terrainMapMask), (QueryTriggerInteraction)1)) { val2 = ((RaycastHit)(ref val4)).point + Vector3.up * 0.5f; } try { PhotonNetwork.Instantiate("MushroomZombie", val2, Quaternion.identity, (byte)0, (object[])null); num++; } catch (Exception ex) { Plugin.Log.LogError((object)("Could not spawn a Shore test zombie: " + ex.Message)); return; } } Plugin.Log.LogInfo((object)$"Spawned {num} test zombies on the Shore."); } } internal static class ShotgunAmmoUI { internal static void Refresh() { if ((Object)(object)GUIManager.instance == (Object)null) { return; } if (GUIManager.instance.items != null) { InventoryItemUI[] items = GUIManager.instance.items; foreach (InventoryItemUI val in items) { if (val != null) { val.UpdateNameText(); } } } InventoryItemUI temporaryItem = GUIManager.instance.temporaryItem; if (temporaryItem != null) { temporaryItem.UpdateNameText(); } GUIManager.instance.UpdateItemPrompts(); } internal static bool TryGetRemaining(Item item, ItemInstanceData? data, out int remaining) { remaining = 0; if ((Object)(object)item == (Object)null || (Object)(object)((Component)item).GetComponent<Action_Gun>() == (Object)null) { return false; } OptionableIntItemData val = default(OptionableIntItemData); if (data != null && data.TryGetDataEntry<OptionableIntItemData>((DataEntryKey)2, ref val) && val.HasData && val.Value >= 0) { remaining = val.Value; return true; } OptionableIntItemData data2 = item.GetData<OptionableIntItemData>((DataEntryKey)2); if (data2.HasData && data2.Value >= 0) { remaining = data2.Value; return true; } if (item.totalUses > 0) { remaining = item.totalUses; return true; } return false; } } [HarmonyPatch(typeof(Item), "GetItemName")] internal static class ShotgunNamePatch { [HarmonyPostfix] private static void AppendShots(Item __instance, ItemInstanceData data, ref string __result) { if (ShotgunAmmoUI.TryGetRemaining(__instance, data, out var remaining)) { __result = $"{__result} ({remaining})"; } } } [HarmonyPatch(typeof(GUIManager), "GetMainInteractPrompt")] internal static class ShotgunPromptPatch { [HarmonyPostfix] private static void AppendShots(Item item, ref string __result) { if (ShotgunAmmoUI.TryGetRemaining(item, null, out var remaining)) { __result = $"{__result} ({remaining})"; } } } [DefaultExecutionOrder(32000)] internal sealed class ShotgunCameraNearClip : MonoBehaviour { private const float MinNearPlane = 0.001f; private const float FullNearRestoreDistance = 3f; private float defaultNear = -1f; private Camera? subscribedCam; private void OnEnable() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(OnAnyCameraPreCull)); } private void OnDisable() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown Camera.onPreCull = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(OnAnyCameraPreCull)); RestoreNear(subscribedCam); subscribedCam = null; } private void OnDestroy() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown Camera.onPreCull = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(OnAnyCameraPreCull)); RestoreNear(subscribedCam); } private void LateUpdate() { ApplyNearClip(GetPeakCamera()); } private void OnAnyCameraPreCull(Camera cam) { Camera peakCamera = GetPeakCamera(); if ((Object)(object)peakCamera != (Object)null && (Object)(object)cam == (Object)(object)peakCamera) { ApplyNearClip(peakCamera); } } private void ApplyNearClip(Camera? cam) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Invalid comparison between Unknown and I4 //IL_00ab: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)cam == (Object)null) { return; } subscribedCam = cam; if (defaultNear < 0f) { defaultNear = cam.nearClipPlane; if (defaultNear <= 0.002f) { defaultNear = 0.05f; } } float num = float.MaxValue; Vector3 position = ((Component)cam).transform.position; foreach (ShotgunInstanceSetup item2 in ShotgunInstanceSetup.Active) { if ((Object)(object)item2 == (Object)null) { continue; } Item item = item2.Item; if (!((Object)(object)item != (Object)null) || ((int)item.itemState != 1 && !((Object)(object)item.holderCharacter != (Object)null))) { float num2 = DistanceToVisual(position, item, ((Component)item2).transform); if (num2 < num) { num = num2; } } } if (num >= 3f) { cam.nearClipPlane = defaultNear; return; } float num3 = Mathf.Clamp01(num / 3f); float num4 = num3 * num3 * num3; cam.nearClipPlane = Mathf.Lerp(0.001f, defaultNear, num4); } private void RestoreNear(Camera? cam) { if ((Object)(object)cam != (Object)null && defaultNear > 0f) { cam.nearClipPlane = defaultNear; } } private static Camera? GetPeakCamera() { if (!((Object)(object)MainCamera.instance != (Object)null)) { return Camera.main; } return MainCamera.instance.cam; } private static float DistanceToVisual(Vector3 camPos, Item? item, Transform itemRoot) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing r