Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ShopItemClone v1.0.0
ShopItemClone.dll
Decompiled 4 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("REPOJP")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("zabuMod")] [assembly: AssemblyTitle("zabuMod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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 REPOJP.ShopItemClone { [BepInPlugin("REPOJP.ShopItemClone", "Shop Item Clone", "1.0.0")] public sealed class ShopItemClonePlugin : BaseUnityPlugin { public const string PluginGuid = "REPOJP.ShopItemClone"; public const string PluginName = "Shop Item Clone"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource LogSource; internal static ShopItemClonePlugin Instance; internal static ConfigEntry<bool> CloneUpgrades; internal static ConfigEntry<bool> CloneMeleeWeapons; internal static ConfigEntry<bool> CloneGuns; internal static ConfigEntry<bool> CloneCarts; internal static ConfigEntry<bool> CloneDrones; internal static ConfigEntry<bool> CloneOrbs; internal static ConfigEntry<bool> CloneHealthPacks; internal static ConfigEntry<bool> CloneExplosives; internal static ConfigEntry<bool> CloneEnergyCrystals; internal static ConfigEntry<bool> PreventCloneInExtractionPoint; private Harmony harmony; private void Awake() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown try { Instance = this; LogSource = ((BaseUnityPlugin)this).Logger; BindConfig(); ShopItemCloneRuntime.EnsureCreated(); harmony = new Harmony("REPOJP.ShopItemClone"); harmony.PatchAll(typeof(ShopItemClonePlugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Shop Item Clone 1.0.0 loaded"); } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogError((object)string.Format("Failed to initialize {0}\n{1}", "Shop Item Clone", arg)); } } private void BindConfig() { CloneUpgrades = ((BaseUnityPlugin)this).Config.Bind<bool>("Category Toggle", "Clone Upgrades", true, "Clone item upgrades and player upgrades when the held item touches the ground in the shop. ショップ中に手持ち状態のアップグレード系アイテムが地面接触したとき複製"); CloneMeleeWeapons = ((BaseUnityPlugin)this).Config.Bind<bool>("Category Toggle", "Clone Melee Weapons", true, "Clone melee weapons when the held item touches the ground in the shop. ショップ中に手持ち状態の近接武器が地面接触したとき複製"); CloneGuns = ((BaseUnityPlugin)this).Config.Bind<bool>("Category Toggle", "Clone Guns", true, "Clone guns when the held item touches the ground in the shop. ショップ中に手持ち状態の銃が地面接触したとき複製"); CloneCarts = ((BaseUnityPlugin)this).Config.Bind<bool>("Category Toggle", "Clone Carts", true, "Clone carts and pocket carts when the held item touches the ground in the shop. cart と pocket_cart はそれぞれ1ショップ中5回まで複製。ショップ中に手持ち状態のカート系が地面接触したとき複製"); CloneDrones = ((BaseUnityPlugin)this).Config.Bind<bool>("Category Toggle", "Clone Drones", true, "Clone drones when the held item touches the ground in the shop. ショップ中に手持ち状態のドローンが地面接触したとき複製"); CloneOrbs = ((BaseUnityPlugin)this).Config.Bind<bool>("Category Toggle", "Clone Orbs", true, "Clone orbs when the held item touches the ground in the shop. ショップ中に手持ち状態のオーブが地面接触したとき複製"); CloneHealthPacks = ((BaseUnityPlugin)this).Config.Bind<bool>("Category Toggle", "Clone Health Packs", true, "Clone health packs when the held item touches the ground in the shop. ショップ中に手持ち状態のヘルスパックが地面接触したとき複製"); CloneExplosives = ((BaseUnityPlugin)this).Config.Bind<bool>("Category Toggle", "Clone Explosives", true, "Clone grenades and mines when the held item touches the ground in the shop. ショップ中に手持ち状態の爆破物系が地面接触したとき複製"); CloneEnergyCrystals = ((BaseUnityPlugin)this).Config.Bind<bool>("Category Toggle", "Clone Energy Crystals", true, "Clone energy crystals when the held item touches the ground in the shop. ショップ中に手持ち状態のエナジークリスタルが地面接触したとき複製"); PreventCloneInExtractionPoint = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Prevent Clone In Extraction Point", true, "Prevent cloning while the held item is inside the extraction point. 納品所内にある手持ちアイテムの複製を禁止"); } } internal sealed class ShopItemCloneRuntime : MonoBehaviour { private sealed class ContactState { internal PhysGrabObject Source; internal bool Latched; internal float LastValidGroundContactTime; internal float LastCloneTime; } [CompilerGenerated] private sealed class <FinalizeCloneAfterStart>d__37 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PhysGrabObject source; public ItemAttributes sourceItem; public GameObject cloneObject; public ShopItemCloneRuntime <>4__this; private ItemAttributes <cloneItem>5__1; private PhotonView <clonePhotonView>5__2; private Rigidbody <sourceRb>5__3; private Rigidbody <cloneRb>5__4; private ItemToggle <sourceToggle>5__5; private ItemToggle <cloneToggle>5__6; private ItemBattery <sourceBattery>5__7; private ItemBattery <cloneBattery>5__8; private int <sourceValue>5__9; private int <targetBars>5__10; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FinalizeCloneAfterStart>d__37(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <cloneItem>5__1 = null; <clonePhotonView>5__2 = null; <sourceRb>5__3 = null; <cloneRb>5__4 = null; <sourceToggle>5__5 = null; <cloneToggle>5__6 = null; <sourceBattery>5__7 = null; <cloneBattery>5__8 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = null; <>1__state = 2; return true; case 2: <>1__state = -1; if ((Object)(object)source == (Object)null || (Object)(object)sourceItem == (Object)null || (Object)(object)cloneObject == (Object)null) { return false; } <cloneItem>5__1 = cloneObject.GetComponent<ItemAttributes>(); <clonePhotonView>5__2 = cloneObject.GetComponent<PhotonView>(); <sourceRb>5__3 = source.rb; <cloneRb>5__4 = cloneObject.GetComponent<Rigidbody>(); if ((Object)(object)<cloneItem>5__1 == (Object)null) { return false; } TryApplyInitialMotion(<sourceRb>5__3, <cloneRb>5__4); if (ItemValueField != null) { <sourceValue>5__9 = (int)ItemValueField.GetValue(sourceItem); if (GameManager.Multiplayer() && (Object)(object)<clonePhotonView>5__2 != (Object)null) { <clonePhotonView>5__2.RPC("GetValueRPC", (RpcTarget)0, new object[1] { <sourceValue>5__9 }); } else { <cloneItem>5__1.GetValueRPC(<sourceValue>5__9); } } <sourceToggle>5__5 = ((Component)source).GetComponent<ItemToggle>(); <cloneToggle>5__6 = cloneObject.GetComponent<ItemToggle>(); if ((Object)(object)<sourceToggle>5__5 != (Object)null && (Object)(object)<cloneToggle>5__6 != (Object)null && <cloneToggle>5__6.toggleState != <sourceToggle>5__5.toggleState) { <cloneToggle>5__6.ToggleItem(<sourceToggle>5__5.toggleState, -1); } <sourceBattery>5__7 = ((Component)source).GetComponent<ItemBattery>(); <cloneBattery>5__8 = cloneObject.GetComponent<ItemBattery>(); if ((Object)(object)<sourceBattery>5__7 != (Object)null && (Object)(object)<cloneBattery>5__8 != (Object)null) { <targetBars>5__10 = Mathf.Clamp(Mathf.RoundToInt(<sourceBattery>5__7.batteryLife / (100f / (float)<cloneBattery>5__8.batteryBars)), 0, <cloneBattery>5__8.batteryBars); if (GameManager.Multiplayer() && (Object)(object)<clonePhotonView>5__2 != (Object)null) { <clonePhotonView>5__2.RPC("BatteryFullPercentChangeRPC", (RpcTarget)0, new object[2] { <targetBars>5__10, false }); } else if (BatteryFullPercentChangeRpcMethod != null) { BatteryFullPercentChangeRpcMethod.Invoke(<cloneBattery>5__8, new object[2] { <targetBars>5__10, false }); } } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <IgnoreCloneCollisionTemporary>d__38 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public GameObject sourceObject; public GameObject cloneObject; public float duration; public ShopItemCloneRuntime <>4__this; private Collider[] <sourceColliders>5__1; private Collider[] <cloneColliders>5__2; private int <i>5__3; private Collider <sourceCollider>5__4; private int <j>5__5; private Collider <cloneCollider>5__6; private int <i>5__7; private Collider <sourceCollider>5__8; private int <j>5__9; private Collider <cloneCollider>5__10; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <IgnoreCloneCollisionTemporary>d__38(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <sourceColliders>5__1 = null; <cloneColliders>5__2 = null; <sourceCollider>5__4 = null; <cloneCollider>5__6 = null; <sourceCollider>5__8 = null; <cloneCollider>5__10 = null; <>1__state = -2; } private bool MoveNext() { //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if ((Object)(object)sourceObject == (Object)null || (Object)(object)cloneObject == (Object)null) { return false; } <sourceColliders>5__1 = sourceObject.GetComponentsInChildren<Collider>(true); <cloneColliders>5__2 = cloneObject.GetComponentsInChildren<Collider>(true); <i>5__3 = 0; while (<i>5__3 < <sourceColliders>5__1.Length) { <sourceCollider>5__4 = <sourceColliders>5__1[<i>5__3]; if (!((Object)(object)<sourceCollider>5__4 == (Object)null)) { <j>5__5 = 0; while (<j>5__5 < <cloneColliders>5__2.Length) { <cloneCollider>5__6 = <cloneColliders>5__2[<j>5__5]; if (!((Object)(object)<cloneCollider>5__6 == (Object)null)) { Physics.IgnoreCollision(<sourceCollider>5__4, <cloneCollider>5__6, true); <cloneCollider>5__6 = null; } <j>5__5++; } <sourceCollider>5__4 = null; } <i>5__3++; } <>2__current = (object)new WaitForSeconds(duration); <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)sourceObject == (Object)null || (Object)(object)cloneObject == (Object)null) { return false; } <i>5__7 = 0; while (<i>5__7 < <sourceColliders>5__1.Length) { <sourceCollider>5__8 = <sourceColliders>5__1[<i>5__7]; if (!((Object)(object)<sourceCollider>5__8 == (Object)null)) { <j>5__9 = 0; while (<j>5__9 < <cloneColliders>5__2.Length) { <cloneCollider>5__10 = <cloneColliders>5__2[<j>5__9]; if (!((Object)(object)<cloneCollider>5__10 == (Object)null)) { Physics.IgnoreCollision(<sourceCollider>5__8, <cloneCollider>5__10, false); <cloneCollider>5__10 = null; } <j>5__9++; } <sourceCollider>5__8 = null; } <i>5__7++; } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const float DefaultCloneHeightOffset = 0.01f; private const float CartCloneHeightOffset = 1f; private const float CloneCollisionIgnoreSeconds = 0.2f; private const float CloneImpactDisableSeconds = 0.2f; private const float RearmNoContactSeconds = 0.08f; private const float RearmAfterSpawnSeconds = 0.15f; private const float GroundNormalMinY = 0.35f; private const int CartCloneMaxPerShop = 5; private const int PocketCartCloneMaxPerShop = 5; private static ShopItemCloneRuntime instance; private static readonly FieldInfo ItemValueField = AccessTools.Field(typeof(ItemAttributes), "value"); private static readonly FieldInfo InExtractionPointField = AccessTools.Field(typeof(RoomVolumeCheck), "inExtractionPoint"); private static readonly MethodInfo BatteryFullPercentChangeRpcMethod = AccessTools.Method(typeof(ItemBattery), "BatteryFullPercentChangeRPC", (Type[])null, (Type[])null); private readonly Dictionary<int, ContactState> contactStates = new Dictionary<int, ContactState>(); private int currentShopCartCloneCount; private int currentShopPocketCartCloneCount; private bool wasShopMainPhase; internal static ShopItemCloneRuntime Instance => instance; internal static void EnsureCreated() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)instance != (Object)null)) { GameObject val = new GameObject("ShopItemCloneRuntime"); val.transform.parent = null; ((Object)val).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)val); instance = val.AddComponent<ShopItemCloneRuntime>(); } } private void Update() { try { bool flag = IsShopMainPhase(); if (flag && !wasShopMainPhase) { ResetShopCounters(); } else if (!flag && wasShopMainPhase) { ResetShopCounters(); contactStates.Clear(); } wasShopMainPhase = flag; if (contactStates.Count == 0) { return; } float unscaledTime = Time.unscaledTime; List<int> list = null; foreach (KeyValuePair<int, ContactState> contactState in contactStates) { ContactState value = contactState.Value; PhysGrabObject source = value.Source; if ((Object)(object)source == (Object)null) { if (list == null) { list = new List<int>(); } list.Add(contactState.Key); continue; } bool flag2 = IsActuallyHeld(source); bool flag3 = IsShopMainPhase(); if (!flag2 || !flag3) { if (list == null) { list = new List<int>(); } list.Add(contactState.Key); } else if (!(unscaledTime - value.LastCloneTime < 0.15f) && unscaledTime - value.LastValidGroundContactTime > 0.08f) { value.Latched = false; } } if (list == null) { return; } foreach (int item in list) { contactStates.Remove(item); } } catch (Exception arg) { ShopItemClonePlugin.LogSource.LogError((object)$"Runtime update failed\n{arg}"); } } internal void OnImpactStay(PhysGrabObjectImpactDetector detector, Collision collision) { try { if ((Object)(object)detector == (Object)null || collision == null || !IsHostAuthority() || !IsShopMainPhase()) { return; } PhysGrabObject component = ((Component)detector).GetComponent<PhysGrabObject>(); if ((Object)(object)component == (Object)null) { return; } ItemAttributes component2 = ((Component)component).GetComponent<ItemAttributes>(); if (!((Object)(object)component2 == (Object)null) && !((Object)(object)((Component)component).GetComponent<ValuableObject>() != (Object)null) && IsCategoryEnabled(component2) && IsActuallyHeld(component) && (ShopItemClonePlugin.PreventCloneInExtractionPoint == null || !ShopItemClonePlugin.PreventCloneInExtractionPoint.Value || !IsInsideExtractionPoint(component)) && IsGroundLikeEnvironmentCollision(collision)) { int instanceID = ((Object)component).GetInstanceID(); if (!contactStates.TryGetValue(instanceID, out ContactState value)) { value = new ContactState(); value.Source = component; contactStates[instanceID] = value; } value.LastValidGroundContactTime = Time.unscaledTime; if (!value.Latched) { value.Latched = true; value.LastCloneTime = Time.unscaledTime; CloneHeldShopItem(component, component2); } } } catch (Exception arg) { ShopItemClonePlugin.LogSource.LogError((object)$"Impact handling failed\n{arg}"); } } private static bool IsHostAuthority() { if (!GameManager.Multiplayer()) { return true; } return PhotonNetwork.IsMasterClient; } private static bool IsShopMainPhase() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 if (!SemiFunc.RunIsShop()) { return false; } if ((Object)(object)GameDirector.instance == (Object)null) { return false; } return (int)GameDirector.instance.currentState == 2; } private static bool IsCategoryEnabled(ItemAttributes itemAttributes) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected I4, but got Unknown if ((Object)(object)itemAttributes == (Object)null || (Object)(object)itemAttributes.item == (Object)null) { return false; } itemType itemType = itemAttributes.item.itemType; itemType val = itemType; switch ((int)val) { case 3: case 4: return ShopItemClonePlugin.CloneUpgrades != null && ShopItemClonePlugin.CloneUpgrades.Value; case 7: return ShopItemClonePlugin.CloneMeleeWeapons != null && ShopItemClonePlugin.CloneMeleeWeapons.Value; case 9: return ShopItemClonePlugin.CloneGuns != null && ShopItemClonePlugin.CloneGuns.Value; case 2: case 12: return ShopItemClonePlugin.CloneCarts != null && ShopItemClonePlugin.CloneCarts.Value; case 0: return ShopItemClonePlugin.CloneDrones != null && ShopItemClonePlugin.CloneDrones.Value; case 1: return ShopItemClonePlugin.CloneOrbs != null && ShopItemClonePlugin.CloneOrbs.Value; case 8: return ShopItemClonePlugin.CloneHealthPacks != null && ShopItemClonePlugin.CloneHealthPacks.Value; case 6: case 11: return ShopItemClonePlugin.CloneExplosives != null && ShopItemClonePlugin.CloneExplosives.Value; case 5: return ShopItemClonePlugin.CloneEnergyCrystals != null && ShopItemClonePlugin.CloneEnergyCrystals.Value; default: return false; } } private static bool IsActuallyHeld(PhysGrabObject source) { if ((Object)(object)source == (Object)null) { return false; } if (!source.grabbed) { return false; } List<PhysGrabber> playerGrabbing = source.playerGrabbing; if (playerGrabbing == null || playerGrabbing.Count == 0) { return false; } for (int i = 0; i < playerGrabbing.Count; i++) { PhysGrabber val = playerGrabbing[i]; if (!((Object)(object)val == (Object)null) && val.grabbed && !((Object)(object)val.grabbedPhysGrabObject != (Object)(object)source)) { return true; } } return false; } private static bool IsInsideExtractionPoint(PhysGrabObject source) { if ((Object)(object)source == (Object)null) { return false; } RoomVolumeCheck val = ((Component)source).GetComponent<RoomVolumeCheck>(); if ((Object)(object)val == (Object)null) { val = ((Component)source).GetComponentInChildren<RoomVolumeCheck>(); } if ((Object)(object)val == (Object)null) { val = ((Component)source).GetComponentInParent<RoomVolumeCheck>(); } if ((Object)(object)val == (Object)null) { return false; } val.CheckSet(); object value = InExtractionPointField.GetValue(val); bool flag = default(bool); int num; if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } private static void TryApplyInitialMotion(Rigidbody sourceRb, Rigidbody cloneRb) { //IL_002a: 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) if (!((Object)(object)sourceRb == (Object)null) && !((Object)(object)cloneRb == (Object)null) && !cloneRb.isKinematic) { cloneRb.velocity = sourceRb.velocity; cloneRb.angularVelocity = sourceRb.angularVelocity; } } private static bool IsGroundLikeEnvironmentCollision(Collision collision) { //IL_00f5: 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) if (collision == null) { return false; } Transform transform = collision.transform; if ((Object)(object)transform == (Object)null) { return false; } MaterialSurface val = ((Component)transform).GetComponent<MaterialSurface>(); if ((Object)(object)val == (Object)null) { val = ((Component)transform).GetComponentInParent<MaterialSurface>(); } if ((Object)(object)val == (Object)null) { return false; } if ((Object)(object)((Component)transform).GetComponentInParent<PhysGrabObject>() != (Object)null) { return false; } if (((Component)transform).CompareTag("Player") || (Object)(object)((Component)transform).GetComponentInParent<PlayerAvatar>() != (Object)null) { return false; } if ((Object)(object)((Component)transform).GetComponentInParent<EnemyRigidbody>() != (Object)null) { return false; } if ((Object)(object)((Component)transform).GetComponentInParent<PhysGrabCart>() != (Object)null) { return false; } float num = -1f; ContactPoint[] contacts = collision.contacts; for (int i = 0; i < contacts.Length; i++) { if (((ContactPoint)(ref contacts[i])).normal.y > num) { num = ((ContactPoint)(ref contacts[i])).normal.y; } } return num >= 0.35f; } private static bool IsCartItem(ItemAttributes itemAttributes) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Invalid comparison between Unknown and I4 if ((Object)(object)itemAttributes == (Object)null || (Object)(object)itemAttributes.item == (Object)null) { return false; } return (int)itemAttributes.item.itemType == 2 || (int)itemAttributes.item.itemType == 12; } private static bool IsStandardCartItem(ItemAttributes itemAttributes) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 if ((Object)(object)itemAttributes == (Object)null || (Object)(object)itemAttributes.item == (Object)null) { return false; } return (int)itemAttributes.item.itemType == 2; } private static bool IsPocketCartItem(ItemAttributes itemAttributes) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Invalid comparison between Unknown and I4 if ((Object)(object)itemAttributes == (Object)null || (Object)(object)itemAttributes.item == (Object)null) { return false; } return (int)itemAttributes.item.itemType == 12; } private Vector3 GetCloneSpawnPosition(PhysGrabObject source, ItemAttributes sourceItem) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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) float num = 0.01f; if (IsCartItem(sourceItem)) { num = 1f; } return ((Component)source).transform.position + Vector3.up * num; } private bool CanCloneCartThisShop(ItemAttributes sourceItem) { if (IsStandardCartItem(sourceItem)) { return currentShopCartCloneCount < 5; } if (IsPocketCartItem(sourceItem)) { return currentShopPocketCartCloneCount < 5; } return true; } private void RegisterCartClone(ItemAttributes sourceItem) { if (IsStandardCartItem(sourceItem)) { currentShopCartCloneCount++; } else if (IsPocketCartItem(sourceItem)) { currentShopPocketCartCloneCount++; } } private void ResetShopCounters() { currentShopCartCloneCount = 0; currentShopPocketCartCloneCount = 0; } private void CloneHeldShopItem(PhysGrabObject source, ItemAttributes sourceItem) { //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_00b3: 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_00e4: 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_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null || (Object)(object)sourceItem == (Object)null || (Object)(object)sourceItem.item == (Object)null || !CanCloneCartThisShop(sourceItem)) { return; } string text = null; if (sourceItem.item.prefab != null) { text = sourceItem.item.prefab.ResourcePath; } if (string.IsNullOrEmpty(text)) { ShopItemClonePlugin.LogSource.LogWarning((object)("Skipped clone because resource path was missing: " + ((Object)source).name)); return; } Vector3 cloneSpawnPosition = GetCloneSpawnPosition(source, sourceItem); Quaternion rotation = ((Component)source).transform.rotation; GameObject val = ((!GameManager.Multiplayer()) ? Object.Instantiate<GameObject>(sourceItem.item.prefab.Prefab, cloneSpawnPosition, rotation) : PhotonNetwork.InstantiateRoomObject(text, cloneSpawnPosition, rotation, (byte)0, (object[])null)); if (!((Object)(object)val == (Object)null)) { RegisterCartClone(sourceItem); Rigidbody rb = source.rb; Rigidbody component = val.GetComponent<Rigidbody>(); TryApplyInitialMotion(rb, component); PhysGrabObjectImpactDetector component2 = val.GetComponent<PhysGrabObjectImpactDetector>(); if ((Object)(object)component2 != (Object)null) { component2.ImpactDisable(0.2f); } ((MonoBehaviour)this).StartCoroutine(FinalizeCloneAfterStart(source, sourceItem, val)); ((MonoBehaviour)this).StartCoroutine(IgnoreCloneCollisionTemporary(((Component)source).gameObject, val, 0.2f)); } } [IteratorStateMachine(typeof(<FinalizeCloneAfterStart>d__37))] private IEnumerator FinalizeCloneAfterStart(PhysGrabObject source, ItemAttributes sourceItem, GameObject cloneObject) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FinalizeCloneAfterStart>d__37(0) { <>4__this = this, source = source, sourceItem = sourceItem, cloneObject = cloneObject }; } [IteratorStateMachine(typeof(<IgnoreCloneCollisionTemporary>d__38))] private IEnumerator IgnoreCloneCollisionTemporary(GameObject sourceObject, GameObject cloneObject, float duration) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <IgnoreCloneCollisionTemporary>d__38(0) { <>4__this = this, sourceObject = sourceObject, cloneObject = cloneObject, duration = duration }; } } [HarmonyPatch(typeof(PhysGrabObjectImpactDetector), "OnCollisionStay")] internal static class PhysGrabObjectImpactDetectorPatch { private static void Postfix(PhysGrabObjectImpactDetector __instance, Collision collision) { ShopItemCloneRuntime instance = ShopItemCloneRuntime.Instance; if (!((Object)(object)instance == (Object)null)) { instance.OnImpactStay(__instance, collision); } } } }