Decompiled source of KickThings v1.2.3

plugins/com.github.MiiMii1205.KickThings.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using KickThings.Handler;
using KickThings.Patchers;
using Microsoft.CodeAnalysis;
using Peak.Network;
using Photon.Pun;
using Photon.Realtime;
using PhotonCustomPropsUtils;
using UnityEngine;
using UnityEngine.UI.Extensions;

[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("com.github.MiiMii1205.KickThings")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.2.3.0")]
[assembly: AssemblyInformationalVersion("1.2.3+c1ebd2413b4c355caec066517ab081b96c912d4a")]
[assembly: AssemblyProduct("com.github.MiiMii1205.KickThings")]
[assembly: AssemblyTitle("KickThings")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.3.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 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 KickThings
{
	[BepInPlugin("com.github.MiiMii1205.KickThings", "KickThings", "1.2.3")]
	public class Plugin : BaseUnityPlugin
	{
		private static readonly HashSet<string> kickableKinematicItemList = new HashSet<string>
		{
			"Dynamite", "Aloe Vera", "Strange Gem", "Coconut", "Purple Kingberry", "Yellow Kingberry", "Beehive", "Black Clusterberry", "Red Clusterberry", "Yellow Clusterberry",
			"Green Clusterberry", "Remedy Fungus", "Big Egg", "Napberry", "Scorchberry", "Red Prickleberry", "Shelf Fungus", "Red Crispberry", "Yellow Crispberry", "Cloud Fungus",
			"Chubby Shroom", "Cluster Shroom", "Bugle Shroom", "Bounce Fungus", "Button Shroom", "Weird Shroom", "Green Crispberry", "Blue Shroomberry", "Green Shroomberry", "Yellow Shroomberry",
			"Red Shroomberry", "Orange Winterberry", "Yellow Winterberry", "Purple Shroomberry", "Gold Prickleberry", "Cactus", "Green Kingberry"
		};

		private static bool _kickThingsRegistered = false;

		public const string Id = "com.github.MiiMii1205.KickThings";

		internal static ManualLogSource Log { get; private set; } = null;


		public static Plugin Instance { get; private set; } = null;


		public static PhotonScopedManager? Manager { get; private set; }

		public static string Name => "KickThings";

		public static string Version => "1.2.3";

		private void Awake()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Manager = PhotonCustomPropsUtilsPlugin.GetManager("com.github.MiiMii1205.KickThings");
			Instance = this;
			Harmony val = new Harmony("com.github.MiiMii1205.KickThings");
			Manager.RegisterPlayerProperty<bool>("_kickThingsRegistered", (PlayerEventType)2, (Action<Player, bool>)delegate(Player player, bool b)
			{
				_kickThingsRegistered = b;
			});
			Manager.RegisterOnJoinedRoom((Action<Player>)SetupRegistered);
			val.PatchAll(typeof(KickPatcher));
			Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
		}

		private void SetupRegistered(Player player)
		{
			if (PhotonNetwork.InRoom && Manager != null)
			{
				Log.LogInfo((object)$"Registering player {player} as a KickThings user.");
				Manager.SetPlayerProperty("_kickThingsRegistered", (object)true);
			}
		}

		private void MakeBerriesFall(Character character, float maxBerries, List<Transform> spawnSpots, ref HashSet<int> activatedItemSet)
		{
			//IL_0026: 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)
			int num = 0;
			Item val = default(Item);
			foreach (Transform spawnSpot in spawnSpots)
			{
				Collider[] array = (Collider[])(object)new Collider[5];
				int num2 = Physics.OverlapSphereNonAlloc(((Component)spawnSpot).transform.position, 0.1f, array);
				for (int i = 0; i < num2; i++)
				{
					if (!((float)num < maxBerries))
					{
						break;
					}
					if ((Object)(object)array[i].attachedRigidbody != (Object)null)
					{
						Rigidbody attachedRigidbody = array[i].attachedRigidbody;
						if (attachedRigidbody != null && ((Component)attachedRigidbody).gameObject.TryGetComponent<Item>(ref val) && !activatedItemSet.Contains(((Object)((Component)val).gameObject).GetInstanceID()) && attachedRigidbody.isKinematic && (int)val.itemState == 0)
						{
							Log.LogInfo((object)$"Making {val} fall...");
							val.SetKinematicNetworked(false);
							KickThingsHandler.Instance.view.RPC("RPC_UpdateItemData", (RpcTarget)0, new object[2] { val.view, character.view });
							num++;
							activatedItemSet.Add(((Object)((Component)val).gameObject).GetInstanceID());
						}
					}
				}
			}
		}

		public void FallBerries(Collider collider, BerryBush bush, Character character)
		{
			//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_0088: 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_0093: 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)
			if (!((Spawner)bush).isKinematic)
			{
				return;
			}
			Log.LogInfo((object)$"Kicking {((object)bush).GetType().Name}: {bush}");
			HashSet<int> activatedItemSet = new HashSet<int>();
			MakeBerriesFall(character, bush.possibleBerries.y, ((Spawner)bush).spawnSpots, ref activatedItemSet);
			if (!((Object)((Component)bush).gameObject).name.StartsWith("Jungle_Willow"))
			{
				return;
			}
			Log.LogInfo((object)string.Format("Checking for {0} on {1}...", "Beehive", bush));
			Bounds bounds = collider.bounds;
			Vector3 center = ((Bounds)(ref bounds)).center;
			bounds = collider.bounds;
			Collider[] array = Physics.OverlapBox(center, ((Bounds)(ref bounds)).extents);
			Beehive val2 = default(Beehive);
			Item val3 = default(Item);
			foreach (Collider val in array)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.attachedRigidbody == (Object)null) && !activatedItemSet.Contains(((Object)((Component)val.attachedRigidbody).gameObject).GetInstanceID()) && ((Component)val.attachedRigidbody).gameObject.TryGetComponent<Beehive>(ref val2) && !activatedItemSet.Contains(((Object)((Component)val2).gameObject).GetInstanceID()) && ((Component)val2).TryGetComponent<Item>(ref val3))
				{
					Log.LogInfo((object)$"Kicking {((object)val2).GetType().Name}: {val2}");
					val3.SetKinematicNetworked(false);
					KickThingsHandler.Instance.view.RPC("RPC_UpdateItemData", (RpcTarget)0, new object[2] { val3.view, character.view });
					((MonoBehaviourPun)val2.currentBees).photonView.RPC("SetBeesAngryRPC", (RpcTarget)3, new object[1] { true });
					activatedItemSet.Add(((Object)((Component)val2).gameObject).GetInstanceID());
				}
			}
		}

		public void FallBerries(Collider collider, BerryVine bv, Character character)
		{
			if (((Spawner)bv).isKinematic)
			{
				Log.LogInfo((object)$"Kicking {((object)bv).GetType().Name}: {bv}");
				HashSet<int> activatedItemSet = new HashSet<int>();
				MakeBerriesFall(character, bv.possibleBerries.y, ((Spawner)bv).spawnSpots, ref activatedItemSet);
			}
		}

		public void ManageKick(CharacterGrabbing characterGrabbing)
		{
			((MonoBehaviour)this).StartCoroutine(DoKickThings(characterGrabbing.kickDelay, characterGrabbing.kickForce, characterGrabbing.character));
		}

		public static bool IsRegistered(Player player)
		{
			Player p = default(Player);
			if (PhotonNetwork.TryGetPlayer(NetworkingUtilities.GetActorNumber(player), ref p))
			{
				return IsRegistered(p);
			}
			return false;
		}

		public static bool IsRegistered(Player p)
		{
			if (!p.IsLocal || !_kickThingsRegistered)
			{
				if (!p.IsLocal)
				{
					return ((Dictionary<object, object>)(object)p.CustomProperties).ContainsKey((object)"_kickThingsRegistered");
				}
				return false;
			}
			return true;
		}

		private IEnumerator DoKickThings(float kickDelay, float kickForce, Character character)
		{
			yield return (object)new WaitForSeconds(kickDelay);
			Vector3 lookDirection_Flat = character.data.lookDirection_Flat;
			Collider[] results = (Collider[])(object)new Collider[10];
			Bounds bounds = ((Renderer)character.refs.mainRenderer).bounds;
			float x = ((Bounds)(ref bounds)).extents.x;
			bounds = ((Renderer)character.refs.mainRenderer).bounds;
			float num = Mathf.Max(x, ((Bounds)(ref bounds)).extents.z) / 2f;
			int size = Physics.OverlapSphereNonAlloc(((Component)character.GetBodypart((BodypartType)16)).transform.position + num * lookDirection_Flat, num, results, -1, (QueryTriggerInteraction)2);
			HashSet<int> kickedThings = new HashSet<int>();
			Mob mob = default(Mob);
			Spider val2 = default(Spider);
			Item it = default(Item);
			RopeSegment val3 = default(RopeSegment);
			RopeSegment val5 = default(RopeSegment);
			BerryVine bv = default(BerryVine);
			BreakableBridge val7 = default(BreakableBridge);
			int num2;
			for (int i = 0; i < size; num2 = i + 1, i = num2)
			{
				Collider val = results[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				if ((Object)(object)val.attachedRigidbody != (Object)null)
				{
					Rigidbody rig = val.attachedRigidbody;
					if (((Component)rig).TryGetComponent<Mob>(ref mob))
					{
						if (!kickedThings.Contains(((Object)((Component)mob).gameObject).GetInstanceID()))
						{
							float mobKickForce = kickForce * mob.rig.mass / 5f;
							Vector3 point = character.Center + character.data.lookDirection * Vector3.Distance(character.Center, mob.Center());
							if (CanInteractPhysics(((MonoBehaviourPun)mob).photonView))
							{
								Log.LogInfo((object)$"Kicking mob: {mob}");
								Player switchOwnershipBackTo = null;
								bool shouldSwitchBackToOwner = false;
								if (!((MonoBehaviourPun)mob).photonView.IsMine)
								{
									shouldSwitchBackToOwner = true;
									switchOwnershipBackTo = ((MonoBehaviourPun)mob).photonView.Owner;
									((MonoBehaviourPun)mob).photonView.RequestOwnership();
									yield return (object)new WaitUntil((Func<bool>)(() => ((MonoBehaviourPun)mob).photonView.IsMine));
								}
								KickThingsHandler.Instance.RPC_Registered("RPC_KickMob", ((MonoBehaviourPun)mob).photonView, character.view, character.data.lookDirection * mobKickForce, point);
								if (shouldSwitchBackToOwner)
								{
									((MonoBehaviour)this).StartCoroutine(RetransferOwnershipDelay(((MonoBehaviourPun)mob).photonView, switchOwnershipBackTo, 5));
								}
								KickImpact(character, ((Component)mob).gameObject, point, ref kickedThings);
							}
							else if (IsRegistered(((MonoBehaviourPun)mob).photonView.Owner))
							{
								Log.LogInfo((object)$"Kicking mob trough RPC: {mob}");
								KickThingsHandler.Instance.view.RPC("RPC_KickMob", (RpcTarget)0, new object[4]
								{
									((MonoBehaviourPun)mob).photonView,
									character.view,
									character.data.lookDirection * mobKickForce,
									point
								});
								KickImpact(character, ((Component)mob).gameObject, point, ref kickedThings);
							}
							else
							{
								Log.LogWarning((object)$"Mob owner ({((MonoBehaviourPun)mob).photonView.Owner}) doesn't have {Name} installed and can't transfer ownership (ownership is {((MonoBehaviourPun)mob).photonView.OwnershipTransfer}). Not kicking {mob}.");
							}
						}
						else
						{
							Log.LogInfo((object)$"Already kicked {mob}. Skipping");
						}
					}
					else if (((Component)rig).TryGetComponent<Spider>(ref val2))
					{
						if (!kickedThings.Contains(((Object)((Component)val2).gameObject).GetInstanceID()))
						{
							Log.LogInfo((object)$"Kicking spider: {val2}");
							val2.Bonk();
							KickImpact(character, ((Component)val2).gameObject, val.ClosestPoint(character.Center + character.data.lookDirection), ref kickedThings);
						}
						else
						{
							Log.LogInfo((object)$"Already kicked {val2}. Skipping");
						}
					}
					else if (((Component)rig).TryGetComponent<Item>(ref it) && (int)it.itemState == 0)
					{
						if (!kickedThings.Contains(((Object)((Component)it).gameObject).GetInstanceID()))
						{
							float mobKickForce = kickForce * it.rig.mass / 5f;
							Vector3 point = character.Center + character.data.lookDirection * Vector3.Distance(character.Center, it.Center());
							if (CanInteractPhysics(it.view))
							{
								Log.LogInfo((object)$"Kicking item: {it}");
								Player switchOwnershipBackTo = null;
								bool shouldSwitchBackToOwner = false;
								if (!((MonoBehaviourPun)it).photonView.IsMine)
								{
									shouldSwitchBackToOwner = true;
									switchOwnershipBackTo = it.view.Owner;
									((MonoBehaviourPun)it).photonView.RequestOwnership();
									yield return (object)new WaitUntil((Func<bool>)(() => it.view.IsMine));
								}
								if (rig.isKinematic && kickableKinematicItemList.Contains(it.UIData.itemName))
								{
									it.SetKinematicNetworked(false);
								}
								KickThingsHandler.Instance.RPC_Registered("RPC_KickItem", it.view, character.view, character.data.lookDirection * mobKickForce, point);
								if (shouldSwitchBackToOwner)
								{
									((MonoBehaviour)this).StartCoroutine(RetransferOwnershipDelay(it.view, switchOwnershipBackTo, 5));
								}
								KickImpact(character, ((Component)it).gameObject, point, ref kickedThings);
							}
							else if (IsRegistered(it.view.Owner))
							{
								Log.LogInfo((object)$"Kicking item trough RPC: {it}");
								KickThingsHandler.Instance.view.RPC("RPC_KickItem", (RpcTarget)0, new object[4]
								{
									((MonoBehaviourPun)it).photonView,
									((MonoBehaviourPun)character).photonView,
									character.data.lookDirection * mobKickForce,
									point
								});
								KickImpact(character, ((Component)mob).gameObject, point, ref kickedThings);
							}
							else
							{
								Log.LogWarning((object)$"Item owner ({it.view.Owner}) doesn't have {Name} installed and can't transfer ownership (ownership is {it.view.OwnershipTransfer}). Not kicking {it}.");
							}
						}
						else
						{
							Log.LogInfo((object)$"Already kicked {it}. Skipping");
						}
					}
					else
					{
						if (!((Component)rig).TryGetComponent<RopeSegment>(ref val3))
						{
							continue;
						}
						Rope rope = val3.rope;
						if (rope == null)
						{
							continue;
						}
						if (!kickedThings.Contains(((Object)((Component)rope).gameObject).GetInstanceID()))
						{
							Log.LogInfo((object)$"Kicking Rope: {rope}");
							Vector3 point3 = character.Center + character.data.lookDirection * Vector3.Distance(character.Center, val3.Center());
							Vector3 val4 = val3.Center();
							foreach (Character item in rope.charactersClimbing)
							{
								if (rope.antigrav ? (item.Center.y > val4.y) : (item.Center.y < val4.y))
								{
									Log.LogWarning((object)(((Object)((Component)item).gameObject).name + " is passed the affected segment. Skipping..."));
								}
								if (IsRegistered(item.player))
								{
									Log.LogWarning((object)$"Dropping {((Object)((Component)item).gameObject).name} off of {rope}.");
									item.view.RPC("StopRopeClimbingRpc", (RpcTarget)0, Array.Empty<object>());
									item.view.RPC("RPCA_Fall", (RpcTarget)0, new object[1] { 1f });
								}
								else
								{
									Log.LogWarning((object)$"{((Object)((Component)item).gameObject).name} doesn't have {Name} installed. Not dropping {((Object)((Component)item).gameObject).name} off {rope}.");
								}
							}
							KickImpact(character, ((Component)rope).gameObject, point3, ref kickedThings);
						}
						else
						{
							Log.LogInfo((object)$"Already kicked {rope}. Skipping");
						}
					}
					continue;
				}
				Spider componentInParent = ((Component)val).GetComponentInParent<Spider>();
				if (componentInParent != null)
				{
					if (!kickedThings.Contains(((Object)((Component)componentInParent).gameObject).GetInstanceID()))
					{
						Log.LogInfo((object)$"Kicking {((object)componentInParent).GetType().Name}: {componentInParent}");
						componentInParent.Bonk();
						KickImpact(character, ((Component)componentInParent).gameObject, val.ClosestPoint(character.Center + character.data.lookDirection), ref kickedThings);
					}
					else
					{
						Log.LogInfo((object)$"Already kicked {componentInParent}. Skipping");
					}
				}
				Luggage componentInParent2 = ((Component)val).GetComponentInParent<Luggage>();
				if (componentInParent2 != null && (Object)(object)componentInParent2 != (Object)null)
				{
					if (!kickedThings.Contains(((Object)((Component)componentInParent2).gameObject).GetInstanceID()))
					{
						Log.LogInfo((object)$"Kicking {((object)componentInParent2).GetType().Name}: {componentInParent2}");
						componentInParent2.Interact_CastFinished(character);
						KickImpact(character, ((Component)componentInParent2).gameObject, val.ClosestPoint(character.Center + character.data.lookDirection), ref kickedThings);
					}
					else
					{
						Log.LogInfo((object)$"Already kicked {componentInParent2}. Skipping");
					}
					continue;
				}
				if (((Component)val).TryGetComponent<RopeSegment>(ref val5))
				{
					Rope rope2 = val5.rope;
					if (rope2 != null)
					{
						if (!kickedThings.Contains(((Object)((Component)rope2).gameObject).GetInstanceID()))
						{
							Log.LogInfo((object)$"Kicking {((object)rope2).GetType().Name} (no rigidbody): {rope2}");
							Vector3 point4 = character.Center + character.data.lookDirection * Vector3.Distance(character.Center, val5.Center());
							Vector3 val6 = val5.Center();
							foreach (Character item2 in rope2.charactersClimbing)
							{
								if (rope2.antigrav ? (item2.Center.y > val6.y) : (item2.Center.y < val6.y))
								{
									Log.LogWarning((object)(((Object)((Component)item2).gameObject).name + " is passed the affected segment. Skipping..."));
								}
								if (IsRegistered(item2.player))
								{
									Log.LogWarning((object)$"Dropping {((Object)((Component)item2).gameObject).name} off of {rope2}.");
									item2.view.RPC("StopRopeClimbingRpc", (RpcTarget)0, Array.Empty<object>());
									item2.view.RPC("RPCA_Fall", (RpcTarget)0, new object[1] { 1f });
								}
								else
								{
									Log.LogWarning((object)$"{((Object)((Component)item2).gameObject).name} is not registered. Not dropping them off of {rope2}.");
								}
							}
							KickImpact(character, ((Component)rope2).gameObject, point4, ref kickedThings);
						}
						else
						{
							Log.LogInfo((object)$"Already kicked {rope2}. Skipping");
						}
						continue;
					}
				}
				JungleVine componentInParent3 = ((Component)val).GetComponentInParent<JungleVine>();
				if (componentInParent3 != null && (Object)(object)componentInParent3 != (Object)null)
				{
					if (componentInParent3.displayName.Length > 0)
					{
						if (!kickedThings.Contains(((Object)((Component)componentInParent3).gameObject).GetInstanceID()))
						{
							Log.LogInfo((object)$"Kicking {((object)componentInParent3).GetType().Name}: {componentInParent3}");
							foreach (Character allCharacter in Character.AllCharacters)
							{
								if ((Object)(object)allCharacter.data.heldVine == (Object)(object)componentInParent3 && allCharacter.data.isVineClimbing)
								{
									if (IsRegistered(allCharacter.player))
									{
										Log.LogWarning((object)$"Dropping {((Object)((Component)allCharacter).gameObject).name} off of {componentInParent3}.");
										allCharacter.refs.vineClimbing.view.RPC("StopVineClimbingRpc", (RpcTarget)0, Array.Empty<object>());
										allCharacter.view.RPC("RPCA_Fall", (RpcTarget)0, new object[1] { 1f });
									}
									else
									{
										Log.LogWarning((object)(((Object)((Component)allCharacter).gameObject).name + " is not registered. Skipping..."));
									}
								}
							}
							if (((Component)componentInParent3).TryGetComponent<BerryVine>(ref bv))
							{
								FallBerries(val, bv, character);
							}
							KickImpact(character, ((Component)componentInParent3).gameObject, val.ClosestPoint(character.Center + character.data.lookDirection), ref kickedThings);
						}
						else
						{
							Log.LogInfo((object)$"Already kicked {componentInParent3}. Skipping");
						}
					}
					else
					{
						if (!((Component)componentInParent3).gameObject.TryGetComponent<BreakableBridge>(ref val7))
						{
							continue;
						}
						if (!kickedThings.Contains(((Object)((Component)val7).gameObject).GetInstanceID()))
						{
							Log.LogInfo((object)$"Kicking {((object)val7).GetType().Name}: {val7}");
							if (val7.peopleOnBridgeDict.Keys.All((Character c) => IsRegistered(c.player)))
							{
								Log.LogInfo((object)$"Every people on the bridge are registered. Breaking {val7}. Remember it's your fault {Character.localCharacter.characterName}");
								val7.photonView.RPC("ShakeBridge_Rpc", (RpcTarget)0, Array.Empty<object>());
							}
							else
							{
								Log.LogWarning((object)$"Some Players on the bridge were not registered. Not Breaking {val7}");
							}
							KickImpact(character, ((Component)val7).gameObject, val.ClosestPoint(character.Center + character.data.lookDirection), ref kickedThings);
						}
						else
						{
							Log.LogInfo((object)$"Already kicked {val7}. Skipping");
						}
					}
					continue;
				}
				BerryBush componentInParent4 = ((Component)val).GetComponentInParent<BerryBush>();
				if ((Object)(object)componentInParent4 != (Object)null)
				{
					if (!kickedThings.Contains(((Object)((Component)componentInParent4).gameObject).GetInstanceID()))
					{
						FallBerries(val, componentInParent4, character);
						KickImpact(character, ((Component)componentInParent4).gameObject, val.ClosestPoint(character.Center + character.data.lookDirection), ref kickedThings);
					}
					else
					{
						Log.LogInfo((object)$"Already kicked {componentInParent4}. Skipping");
					}
				}
			}
		}

		private static IEnumerator RetransferOwnershipDelay(PhotonView componentPhotonView, Player previousOwner, int f)
		{
			int frames = 0;
			while (frames < f)
			{
				frames++;
				yield return null;
			}
			if ((Object)(object)componentPhotonView != (Object)null)
			{
				componentPhotonView.TransferOwnership(previousOwner);
			}
		}

		public static IEnumerator ReanimateMob(Mob component)
		{
			yield return (object)new WaitForSeconds(6f);
			component.mobState = (MobState)2;
		}

		private static bool CanInteractPhysics(PhotonView componentView)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			if (!componentView.IsMine)
			{
				return (int)componentView.OwnershipTransfer > 0;
			}
			return true;
		}

		private static void KickImpact(Character character, GameObject thing, Vector3 point, ref HashSet<int> kickedThings)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			character.view.RPC("RPCA_KickImpact", (RpcTarget)0, new object[1] { point });
			kickedThings.Add(((Object)thing).GetInstanceID());
		}
	}
}
namespace KickThings.Patchers
{
	public static class KickPatcher
	{
		[HarmonyPatch(typeof(CharacterGrabbing), "KickCast")]
		[HarmonyPostfix]
		public static void KickPost(CharacterGrabbing __instance)
		{
			Plugin.Instance.ManageKick(__instance);
		}

		[HarmonyPatch(typeof(RunManager), "Awake")]
		[HarmonyPostfix]
		public static void KickThingsManagerPost(RunManager __instance)
		{
			ExtensionMethods.GetOrAddComponent<KickThingsHandler>(((Component)__instance).gameObject);
		}
	}
}
namespace KickThings.Handler
{
	public class KickThingsHandler : MonoBehaviourPunCallbacks
	{
		public PhotonView view;

		public static KickThingsHandler Instance { get; private set; }

		private void Awake()
		{
			Instance = this;
			view = ((Component)this).GetComponent<PhotonView>();
		}

		[PunRPC]
		public void RPC_KickMob(PhotonView mobView, PhotonView charView, Vector3 kickForce, Vector3 pos)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log.LogInfo((object)$"Received kicking #{mobView}");
			Mob component = ((Component)mobView).GetComponent<Mob>();
			if (component is Beetle)
			{
				((MonoBehaviour)this).StartCoroutine(ApplyMobForce(component, charView, kickForce, pos));
			}
		}

		[PunRPC]
		public void RPC_SyncKickedRig(PhotonView kickedView, Vector3 linVel, Vector3 rotVel)
		{
			//IL_001d: 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)
			Plugin.Log.LogInfo((object)$"Received kicked rigidbody #{kickedView}");
			Rigidbody component = ((Component)kickedView).GetComponent<Rigidbody>();
			component.angularVelocity = rotVel;
			component.linearVelocity = linVel;
		}

		private IEnumerator ApplyMobForce(Mob mob, PhotonView charView, Vector3 force, Vector3 pos)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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)
			Mob mob2 = mob;
			MobState stateToUse = (MobState)3;
			mob2.mobState = stateToUse;
			yield return (object)new WaitUntil((Func<bool>)(() => mob2.mobState == stateToUse));
			mob2.rig.AddForceAtPosition(force, pos, (ForceMode)1);
			if (charView.Owner.IsLocal)
			{
				PhysicsSyncer val = default(PhysicsSyncer);
				if ((Object)(object)mob2._mobItem != (Object)null)
				{
					((ItemPhysicsSyncer)mob2._mobItem.syncer).ForceSyncForFrames(3);
				}
				else if (((Component)mob2).TryGetComponent<PhysicsSyncer>(ref val))
				{
					val.ForceSyncForFrames(3);
				}
			}
			((MonoBehaviour)this).StartCoroutine(Plugin.ReanimateMob(mob2));
		}

		private static IEnumerator SetMobStateForSecs(Mob mob, MobState state, float duration)
		{
			//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)
			float t = 0f;
			while (t < duration)
			{
				t += Time.deltaTime;
				mob.mobState = state;
				mob.rig.constraints = (RigidbodyConstraints)0;
				yield return null;
			}
		}

		[PunRPC]
		public void RPC_KickItem(PhotonView itemView, PhotonView charView, Vector3 kickForce, Vector3 pos)
		{
			//IL_0033: 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)
			Plugin.Log.LogInfo((object)$"Received kicking #{itemView}");
			Item component = ((Component)itemView).GetComponent<Item>();
			Mob val = default(Mob);
			if (((Component)component).TryGetComponent<Mob>(ref val))
			{
				val.mobState = (MobState)0;
			}
			component.rig.AddForceAtPosition(kickForce, pos, (ForceMode)1);
			if (charView.Owner.IsLocal)
			{
				component.physicsSyncer.ForceSyncForFrames(3);
			}
			RPC_Registered("RPC_UpdateItemData", itemView, charView);
		}

		[PunRPC]
		public void RPC_UpdateItemData(PhotonView itemView, PhotonView charView)
		{
			Plugin.Log.LogInfo((object)$"Received kick data #{itemView}. Was kicked by {charView.Owner}");
			Item component = ((Component)itemView).GetComponent<Item>();
			component.lastThrownCharacter = (component.lastHolderCharacter = ((Component)charView).GetComponent<Character>());
		}

		public void RPC_Registered(string methodName, params object[] parameters)
		{
			Player[] playerList = PhotonNetwork.PlayerList;
			int i = 0;
			for (int num = playerList.Length; i < num; i++)
			{
				if (Plugin.IsRegistered(playerList[i]))
				{
					view.RPC(methodName, playerList[i], parameters);
				}
			}
		}

		public void RPC_OtherRegistered(string methodName, params object[] parameters)
		{
			Player[] playerListOthers = PhotonNetwork.PlayerListOthers;
			int i = 0;
			for (int num = playerListOthers.Length; i < num; i++)
			{
				if (Plugin.IsRegistered(playerListOthers[i]))
				{
					view.RPC(methodName, playerListOthers[i], parameters);
				}
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}