Decompiled source of PeakShotgun v1.0.25
plugins/PeakShotgun.dll
Decompiled a week 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 UnityEngine.UI; 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.25.0")] [assembly: AssemblyInformationalVersion("1.0.25+88c4ea6fbe8f6e39c2f5688776d748f97a856b66")] [assembly: AssemblyProduct("PeakShotgun")] [assembly: AssemblyTitle("PeakShotgun")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.25.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [CompilerGenerated] internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T> { int ICollection.Count => _items.Length; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection<T>.Count => _items.Length; T IReadOnlyList<T>.this[int index] => _items[index]; int ICollection<T>.Count => _items.Length; bool ICollection<T>.IsReadOnly => true; T IList<T>.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } public <>z__ReadOnlyArray(T[] items) { _items = items; } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.CopyTo(Array array, int index) { ((ICollection)_items).CopyTo(array, index); } int IList.Add(object value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object value) { return ((IList)_items).Contains(value); } int IList.IndexOf(object value) { return ((IList)_items).IndexOf(value); } void IList.Insert(int index, object value) { throw new NotSupportedException(); } void IList.Remove(object value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return ((IEnumerable<T>)_items).GetEnumerator(); } void ICollection<T>.Add(T item) { throw new NotSupportedException(); } void ICollection<T>.Clear() { throw new NotSupportedException(); } bool ICollection<T>.Contains(T item) { return ((ICollection<T>)_items).Contains(item); } void ICollection<T>.CopyTo(T[] array, int arrayIndex) { ((ICollection<T>)_items).CopyTo(array, arrayIndex); } bool ICollection<T>.Remove(T item) { throw new NotSupportedException(); } int IList<T>.IndexOf(T item) { return ((IList<T>)_items).IndexOf(item); } void IList<T>.Insert(int index, T item) { throw new NotSupportedException(); } void IList<T>.RemoveAt(int index) { throw new NotSupportedException(); } } 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; internal bool TrySpendOne() { if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient) { return false; } 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 false; } 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)); } return true; } 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 }); } } } internal bool TryRefillToCapacity() { if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient) { return false; } int shotCount = Plugin.ShotCount; ((ItemActionBase)this).item.totalUses = shotCount; 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 >= shotCount) { if (data.Value > shotCount) { data.Value = shotCount; BroadcastUses(shotCount); } return false; } data.HasData = true; data.Value = shotCount; BroadcastUses(shotCount); return true; } private void BroadcastUses(int remaining) { int num = Mathf.Max(((ItemActionBase)this).item.totalUses, Plugin.ShotCount); ((ItemActionBase)this).item.totalUses = num; if (!PhotonNetwork.InRoom) { ApplyUses(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, PhotonMessageInfo info) { //IL_0007: 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) if (!PhotonNetwork.InRoom || (info.Sender != null && info.Sender.IsMasterClient)) { ApplyUses(remaining, capacity); } } private void ApplyUses(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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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 || ((ItemActionBase)this).item.data == null) { return; } ItemSlot val2 = FindSlotHolding(val.player, ((ItemActionBase)this).item.data.guid); if (((val2 != null) ? val2.data : null) != null) { OptionableIntItemData val3 = default(OptionableIntItemData); if (val2.data.TryGetDataEntry<OptionableIntItemData>((DataEntryKey)2, ref val3)) { val3.HasData = true; val3.Value = remaining; return; } OptionableIntItemData val4 = new OptionableIntItemData { HasData = true, Value = remaining }; val2.data.RegisterEntry<OptionableIntItemData>((DataEntryKey)2, val4); } } private static ItemSlot? FindSlotHolding(Player player, Guid guid) { ItemSlot[] itemSlots = player.itemSlots; foreach (ItemSlot val in itemSlots) { if (((val != null) ? val.data : null) != null && val.data.guid == guid) { return val; } } ItemSlot tempFullSlot = player.tempFullSlot; if (((tempFullSlot != null) ? tempFullSlot.data : null) == null || !(tempFullSlot.data.guid == guid)) { return null; } return tempFullSlot; } } public class Action_Gun : ItemAction { private readonly struct PendingHit { public readonly int TargetId; public readonly Action Apply; public PendingHit(int targetId, Action apply) { TargetId = targetId; Apply = apply; } } 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 SFX_Instance? emptyClickSFX; public Action? OnShoot; private const float PendingShotRetry = 1.5f; private const float HostFireRateTolerance = 0.9f; private const float AuthorizedShotLifetime = 10f; private static int nextShotId; private float lastShootTime = float.NegativeInfinity; private int pendingShotId; private float pendingShotSentTime; private Vector3 pendingForward; private readonly Dictionary<int, (int shotId, bool accepted)> lastShotBySender = new Dictionary<int, (int, bool)>(); private double lastAcceptedShotTime = double.NegativeInfinity; private readonly Dictionary<long, float> authorizedShots = new Dictionary<long, float>(); private readonly Dictionary<long, HashSet<int>> consumedTargets = new Dictionary<long, HashSet<int>>(); private readonly Dictionary<long, List<PendingHit>> pendingHits = new Dictionary<long, List<PendingHit>>(); public override void RunAction() { //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_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) if (pendingShotId != 0) { if (Time.time >= pendingShotSentTime + 1.5f) { pendingForward = ((Component)MainCamera.instance).transform.forward; SendShotRequest(); } } else if (!(Time.time <= lastShootTime + fireRate) && !((Object)(object)spawnTransform == (Object)null)) { if (!HasAmmo()) { lastShootTime = Time.time; PlayEmptyClick(); return; } lastShootTime = Time.time; pendingShotId = ++nextShotId; pendingForward = ((Component)MainCamera.instance).transform.forward; SendShotRequest(); } } private void SendShotRequest() { pendingShotSentTime = Time.time; if (!PhotonNetwork.InRoom) { HandleShotRequest(pendingShotId, null, Time.timeAsDouble); return; } ((MonoBehaviourPun)this).photonView.RPC("RPC_RequestShot", (RpcTarget)2, new object[1] { pendingShotId }); } [PunRPC] public void RPC_RequestShot(int shotId, PhotonMessageInfo info) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (PhotonNetwork.IsMasterClient) { HandleShotRequest(shotId, info.Sender, ((PhotonMessageInfo)(ref info)).SentServerTime); } } private void HandleShotRequest(int shotId, Player? sender, double sentTime) { int num = ((sender != null) ? sender.ActorNumber : 0); if (lastShotBySender.TryGetValue(num, out (int, bool) value)) { if (shotId < value.Item1) { return; } if (shotId == value.Item1) { SendShotResult(num, shotId, value.Item2); return; } } double num2 = sentTime - lastAcceptedShotTime; bool flag = num2 >= (double)(fireRate * 0.9f) || num2 < -60.0; Action_Ammo component = ((Component)this).GetComponent<Action_Ammo>(); bool flag2 = IsHeldBy(sender) && flag && (Object)(object)component != (Object)null && component.TrySpendOne(); if (flag2) { lastAcceptedShotTime = sentTime; } lastShotBySender[num] = (shotId, flag2); SendShotResult(num, shotId, flag2); } private bool IsHeldBy(Player? sender) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 Character holderCharacter = ((ItemActionBase)this).item.holderCharacter; if ((int)((ItemActionBase)this).item.itemState != 1 || (Object)(object)holderCharacter == (Object)null) { return false; } if (sender != null) { if ((Object)(object)((MonoBehaviourPun)holderCharacter).photonView != (Object)null) { return ((MonoBehaviourPun)holderCharacter).photonView.Owner == sender; } return false; } return true; } private void SendShotResult(int shooterActor, int shotId, bool accepted) { if (!PhotonNetwork.InRoom) { OnShotResult(shotId, accepted); return; } if (accepted) { ((MonoBehaviourPun)this).photonView.RPC("RPC_ShotResult", (RpcTarget)0, new object[3] { shooterActor, shotId, true }); return; } Room currentRoom = PhotonNetwork.CurrentRoom; Player val = ((currentRoom != null) ? currentRoom.GetPlayer(shooterActor, false) : null); if (val != null) { ((MonoBehaviourPun)this).photonView.RPC("RPC_ShotResult", val, new object[3] { shooterActor, shotId, false }); } } [PunRPC] public void RPC_ShotResult(int shooterActor, int shotId, bool accepted, PhotonMessageInfo info) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (info.Sender != null && info.Sender.IsMasterClient) { if (accepted) { RecordAuthorizedShot(shooterActor, shotId); } if (PhotonNetwork.LocalPlayer != null && shooterActor == PhotonNetwork.LocalPlayer.ActorNumber) { OnShotResult(shotId, accepted); } } } private void OnShotResult(int shotId, bool accepted) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (shotId == pendingShotId) { pendingShotId = 0; if (accepted) { Fire(shotId, pendingForward); } } } private static long ShotKey(int shooterActor, int shotId) { return ((long)shooterActor << 32) | (uint)shotId; } private void RecordAuthorizedShot(int shooterActor, int shotId) { float time = Time.time; List<long> list = new List<long>(); foreach (KeyValuePair<long, float> authorizedShot in authorizedShots) { if (time - authorizedShot.Value > 10f) { list.Add(authorizedShot.Key); } } foreach (long item in list) { authorizedShots.Remove(item); consumedTargets.Remove(item); pendingHits.Remove(item); } long key = ShotKey(shooterActor, shotId); authorizedShots[key] = time; FlushPendingHits(key); } internal bool TryConsumeShot(Player? sender, int shotId, int targetId) { if (!PhotonNetwork.InRoom) { return true; } if (sender == null) { return false; } long key = ShotKey(sender.ActorNumber, shotId); if (!authorizedShots.ContainsKey(key)) { return false; } return ConsumeTarget(key, targetId); } internal bool TryConsumeOrDeferHit(Player? sender, int shotId, int targetId, Action apply) { if (!PhotonNetwork.InRoom) { return true; } if (sender == null) { return false; } long key = ShotKey(sender.ActorNumber, shotId); if (!authorizedShots.ContainsKey(key)) { if (!pendingHits.TryGetValue(key, out List<PendingHit> value)) { value = new List<PendingHit>(); pendingHits[key] = value; } value.Add(new PendingHit(targetId, apply)); return false; } return ConsumeTarget(key, targetId); } private bool ConsumeTarget(long key, int targetId) { if (!consumedTargets.TryGetValue(key, out HashSet<int> value)) { value = new HashSet<int>(); consumedTargets[key] = value; } return value.Add(targetId); } private void FlushPendingHits(long key) { if (!pendingHits.TryGetValue(key, out List<PendingHit> value)) { return; } pendingHits.Remove(key); foreach (PendingHit item in value) { if (ConsumeTarget(key, item.TargetId)) { item.Apply(); } } } private void PlayEmptyClick() { //IL_0021: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) Vector3 val = (((Object)(object)spawnTransform != (Object)null) ? spawnTransform.position : ((Component)this).transform.position); if (PhotonNetwork.InRoom) { ((MonoBehaviourPun)this).photonView.RPC("RPC_EmptyClick", (RpcTarget)0, new object[1] { val }); } else { PlayEmptyClickAt(val); } } [PunRPC] private void RPC_EmptyClick(Vector3 origin) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) PlayEmptyClickAt(origin); } private void PlayEmptyClickAt(Vector3 origin) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) SFX_Instance? obj = emptyClickSFX ?? shotSFX; if (obj != null) { obj.Play(origin); } } 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(int shotId, Vector3 forward) { //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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)spawnTransform == (Object)null) && !((Object)(object)((ItemActionBase)this).character == (Object)null) && ((ItemActionBase)this).character.IsLocal) { OnShoot?.Invoke(); Vector3 position = spawnTransform.position; 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>(); float[] array = new float[pelletCount * 4]; bool flag = false; 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; flag |= TryPellet(shotId, position, normalized, struck, out var end, out var impact); ShotgunVFX.PackPellet(array, i, end, impact); } if (flag) { ShotgunHitMarker.Show(defeat: false); } ((MonoBehaviourPun)this).photonView.RPC("RPC_ShotgunBlastFX", (RpcTarget)0, new object[3] { position, forward, array }); } } private bool TryPellet(int shotId, Vector3 origin, Vector3 direction, HashSet<int> struck, out Vector3 end, out bool impact) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_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_002e: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) float distance = maxDistance; end = origin + direction * maxDistance; impact = false; RaycastHit val = default(RaycastHit); if (Physics.Raycast(origin, direction, ref val, maxDistance, LayerMask.op_Implicit(HelperFunctions.terrainMapMask), (QueryTriggerInteraction)1)) { distance = ((RaycastHit)(ref val)).distance; end = ((RaycastHit)(ref val)).point; impact = true; } RaycastHit[] array = Physics.SphereCastAll(origin, pelletRadius, direction, distance, LayerMask.op_Implicit(HelperFunctions.CharacterAndDefaultMask) | ShotTargetRegistry.ExtraLayerMask, (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, shotId, ((RaycastHit)(ref val2)).point, direction)) { struck.Add(instanceID); end = ((((RaycastHit)(ref val2)).distance > 0f) ? ((RaycastHit)(ref val2)).point : (origin + direction * pelletRadius)); impact = true; return true; } } } return false; } [PunRPC] public void RPC_GunImpact(Player? hitPlayer, Vector3 endpoint, Vector3 direction, int shotId, PhotonMessageInfo info) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_007f: Unknown result type (might be due to invalid IL or missing references) if (hitPlayer == null || !hitPlayer.IsLocal) { return; } Character local = Character.localCharacter; if (!((Object)(object)local == (Object)null)) { int viewID = ((MonoBehaviourPun)local).photonView.ViewID; if (TryConsumeOrDeferHit(info.Sender, shotId, viewID, delegate { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) ApplyGunImpact(local, direction, endpoint); })) { ApplyGunImpact(local, direction, endpoint); } } } private void ApplyGunImpact(Character local, Vector3 direction, Vector3 endpoint) { //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) if (ShootableRules.Scouts.Enabled) { ((Component)local).GetComponent<GunCharacterLaunch>().Blast(direction, endpoint); Affliction[] array = afflictionsOnHit; foreach (Affliction val in array) { local.refs.afflictions.AddAffliction(val, false); } } } [PunRPC] public void RPC_HostShootTarget(int viewId, int kind, int shotId, int extra, PhotonMessageInfo info) { //IL_0008: 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) if (PhotonNetwork.IsMasterClient && TryConsumeShot(info.Sender, shotId, viewId)) { PhotonView val = PhotonView.Find(viewId); if ((Object)(object)val != (Object)null) { ShotgunCombat.HostApply(val, (ShotTargetKind)kind, this, extra, info.Sender); } } } [PunRPC] public void RPC_ShotDefeat(int targetViewId, PhotonMessageInfo info) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (info.Sender == null) { return; } if (!info.Sender.IsMasterClient) { PhotonView val = PhotonView.Find(targetViewId); if ((Object)(object)val == (Object)null || val.Owner != info.Sender) { return; } } ShotgunHitMarker.Show(defeat: true); } [PunRPC] public void RPC_ApplyWorldDefeat(int viewId, int kind, int extra, PhotonMessageInfo info) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (info.Sender != null && info.Sender.IsMasterClient) { ShotgunCombat.ClientApplyDefeat(PhotonView.Find(viewId), (ShotTargetKind)kind, extra); } } [PunRPC] public void RPC_ShotEffect(int viewId, int kind, int extra, Vector3 push, int variant, PhotonMessageInfo info) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (info.Sender != null && info.Sender.IsMasterClient) { ShotgunCombat.ApplyEffect(PhotonView.Find(viewId), (ShotTargetKind)kind, extra, push, variant); } } [PunRPC] private void RPC_ShotgunBlastFX(Vector3 origin, Vector3 forward, float[] pellets) { //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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) SFX_Instance? obj = shotSFX; if (obj != null) { obj.Play(origin); } ShotgunVFX vfx = ((Component)this).GetComponent<ShotgunVFX>(); if ((Object)(object)vfx != (Object)null) { vfx.Play(origin, forward); Plugin.Guard("Pellet tracers and impacts", delegate { //IL_0007: Unknown result type (might be due to invalid IL or missing references) vfx.Pellets(origin, pellets); }); } 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 AmmoPileInteract : MonoBehaviour { private Item item; private void Awake() { item = ((Component)this).GetComponent<Item>(); } internal static bool IsAmmoPile(Item? candidate) { if ((Object)(object)candidate != (Object)null) { return (Object)(object)((Component)candidate).GetComponent<AmmoPileInteract>() != (Object)null; } return false; } internal static bool CanRefillFrom(Character? interactor, out Item? shotgun) { shotgun = null; if ((Object)(object)interactor?.data == (Object)null) { return false; } Item currentItem = interactor.data.currentItem; if ((Object)(object)currentItem == (Object)null || (Object)(object)((Component)currentItem).GetComponent<Action_Gun>() == (Object)null || (Object)(object)((Component)currentItem).GetComponent<Action_Ammo>() == (Object)null) { return false; } shotgun = currentItem; if (!ShotgunAmmoUI.TryGetRemaining(currentItem, null, out var remaining)) { return true; } return remaining < Plugin.ShotCount; } internal void RequestRefill(Character interactor) { if (CanRefillFrom(interactor, out Item _)) { if (!PhotonNetwork.InRoom) { HostTryRefill(interactor); } else if (!((Object)(object)((MonoBehaviourPun)item).photonView == (Object)null)) { ((MonoBehaviourPun)item).photonView.RPC("RequestRefillRPC", (RpcTarget)2, new object[1] { ((MonoBehaviourPun)interactor).photonView.ViewID }); } } } [PunRPC] public void RequestRefillRPC(int characterViewId, PhotonMessageInfo info) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient) { PhotonView val = PhotonView.Find(characterViewId); Character val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Character>() : null); if (!((Object)(object)val2 == (Object)null) && (!PhotonNetwork.InRoom || (info.Sender != null && !((Object)(object)((MonoBehaviourPun)val2).photonView == (Object)null) && info.Sender == ((MonoBehaviourPun)val2).photonView.Owner))) { HostTryRefill(val2); } } } private void HostTryRefill(Character interactor) { if (!CanRefillFrom(interactor, out Item shotgun) || (Object)(object)shotgun == (Object)null) { return; } Action_Ammo component = ((Component)shotgun).GetComponent<Action_Ammo>(); if (!((Object)(object)component == (Object)null) && component.TryRefillToCapacity()) { ManualLogSource log = Plugin.Log; PhotonView photonView = ((MonoBehaviourPun)interactor).photonView; object obj; if (photonView == null) { obj = null; } else { Player owner = photonView.Owner; obj = ((owner != null) ? owner.NickName : null); } if (obj == null) { obj = "scout"; } log.LogInfo((object)$"Ammo pile refilled {obj}'s shotgun to {Plugin.ShotCount}."); } } } internal static class AmmoPileModelSwap { private const string ObjResource = "Peak.Shotgun.models.ammo_pile.obj"; private const string AlbedoResource = "Peak.Shotgun.models.ammo_pile_albedo.png"; private const string ItemShader = "W/Peak_Standard"; internal static void Apply(GameObject pileObject, ItemDatabase database) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_006f: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) Mesh val = LoadEmbeddedMesh(); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"Custom ammo pile mesh could not be loaded; keeping the clone look."); return; } Texture2D albedo = LoadEmbeddedTexture("Peak.Shotgun.models.ammo_pile_albedo.png", "AmmoPileAlbedo"); Material val2 = FindItemMaterial(database); if ((Object)(object)val2 == (Object)null) { val2 = FindAnyMaterial(pileObject); } HideVanillaRenderers(pileObject); GameObject val3 = new GameObject("AmmoPileVisual"); val3.transform.SetParent(pileObject.transform, false); val3.transform.localPosition = Vector3.zero; val3.transform.localRotation = Quaternion.Euler(-90f, 0f, 0f); val3.transform.localScale = Vector3.one * 0.425f; MeshFilter val4 = val3.AddComponent<MeshFilter>(); val4.sharedMesh = val; MeshRenderer val5 = val3.AddComponent<MeshRenderer>(); ((Renderer)val5).sharedMaterial = BuildMaterial(val2, albedo); RefitCollider(pileObject, val3, val); Item component = pileObject.GetComponent<Item>(); if ((Object)(object)component != (Object)null) { component.mainRenderer = (Renderer)(object)val5; component.addtlRenderers = Array.Empty<Renderer>(); } ManualLogSource log = Plugin.Log; object arg = 0.425f; Material sharedMaterial = ((Renderer)val5).sharedMaterial; object arg2; if (sharedMaterial == null) { arg2 = null; } else { Shader shader = sharedMaterial.shader; arg2 = ((shader != null) ? ((Object)shader).name : null); } log.LogInfo((object)$"Applied ammo pile mesh (scale={arg:0.###}, shader={arg2})."); } private static Material? FindItemMaterial(ItemDatabase database) { foreach (Item @object in ((DatabaseAsset<ItemDatabase, Item>)(object)database).Objects) { if ((Object)(object)@object == (Object)null) { continue; } Renderer[] componentsInChildren = ((Component)@object).GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { Material[] sharedMaterials = val.sharedMaterials; foreach (Material val2 in sharedMaterials) { if ((Object)(object)val2 != (Object)null && (Object)(object)val2.shader != (Object)null && ((Object)val2.shader).name == "W/Peak_Standard") { return val2; } } } } return null; } private static Material? FindAnyMaterial(GameObject root) { Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { Material sharedMaterial = val.sharedMaterial; if ((Object)(object)((sharedMaterial != null) ? sharedMaterial.shader : null) != (Object)null) { return val.sharedMaterial; } } return null; } private static Material BuildMaterial(Material? peakMaterial, Texture2D? albedo) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_012f: Unknown result type (might be due to invalid IL or missing references) Material val; if ((Object)(object)peakMaterial != (Object)null) { val = new Material(peakMaterial.shader); val.CopyPropertiesFromMaterial(peakMaterial); ClearTextures(val); } else { val = new Material(Shader.Find("Hidden/InternalErrorShader")); } ((Object)val).name = "AmmoPileCustom"; if ((Object)(object)albedo != (Object)null) { string[] array = new string[10] { "_MainTex", "_BaseMap", "_BaseColorMap", "_UnlitColorMap", "_Albedo", "_Diffuse", "_Texture", "_MainTexture", "_BaseColorTexture", "_BaseTexture" }; string[] array2 = array; foreach (string text in array2) { if (val.HasProperty(text)) { val.SetTexture(text, (Texture)(object)albedo); } } try { val.mainTexture = (Texture)(object)albedo; } catch { } if (val.HasProperty("_BaseTexAmount")) { val.SetFloat("_BaseTexAmount", 1f); } string[] array3 = new string[3] { "_Color", "_BaseColor", "_UnlitColor" }; foreach (string text2 in array3) { if (val.HasProperty(text2)) { val.SetColor(text2, Color.white); } } } if (val.HasProperty("_Cull")) { val.SetFloat("_Cull", 0f); } return val; } private static void ClearTextures(Material material) { List<string> list = new List<string>(); material.GetTexturePropertyNames(list); foreach (string item in list) { if (material.HasProperty(item)) { material.SetTexture(item, (Texture)null); } } } private static void HideVanillaRenderers(GameObject root) { Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (!(val is ParticleSystemRenderer)) { Object.DestroyImmediate((Object)(object)val); } } MeshFilter[] componentsInChildren2 = root.GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val2 in componentsInChildren2) { Object.DestroyImmediate((Object)(object)val2); } } private static void RefitCollider(GameObject root, GameObject visual, Mesh mesh) { //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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) Item component = root.GetComponent<Item>(); bool flag = (Object)(object)component != (Object)null && Item.ALL_ITEMS.Contains(component); Collider[] componentsInChildren = root.GetComponentsInChildren<Collider>(true); foreach (Collider val in componentsInChildren) { if (flag && Item.COLLIDER_TO_ITEM.TryGetValue(val, out var value) && (Object)(object)value == (Object)(object)component) { Item.COLLIDER_TO_ITEM.Remove(val); } Object.DestroyImmediate((Object)(object)val); } BoxCollider val2 = visual.AddComponent<BoxCollider>(); ((Collider)val2).isTrigger = false; Bounds bounds = mesh.bounds; val2.center = ((Bounds)(ref bounds)).center; bounds = mesh.bounds; val2.size = ((Bounds)(ref bounds)).size; if ((Object)(object)component == (Object)null) { return; } component.colliders = root.GetComponentsInChildren<Collider>(true); if (flag) { Collider[] colliders = component.colliders; foreach (Collider key in colliders) { Item.COLLIDER_TO_ITEM[key] = component; } } } private static Mesh? LoadEmbeddedMesh() { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Peak.Shotgun.models.ammo_pile.obj"); if (stream == null) { Plugin.Log.LogWarning((object)"Embedded mesh resource 'Peak.Shotgun.models.ammo_pile.obj' was not found."); return null; } return ObjMeshLoader.Load(stream, "AmmoPileMesh"); } private static Texture2D? LoadEmbeddedTexture(string resourceName, string textureName) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName); if (stream == null) { Plugin.Log.LogWarning((object)("Embedded texture '" + resourceName + "' was not found.")); return null; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, memoryStream.ToArray())) { Plugin.Log.LogWarning((object)("Embedded texture '" + resourceName + "' could not be decoded.")); return null; } ((Object)val).name = textureName; ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).anisoLevel = 4; return val; } } [HarmonyPatch(typeof(Item), "IsInteractible")] internal static class AmmoPileIsInteractiblePatch { [HarmonyPrefix] private static bool Prefix(Item __instance, Character interactor, ref bool __result) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 if (!AmmoPileInteract.IsAmmoPile(__instance)) { return true; } if (__instance.blockInteraction || (int)__instance.itemState == 1 || (int)__instance.itemState == 2) { __result = false; return false; } __result = AmmoPileInteract.CanRefillFrom(interactor, out Item _); return false; } } [HarmonyPatch(typeof(Item), "GetInteractionText")] internal static class AmmoPileInteractionTextPatch { [HarmonyPrefix] private static bool Prefix(Item __instance, ref string __result) { if (!AmmoPileInteract.IsAmmoPile(__instance)) { return true; } __result = ShotgunText.Refill; return false; } } [HarmonyPatch(typeof(Item), "Interact")] internal static class AmmoPileInteractPatch { [HarmonyPrefix] private static bool Prefix(Item __instance, Character interactor) { AmmoPileInteract component = ((Component)__instance).GetComponent<AmmoPileInteract>(); if ((Object)(object)component == (Object)null) { return true; } component.RequestRefill(interactor); return false; } } internal static class CampfireAmmoSpawner { private static readonly HashSet<int> SpawnedKeys = new HashSet<int>(); internal static void ClearRunState() { SpawnedKeys.Clear(); } internal static void TrySpawnAtRoot(GameObject? campfireRoot) { if (!((Object)(object)campfireRoot == (Object)null)) { Campfire componentInChildren = campfireRoot.GetComponentInChildren<Campfire>(true); if ((Object)(object)componentInChildren == (Object)null) { Plugin.Log.LogWarning((object)"Campfire ammo: SpawnCampfireItems root had no Campfire component."); } else { TrySpawnAround(componentInChildren); } } } internal static IEnumerator WhenMapIsReady() { if (!Plugin.SpawnAmmoPilesAtCampfire) { yield break; } WaitForSecondsRealtime wait = new WaitForSecondsRealtime(0.5f); for (int i = 0; i < 60; i++) { yield return wait; if (!Plugin.SpawnAmmoPilesAtCampfire) { break; } if (!((Object)(object)Plugin.AmmoPilePrefab == (Object)null) && PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient && !LoadingScreenHandler.loading && MapHandler.ExistsAndInitialized) { Campfire val = null; try { val = MapHandler.CurrentCampfire; } catch (Exception) { } if (!((Object)(object)val == (Object)null)) { TrySpawnAround(val); break; } } } } internal static void TrySpawnAround(Campfire campfire) { if (Plugin.SpawnAmmoPilesAtCampfire && !((Object)(object)campfire == (Object)null) && (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient) && !IsPortableOrWings(campfire)) { int num = CampfireKey(campfire); if (SpawnedKeys.Add(num)) { _ = ((Behaviour)campfire).isActiveAndEnabled; ((MonoBehaviour)campfire).StartCoroutine(SpawnWhenReady(campfire, num)); } } } private static IEnumerator SpawnWhenReady(Campfire campfire, int key) { WaitForSecondsRealtime wait = new WaitForSecondsRealtime(0.25f); for (int i = 0; i < 40; i++) { if (!Plugin.SpawnAmmoPilesAtCampfire || (Object)(object)campfire == (Object)null) { SpawnedKeys.Remove(key); yield break; } if ((Object)(object)Plugin.AmmoPilePrefab == (Object)null || (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient)) { yield return wait; continue; } if (PhotonNetwork.InRoom && (PhotonNetwork.CurrentRoom == null || LoadingScreenHandler.loading)) { yield return wait; continue; } if (!((Behaviour)campfire).isActiveAndEnabled) { yield return wait; continue; } SpawnPiles(campfire, Plugin.AmmoPilesPerCampfire); yield break; } SpawnedKeys.Remove(key); Plugin.Log.LogWarning((object)$"Timed out waiting to spawn campfire ammo piles ({campfire?.advanceToSegment})."); } private static void SpawnPiles(Campfire campfire, int count) { //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_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_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_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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) GameObject ammoPilePrefab = Plugin.AmmoPilePrefab; if ((Object)(object)ammoPilePrefab == (Object)null || count < 1) { return; } Vector3 position = ((Component)campfire).transform.position; int num = 0; for (int i = 0; i < count; i++) { float num2 = 360f / (float)Mathf.Max(count, 1) * (float)i + 35f; Vector3 val = Quaternion.Euler(0f, num2, 0f) * (Vector3.forward * 2.4f); Vector3 val2 = GroundPoint(position + val); Quaternion val3 = Quaternion.Euler(0f, num2 + 180f, 0f); try { if (PhotonNetwork.InRoom) { PhotonNetwork.InstantiateItemRoom(((Object)ammoPilePrefab).name, val2, val3, false); } else { Object.Instantiate<GameObject>(ammoPilePrefab, val2, val3).SetActive(true); } num++; Plugin.Log.LogInfo((object)$"Ammo pile spawn point {val2} (campfire {position}, segment {campfire.advanceToSegment})."); } catch (Exception ex) { Plugin.Log.LogError((object)("Could not spawn an ammo pile at a campfire: " + ex.Message)); } } if (num > 0) { Plugin.Log.LogInfo((object)$"Spawned {num} ammo pile(s) at campfire ({campfire.advanceToSegment})."); } } 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) 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; } if (Physics.Raycast(val, Vector3.down, ref val2, 80f, -5, (QueryTriggerInteraction)1)) { return ((RaycastHit)(ref val2)).point + Vector3.up * 0.08f; } return point; } private static int CampfireKey(Campfire campfire) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected I4, but got Unknown PhotonView component = ((Component)campfire).GetComponent<PhotonView>(); if (!((Object)(object)component != (Object)null) || component.ViewID <= 0) { return (campfire.advanceToSegment * 1000003) ^ ((Object)campfire).GetInstanceID(); } return component.ViewID; } private static bool IsPortableOrWings(Campfire campfire) { if (campfire.nameOverride == "NAME_PORTABLE STOVE") { return true; } Transform parent = ((Component)campfire).transform.parent; if ((Object)(object)parent != (Object)null) { return ((Object)((Component)parent).gameObject).name.ToLowerInvariant().Contains("wings"); } return false; } } [HarmonyPatch(typeof(MapHandler), "SpawnCampfireItems")] internal static class SpawnCampfireItemsAmmoPatch { [HarmonyPostfix] private static void Postfix(GameObject campfireRoot) { CampfireAmmoSpawner.TrySpawnAtRoot(campfireRoot); } } internal static class GameCompat { internal const string ZombieTypeName = "MushroomZombie"; internal const string SyncMobStateRpc = "RPC_SyncMobState"; private const BindingFlags AnyInstance = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; internal static void PatchAll(Harmony harmony) { int num = 0; List<string> list = new List<string>(); List<string> list2 = new List<string>(); Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(typeof(Plugin).Assembly); foreach (Type type in typesFromAssembly) { if (!type.IsDefined(typeof(HarmonyPatch), inherit: true)) { continue; } try { List<MethodInfo> list3 = harmony.CreateClassProcessor(type).Patch(); if (list3 != null && list3.Count > 0) { num++; } else { list.Add(type.Name); } } catch (Exception e) { list2.Add(type.Name); Plugin.Log.LogWarning((object)("Patch " + type.Name + " was not applied, so that feature is off: " + Unwrap(e).Message)); } } string text = $"Harmony patches: {num} applied"; if (list.Count > 0) { text += string.Format(", {0} skipped ({1})", list.Count, string.Join(", ", list)); } if (list2.Count > 0) { text += string.Format(", {0} failed ({1}). A PEAK update may have changed the game", list2.Count, string.Join(", ", list2)); Plugin.Log.LogWarning((object)(text + ".")); } else { Plugin.Log.LogInfo((object)(text + ".")); } } internal static void CheckNamedMembers() { List<string> list = new List<string>(); Type type = FindType("MushroomZombie"); if (type == null) { list.Add("MushroomZombie (zombie knockdown)"); } else if (type.GetMethod("RPC_PlaySFX", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) == null) { list.Add("MushroomZombie.RPC_PlaySFX (knocked-down zombie silence)"); } Type typeFromHandle = typeof(Mob); if (!(typeFromHandle.GetProperty("mobState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) == null)) { Type nestedType = typeFromHandle.GetNestedType("MobState", BindingFlags.Public | BindingFlags.NonPublic); if ((object)nestedType != null && Enum.IsDefined(nestedType, "Dead")) { goto IL_0090; } } list.Add("Mob.mobState / MobState.Dead (killing beetles and scorpions offline or as owner)"); goto IL_0090; IL_0090: if (typeFromHandle.GetMethod("RPC_SyncMobState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) == null) { list.Add("Mob.RPC_SyncMobState (killing beetles and scorpions owned by others)"); } if (AccessTools.Method(typeof(CharacterItems), "GetItemHoldRotation", (Type[])null, (Type[])null) == null) { list.Add("CharacterItems.GetItemHoldRotation (shotgun draw can settle centred with crossed arms)"); } if (AccessTools.Field(typeof(ItemCooking), "disableCooking") == null) { list.Add("ItemCooking.disableCooking (ammo piles could be cooked)"); } if (list.Count > 0) { Plugin.Log.LogWarning((object)("These PEAK names were not found; a game update may have changed them: " + string.Join("; ", list) + ".")); } } internal static bool IsGameMismatch(Exception e) { Exception ex = Unwrap(e); if (ex is MissingMemberException || ex is TypeLoadException || ex is BadImageFormatException) { return true; } return false; } internal static Type? FindType(string name) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { Type type = assembly.GetType(name); if (type != null) { return type; } } return null; } private static Exception Unwrap(Exception e) { while (true) { bool flag = ((e is TargetInvocationException || e is TypeInitializationException || e is HarmonyException) ? true : false); if (!flag || e.InnerException == null) { break; } e = e.InnerException; } return e; } } public class GunCharacterLaunch : MonoBehaviourPunCallbacks { private static readonly Type? ZombieType = GameCompat.FindType("MushroomZombie"); private const float BlastRagdollSeconds = 3f; private const float ShoveAcceleration = 36f; private const float ShoveSeconds = 0.3f; private const float ZombieDrowsyDamage = 0.5f; 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, int gunViewId, int shotId, PhotonMessageInfo info) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) Character component = ((Component)this).GetComponent<Character>(); if ((Object)(object)component == (Object)null || !((MonoBehaviourPun)component).photonView.IsMine || !IsZombie(component) || !ShootableRules.Zombies.Enabled) { return; } PhotonView val = PhotonView.Find(gunViewId); Action_Gun gun = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Action_Gun>() : null); if (!((Object)(object)gun == (Object)null)) { int viewID = ((MonoBehaviourPun)component).photonView.ViewID; Player shooter = info.Sender; if (gun.TryConsumeOrDeferHit(shooter, shotId, viewID, delegate { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) Blast(direction, point, gun, shooter); })) { Blast(direction, point, gun, shooter); } } } public void Blast(Vector3 direction, Vector3 point, Action_Gun? gun = null, Player? shooter = 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_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_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: 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)) { return; } shotgunHits++; if (shotgunHits >= ShootableRules.Zombies.HitsToDefeat) { if (!heldDown) { ShotgunHitMarker.ConfirmDefeat(gun, shooter, ((MonoBehaviourPun)component).photonView.ViewID); } KnockDown(component); } else { BroadcastShotState(); component.refs.afflictions.AddAffliction((Affliction)new Affliction_AdjustStatus((STATUSTYPE)6, 0.5f, 1f), false); } } private void FixedUpdate() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) if (!(shoveTime <= 0f)) { Character component = ((Component)this).GetComponent<Character>(); if ((Object)(object)component == (Object)null || !((MonoBehaviourPun)component).photonView.IsMine) { shoveTime = 0f; return; } float fixedDeltaTime = Time.fixedDeltaTime; float num = Mathf.Min(shoveTime, fixedDeltaTime) / fixedDeltaTime; shoveTime -= fixedDeltaTime; component.AddForce(shoveDirection * (36f * num), 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; BroadcastShotState(); } else { HoldDown(component); } } } private void KnockDown(Character character) { heldDown = true; character.PassOutInstantly(); HoldDown(character); Silence(); BroadcastShotState(); } private void BroadcastShotState() { if (PhotonNetwork.InRoom && (Object)(object)((MonoBehaviourPun)this).photonView != (Object)null) { ((MonoBehaviourPun)this).photonView.RPC("RPC_ZombieShotState", (RpcTarget)1, new object[2] { shotgunHits, heldDown }); } } [PunRPC] public void RPC_ZombieShotState(int hits, bool down, PhotonMessageInfo info) { //IL_0000: 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) if (info.Sender != null && info.Sender == ((MonoBehaviourPun)this).photonView.Owner) { shotgunHits = hits; heldDown = down; if (down) { Silence(); } } } public override void OnPlayerEnteredRoom(Player newPlayer) { if ((Object)(object)((MonoBehaviourPun)this).photonView != (Object)null && ((MonoBehaviourPun)this).photonView.IsMine && (shotgunHits > 0 || heldDown)) { ((MonoBehaviourPun)this).photonView.RPC("RPC_ZombieShotState", newPlayer, new object[2] { shotgunHits, heldDown }); } } private void Silence() { 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; } } } [HarmonyPatch(typeof(Character), "Awake")] internal static class GunPatch { [HarmonyPostfix] private static void AddLaunch(Character __instance) { ((Component)__instance).gameObject.AddComponent<GunCharacterLaunch>(); } } internal sealed class HostConfigSync : MonoBehaviour, IInRoomCallbacks, IMatchmakingCallbacks { internal const string RoomShotsKey = "PeakShotgun_Shots"; internal const string RoomShootablesKey = "PeakShotgun_Shootables"; internal const string RoomHitsToDefeatKey = "PeakShotgun_HitsToDefeat"; internal const string RoomWorldDownKey = "PeakShotgun_WorldDown"; private static int? hostShots; private static ShootTargets? hostShootables; private static HitsToDefeatSettings? hostHitsToDefeat; internal static int ShotCount { get { if (hostShots.HasValue) { return Mathf.Max(1, hostShots.Value); } return Plugin.LocalConfiguredShots; } } internal static ShootTargets Shootables => hostShootables ?? ShootableRules.LocalShootables; internal static HitsToDefeatSettings HitsToDefeat => hostHitsToDefeat ?? HitsToDefeatSettings.Local; 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; hostShootables = null; hostHitsToDefeat = null; ShotgunCombat.ClearWorldHitCounts(); Plugin.ApplyShotCountConfig(); Plugin.Log.LogInfo((object)$"Shots (offline/local) = {ShotCount} ({reason})."); } else if (PhotonNetwork.IsMasterClient) { PublishHostSettings(reason); } else if (!TryApplyRoomSettings()) { Plugin.Log.LogInfo((object)("Waiting for host shotgun room settings (" + reason + ").")); } } private static void PublishHostSettings(string reason) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_0088: Expected O, but got Unknown int localConfiguredShots = Plugin.LocalConfiguredShots; ShootTargets localShootables = ShootableRules.LocalShootables; HitsToDefeatSettings local = HitsToDefeatSettings.Local; hostShots = localConfiguredShots; hostShootables = localShootables; hostHitsToDefeat = local; Room currentRoom = PhotonNetwork.CurrentRoom; Hashtable val = new Hashtable(); ((Dictionary<object, object>)val).Add((object)"PeakShotgun_Shots", (object)localConfiguredShots); ((Dictionary<object, object>)val).Add((object)"PeakShotgun_Shootables", (object)(int)localShootables); ((Dictionary<object, object>)val).Add((object)"PeakShotgun_HitsToDefeat", (object)local.ToPacked()); ((Dictionary<object, object>)val).Add((object)"PeakShotgun_WorldDown", (object)ShotgunCombat.PackWorldDefeats()); currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); Plugin.ApplyShotCountConfig(); Plugin.Log.LogInfo((object)$"Host published Shots = {localConfiguredShots}, Shootables = {localShootables}, HitsToDefeat = {local} ({reason})."); } private static bool TryApplyRoomSettings() { Room currentRoom = PhotonNetwork.CurrentRoom; if (((currentRoom != null) ? ((RoomInfo)currentRoom).CustomProperties : null) == null) { return false; } Hashtable customProperties = ((RoomInfo)currentRoom).CustomProperties; if (((Dictionary<object, object>)(object)customProperties).TryGetValue((object)"PeakShotgun_Shootables", out object value) && value is int num && hostShootables != (ShootTargets?)num) { hostShootables = (ShootTargets)num; Plugin.Log.LogInfo((object)$"Client applied host Shootables = {hostShootables}."); } if (((Dictionary<object, object>)(object)customProperties).TryGetValue((object)"PeakShotgun_HitsToDefeat", out object value2) && value2 is byte[] packed) { HitsToDefeatSettings hitsToDefeatSettings = HitsToDefeatSettings.FromPacked(packed); if (!hostHitsToDefeat.HasValue || !hostHitsToDefeat.Value.Equals(hitsToDefeatSettings)) { hostHitsToDefeat = hitsToDefeatSettings; Plugin.Log.LogInfo((object)$"Client applied host HitsToDefeat = {hitsToDefeatSettings}."); } } if (((Dictionary<object, object>)(object)customProperties).TryGetValue((object)"PeakShotgun_WorldDown", out object value3) && value3 is int[] packed2) { ShotgunCombat.ApplyPackedWorldDefeats(packed2); } if (!((Dictionary<object, object>)(object)customProperties).TryGetValue((object)"PeakShotgun_Shots", out object value4) || !(value4 is int num2)) { return false; } int num3 = Mathf.Max(1, num2); if (hostShots == num3) { return true; } hostShots = num3; Plugin.ApplyShotCountConfig(); Plugin.Log.LogInfo((object)$"Client applied host Shots = {num3}."); return true; } internal static void PublishWorldDefeats() { //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_0029: Expected O, but got Unknown //IL_0030: Expected O, but got Unknown if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient) { Room currentRoom = PhotonNetwork.CurrentRoom; Hashtable val = new Hashtable(); ((Dictionary<object, object>)val).Add((object)"PeakShotgun_WorldDown", (object)ShotgunCombat.PackWorldDefeats()); currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } private static void ClearHostSettings() { hostShots = null; hostShootables = null; hostHitsToDefeat = null; ShotgunCombat.ClearWorldHitCounts(); } public void OnJoinedRoom() { SyncFromLocalRole("joined room"); } public void OnLeftRoom() { ClearHostSettings(); } public void OnMasterClientSwitched(Player newMasterClient) { if (PhotonNetwork.IsMasterClient) { PublishHostSettings("became host"); ShotgunLootLedger.OnBecameHost(); } } public void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged) { if (propertiesThatChanged != null) { ShotgunLootLedger.OnRoomPropertiesUpdate(propertiesThatChanged); if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"PeakShotgun_Shots") || ((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"PeakShotgun_Shootables") || ((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"PeakShotgun_HitsToDefeat") || ((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"PeakShotgun_WorldDown")) { TryApplyRoomSettings(); } } } 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 { internal static Vector3 LuggageRestPosition => new Vector3(Plugin.RestPosX, Plugin.RestPosY, Plugin.RestPosZ); [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_0129: 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_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_019e: 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 val6 = Plugin.LuggageVisualRotation(item.transform, up); Vector3 val7 = (val.localPosition = LuggageRestPosition); val.localRotation = val6; 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; } GetOrAddRest(item).Arm(val7, val6); ShotgunLootLedger.SavePose(__instance, val7, val6); item.ForceSyncForFrames(10); Plugin.Log.LogInfo((object)$"Luggage seat yaw={Plugin.LuggageYaw:0.#}° Δ={num3:0.###} (spawn-spot, liftExtra={Plugin.LuggageLiftExtra:0.###})."); } internal static ShotgunLuggageRest GetOrAddRest(Item item) { return ((Component)item).GetComponent<ShotgunLuggageRest>() ?? ((Component)item).gameObject.AddComponent<ShotgunLuggageRest>(); } 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; } } [HarmonyPatch(typeof(Spawner), "InitializePhysics")] internal static class LuggageShotgunSyncPatch { private const float RestoreSlack = 0.5f; [HarmonyPostfix] private static void SyncLuggageRest(Spawner __instance, Item newItem) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) Luggage val = (Luggage)(object)((__instance is Luggage) ? __instance : null); if (val == null || val is RespawnChest || (Object)(object)newItem == (Object)null || !newItem.offsetLuggageSpawn || (Object)(object)((Component)newItem).GetComponent<ShotgunInstanceSetup>() == (Object)null) { return; } ShotgunLuggageRest orAddRest = LuggageShotgunOffsetPatch.GetOrAddRest(newItem); if (!orAddRest.Armed) { if (!IsInside(val, newItem)) { return; } Vector3 position; Quaternion rotation; bool flag = ShotgunLootLedger.TryGetPose(val, out position, out rotation); if (!flag) { position = LuggageShotgunOffsetPatch.LuggageRestPosition; rotation = Plugin.LuggageVisualRotation(newItem.transform, ((Component)val).transform.up); } orAddRest.Arm(position, rotation); ShotgunLootLedger.NoteRestored(val, RootsLuggagePatch.LuggageBiomeKey((Spawner)(object)val, ((Spawner)val).spawnPool)); Plugin.Log.LogInfo((object)("Restored luggage seat for a saved shotgun in '" + ((Object)val).name + "' (" + (flag ? "saved pose" : "current config") + ").")); } orAddRest.Broadcast(); } private static bool IsInside(Luggage luggage, Item item) { //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_0020: Unknown result type (might be due to invalid IL or missing references) Bounds totalBounds = HelperFunctions.GetTotalBounds((IEnumerable<Renderer>)luggage.meshRenderers); ((Bounds)(ref totalBounds)).Expand(0.5f); return ((Bounds)(ref totalBounds)).Contains(item.transform.position); } } 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.25")] public class Plugin : BaseUnityPlugin { private static ConfigEntry<int>? shots; private static ConfigEntry<bool>? recoilEnabled; private static ConfigEntry<float>? recoil; private static ConfigEntry<int>? carryWeight; internal const int DefaultCarryWeight = 4; internal const int MaxCarryWeight = 20; private static ConfigEntry<bool>? debugMode; private static ConfigEntry<bool>? canSpawnOnAnyBiome; private static ConfigEntry<bool>? giveShotgunOnSpawn; private static ConfigEntry<bool>? spawnAmmoPilesAtCampfire; private static ConfigEntry<int>? ammoPilesPerCampfire; internal const float AmmoPileScale = 0.425f; internal const int GuaranteedLuggageShotguns = 2; internal const int MaxShotgunsPerBiome = 4; internal static readonly SpawnPool AllLuggagePools = (SpawnPool)1963064320; private static ConfigEntry<bool>? hitMarkers; private static ConfigEntry<bool>? tracers; private static ConfigEntry<bool>? impactEffects; private static ConfigEntry<float>? poseRight; private static ConfigEntry<float>? poseUp; private static ConfigEntry<float>? poseForward; private static ConfigEntry<float>? poseLeftHandIn; private static ConfigEntry<float>? poseLeftHandUp; private static ConfigEntry<float>? poseRightWristDown; 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 static readonly HashSet<string> reportedGuardFailures = new HashSet<string>(); private Coroutine? shoreSpawnRoutine; private Coroutine? campfireAmmoRoutine; private bool buildingShotgun; private bool buildingAmmoPile; 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 GameObject? AmmoPilePrefab { get; private set; } internal static int LocalConfiguredShots => Mathf.Max(1, shots?.Value ?? 6); internal static int ShotCount => HostConfigSync.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 int CarryWeight => Mathf.Clamp(carryWeight?.Value ?? 4, 0, 20); internal static bool DebugMode => debugMode?.Value ?? false; internal static bool CanSpawnOnAnyBiome { get { ConfigEntry<bool>? obj = canSpawnOnAnyBiome; if (obj != null && !obj.Value) { return !ShootableRules.IsZombiesOnly; } return true; } } internal static bool GiveShotgunOnSpawn => giveShotgunOnSpawn?.Value ?? false; internal static bool SpawnAmmoPilesAtCampfire => spawnAmmoPilesAtCampfire?.Value ?? true; internal static int AmmoPilesPerCampfire => Mathf.Clamp(ammoPilesPerCampfire?.Value ?? 1, 1, 8); 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 bool HitMarkers => hitMarkers?.Value ?? true; internal static bool Tracers => tracers?.Value ?? true; internal static bool ImpactEffects => impactEffects?.Value ?? true; internal static float LeftHandIn => poseLeftHandIn?.Value ?? 0.01f; internal static float LeftHandUp => poseLeftHandUp?.Value ?? 0.04f; internal static float RightWristDown => poseRightWristDown?.Value ?? 45f; internal static Vector3 HeldDefaultPos => new Vector3(poseRight?.Value ?? 0.55f, poseUp?.Value ?? (-0.65f), poseForward?.Value ?? 1.6f); internal static float HeldToeIn => poseToeIn?.Value ?? (-6f); internal static float HeldMuzzleUp => poseMuzzleUp?.Value ?? 0f; 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.25"; 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: Unkno