Decompiled source of XuMiscTools v1.1.0

XuMiscTools.dll

Decompiled a month 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.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using Microsoft.CodeAnalysis;
using On;
using Unity.Netcode;
using UnityEngine;
using XuMiscTools.Patches;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("XuXiaolan")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("The coolest mod ever made")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+55a20245c05e8204d992c070d08a367a16740562")]
[assembly: AssemblyProduct("XuMiscTools")]
[assembly: AssemblyTitle("com.github.xuxiaolan.xumisctools")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/XuuXiao/xumisctools")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.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;
		}
	}
}
[BepInPlugin("com.github.xuxiaolan.xumisctools", "XuMiscTools", "1.1.0")]
public class Plugin : BaseUnityPlugin
{
	public static ManualLogSource Log;

	private void Awake()
	{
		Log = ((BaseUnityPlugin)this).Logger;
		ShovelPatch.Init();
		Log.LogInfo((object)"Plugin XuMiscTools is loaded!");
	}
}
internal static class LCMPluginInfo
{
	public const string PLUGIN_GUID = "com.github.xuxiaolan.xumisctools";

	public const string PLUGIN_NAME = "XuMiscTools";

	public const string PLUGIN_VERSION = "1.1.0";
}
namespace XuMiscTools
{
	public class BetterCooldownTrigger : MonoBehaviour
	{
		public enum DeathAnimation
		{
			Default,
			HeadBurst,
			Spring,
			Electrocuted,
			ComedyMask,
			TragedyMask,
			Burnt,
			Snipped,
			SliceHead
		}

		public enum ForceDirection
		{
			Forward,
			Backward,
			Up,
			Down,
			Left,
			Right,
			Center
		}

		[Tooltip("Different ragdoll body types that spawn after death.")]
		public DeathAnimation deathAnimation;

		[Tooltip("The force direction of the damage.")]
		public ForceDirection forceDirection;

		[Tooltip("Cause of death displayed in ScanNode after death.")]
		public CauseOfDeath causeOfDeath;

		[Tooltip("The force magnitude of the damage.")]
		public float forceMagnitudeAfterDamage;

		[Tooltip("The force magnitude after death of player.")]
		public float forceMagnitudeAfterDeath;

		[Tooltip("Whether to trigger for enemies.")]
		public bool triggerForEnemies;

		[Tooltip("Whether to use shared cooldown between different GameObjects that use this script.")]
		public bool sharedCooldown;

		[Tooltip("Whether to play default player damage SFX when damage is dealt.")]
		public bool playDefaultPlayerDamageSFX;

		[Tooltip("If true, the force direction will be calculated from the object's transform. If false, the force direction will be calculated from the player's transform.")]
		public bool forceDirectionFromThisObject = true;

		[Tooltip("Whether to play sound when damage is dealt to player that enemies can hear.")]
		public bool soundAttractsDogs;

		[Tooltip("Timer in which the gameobject will disable itself, 0 will not disable itself after any point of time.")]
		public float damageDuration;

		[Tooltip("Damage to deal every interval for players.")]
		public int damageToDealForPlayers;

		[Tooltip("Damage to deal every interval for enemies.")]
		public int damageToDealForEnemies;

		[Tooltip("Cooldown to deal damage for players.")]
		public float damageIntervalForPlayers = 0.25f;

		[Tooltip("Cooldown to deal damage for enemies.")]
		public float damageIntervalForEnemies = 0.25f;

		[Tooltip("Damage clip to play when damage is dealt to player/enemy.")]
		public List<AudioClip>? damageClip;

		[Tooltip("Damage audio sources to play when damage is dealt to player (picks the closest AudioSource to the player).")]
		public List<AudioSource>? damageAudioSources;

		private static float lastDamageTime = float.NegativeInfinity;

		private Dictionary<PlayerControllerB, bool> playerCoroutineStatus = new Dictionary<PlayerControllerB, bool>();

		private Dictionary<EnemyAI, bool> enemyCoroutineStatus = new Dictionary<EnemyAI, bool>();

		private Dictionary<PlayerControllerB, AudioSource> playerClosestAudioSources = new Dictionary<PlayerControllerB, AudioSource>();

		private Dictionary<EnemyAI, AudioSource> enemyClosestAudioSources = new Dictionary<EnemyAI, AudioSource>();

		private void OnEnable()
		{
			((MonoBehaviour)this).StartCoroutine(ManageDamageTimer());
		}

		private IEnumerator ManageDamageTimer()
		{
			if (!(damageDuration <= 0f))
			{
				yield return (object)new WaitForSeconds(damageDuration);
				((Component)this).gameObject.SetActive(false);
			}
		}

		private void OnTriggerEnter(Collider other)
		{
			PlayerControllerB val = default(PlayerControllerB);
			if (((Component)other).CompareTag("Player") && Object.op_Implicit((Object)(object)GameNetworkManager.Instance.localPlayerController) == ((Component)other).TryGetComponent<PlayerControllerB>(ref val))
			{
				if (!playerCoroutineStatus.ContainsKey(val))
				{
					playerCoroutineStatus[val] = true;
					if (damageAudioSources != null && damageAudioSources.Count > 0)
					{
						playerClosestAudioSources[val] = GetClosestAudioSource(((Component)val).transform);
					}
					((MonoBehaviour)this).StartCoroutine(DamagePlayerCoroutine(val));
				}
			}
			else
			{
				if (!triggerForEnemies)
				{
					return;
				}
				Transform val2 = TryFindRoot(((Component)other).transform);
				EnemyAI val3 = default(EnemyAI);
				if ((Object)(object)val2 != (Object)null && ((Component)val2).TryGetComponent<EnemyAI>(ref val3) && !val3.isEnemyDead && !enemyCoroutineStatus.ContainsKey(val3))
				{
					enemyCoroutineStatus[val3] = true;
					if (damageAudioSources != null && damageAudioSources.Count > 0)
					{
						enemyClosestAudioSources[val3] = GetClosestAudioSource(((Component)val3).transform);
					}
					((MonoBehaviour)this).StartCoroutine(DamageEnemyCoroutine(val3));
				}
			}
		}

		private void OnTriggerExit(Collider other)
		{
			PlayerControllerB key = default(PlayerControllerB);
			if (((Component)other).CompareTag("Player") && Object.op_Implicit((Object)(object)GameNetworkManager.Instance.localPlayerController) == ((Component)other).TryGetComponent<PlayerControllerB>(ref key))
			{
				playerCoroutineStatus[key] = false;
				playerClosestAudioSources.Remove(key);
			}
			else if (triggerForEnemies)
			{
				Transform val = TryFindRoot(((Component)other).transform);
				EnemyAI key2 = default(EnemyAI);
				if ((Object)(object)val != (Object)null && ((Component)val).TryGetComponent<EnemyAI>(ref key2))
				{
					enemyCoroutineStatus[key2] = false;
					enemyClosestAudioSources.Remove(key2);
				}
			}
		}

		private IEnumerator DamagePlayerCoroutine(PlayerControllerB player)
		{
			while (playerCoroutineStatus[player])
			{
				if (sharedCooldown && Time.time < lastDamageTime + damageIntervalForPlayers)
				{
					yield return null;
					continue;
				}
				lastDamageTime = Time.time;
				ApplyDamageToPlayer(player);
				yield return (object)new WaitForSeconds(damageIntervalForPlayers);
			}
		}

		private IEnumerator DamageEnemyCoroutine(EnemyAI enemy)
		{
			while (enemyCoroutineStatus[enemy])
			{
				if (sharedCooldown && Time.time < lastDamageTime + damageIntervalForEnemies)
				{
					yield return null;
					continue;
				}
				lastDamageTime = Time.time;
				ApplyDamageToEnemy(enemy);
				yield return (object)new WaitForSeconds(damageIntervalForEnemies);
			}
		}

		private void ApplyDamageToPlayer(PlayerControllerB player)
		{
			//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_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_002b: 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_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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = CalculateForceDirection(player, forceMagnitudeAfterDamage);
			Vector3 val2 = CalculateForceDirection(player, forceMagnitudeAfterDeath);
			player.DamagePlayer(damageToDealForPlayers, playDefaultPlayerDamageSFX, true, causeOfDeath, (int)deathAnimation, false, val2);
			PlayDamageSound(((Component)player).transform, playerClosestAudioSources.ContainsKey(player) ? playerClosestAudioSources[player] : null);
			if (!player.isPlayerDead)
			{
				player.externalForces += val;
			}
		}

		private void ApplyDamageToEnemy(EnemyAI enemy)
		{
			enemy.HitEnemy(damageToDealForEnemies, (PlayerControllerB)null, false, -1);
			PlayDamageSound(((Component)enemy).transform, enemyClosestAudioSources.ContainsKey(enemy) ? enemyClosestAudioSources[enemy] : null);
		}

		private Vector3 CalculateForceDirection(PlayerControllerB player, float baseForce)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: 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_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.zero;
			switch (forceDirection)
			{
			case ForceDirection.Forward:
				val = (forceDirectionFromThisObject ? ((Component)this).transform.forward : ((Component)player).transform.forward);
				break;
			case ForceDirection.Backward:
				val = (forceDirectionFromThisObject ? (-((Component)this).transform.forward) : (-((Component)player).transform.forward));
				break;
			case ForceDirection.Up:
				val = Vector3.up;
				break;
			case ForceDirection.Down:
				val = Vector3.down;
				break;
			case ForceDirection.Left:
				val = (forceDirectionFromThisObject ? (-((Component)this).transform.right) : (-((Component)player).transform.right));
				break;
			case ForceDirection.Right:
				val = (forceDirectionFromThisObject ? ((Component)this).transform.right : ((Component)player).transform.right);
				break;
			case ForceDirection.Center:
			{
				Vector3 val2;
				Vector3 normalized;
				if (!forceDirectionFromThisObject)
				{
					val2 = ((Component)this).transform.position - ((Component)player).transform.position;
					normalized = ((Vector3)(ref val2)).normalized;
				}
				else
				{
					val2 = ((Component)player).transform.position - ((Component)this).transform.position;
					normalized = ((Vector3)(ref val2)).normalized;
				}
				val = normalized;
				break;
			}
			}
			return ((Vector3)(ref val)).normalized * baseForce;
		}

		private void PlayDamageSound(Transform targetTransform, AudioSource? audioSource)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (damageClip != null && (Object)(object)audioSource != (Object)null)
			{
				if (soundAttractsDogs)
				{
					RoundManager.Instance.PlayAudibleNoise(((Component)audioSource).transform.position, audioSource.maxDistance, audioSource.volume, 0, false, 0);
				}
				WalkieTalkie.TransmitOneShotAudio(audioSource, damageClip[Random.Range(0, damageClip.Count)], audioSource.volume);
				RoundManager.PlayRandomClip(audioSource, damageClip.ToArray(), true, audioSource.volume, 0, damageClip.Count);
			}
		}

		private AudioSource GetClosestAudioSource(Transform targetTransform)
		{
			//IL_0013: 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_0040: 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)
			AudioSource val = damageAudioSources[0];
			float num = Vector3.Distance(((Component)val).transform.position, targetTransform.position);
			foreach (AudioSource damageAudioSource in damageAudioSources)
			{
				float num2 = Vector3.Distance(((Component)damageAudioSource).transform.position, targetTransform.position);
				if (num2 < num)
				{
					val = damageAudioSource;
					num = num2;
				}
			}
			return val;
		}

		public void OnDisable()
		{
			((MonoBehaviour)this).StopAllCoroutines();
			playerCoroutineStatus.Clear();
			enemyCoroutineStatus.Clear();
			playerClosestAudioSources.Clear();
			enemyClosestAudioSources.Clear();
		}

		public static Transform? TryFindRoot(Transform child)
		{
			Transform val = child;
			while ((Object)(object)val != (Object)null)
			{
				if ((Object)(object)((Component)val).GetComponent<NetworkObject>() != (Object)null)
				{
					return val;
				}
				val = ((Component)val).transform.parent;
			}
			return null;
		}
	}
	public class BetterShovel : Shovel
	{
		private bool _animatorSpeedCurrentlyModified;

		private float _originalPlayerAnimatorSpeed;

		private PlayerControllerB previouslyHeldBy;

		[NonSerialized]
		public int defaultForce;

		[Tooltip("Setup the shovel type automatically, you STILL need to make a proper itemProperties and set it up how you see fit, this just makes sure the values are correct.")]
		public bool SetupShovelTypeAutomatically;

		[Tooltip("The speed of the shovel hitting.")]
		public float ShovelSpeedMultiplier = 1f;

		[Tooltip("If true, the player will be able to crit with this weapon, dealing 2x damage.")]
		public bool CritPossible;

		[Tooltip("The chance that the player will crit with this weapon.")]
		public float CritChance;

		[Tooltip("If true, the player will be able to break trees using this weapon, uses vehicle mechanics.")]
		public bool CanBreakTrees;

		[Tooltip("The position of the tip of the shovel.")]
		public Transform WeaponTip;

		public override void Start()
		{
			((GrabbableObject)this).Start();
			if (SetupShovelTypeAutomatically)
			{
				((GrabbableObject)this).itemProperties.twoHandedAnimation = true;
				((GrabbableObject)this).itemProperties.weight = Mathf.Clamp(((GrabbableObject)this).itemProperties.weight, 1f, 9f);
				((GrabbableObject)this).itemProperties.grabAnim = "HoldLung";
				((GrabbableObject)this).itemProperties.isDefensiveWeapon = true;
				((GrabbableObject)this).itemProperties.holdButtonUse = true;
			}
		}

		public override void EquipItem()
		{
			((GrabbableObject)this).EquipItem();
			AnimationClip val = ((IEnumerable<AnimationClip>)((GrabbableObject)this).playerHeldBy.playerBodyAnimator.runtimeAnimatorController.animationClips).FirstOrDefault((Func<AnimationClip, bool>)((AnimationClip clip) => ((Object)clip).name == "ShovelReelUp"));
			AnimationClip val2 = ((IEnumerable<AnimationClip>)((GrabbableObject)this).playerHeldBy.playerBodyAnimator.runtimeAnimatorController.animationClips).FirstOrDefault((Func<AnimationClip, bool>)((AnimationClip clip) => ((Object)clip).name == "HitShovel"));
			if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null && !_animatorSpeedCurrentlyModified)
			{
				_originalPlayerAnimatorSpeed = ((GrabbableObject)this).playerHeldBy.playerBodyAnimator.speed;
				float length = val.length;
				float speed = length * ShovelSpeedMultiplier;
				_animatorSpeedCurrentlyModified = true;
				((GrabbableObject)this).playerHeldBy.playerBodyAnimator.speed = speed;
			}
			previouslyHeldBy = ((GrabbableObject)this).playerHeldBy;
		}

		public override void DiscardItem()
		{
			((Shovel)this).DiscardItem();
			AnimationClip val = ((IEnumerable<AnimationClip>)previouslyHeldBy.playerBodyAnimator.runtimeAnimatorController.animationClips).FirstOrDefault((Func<AnimationClip, bool>)((AnimationClip clip) => ((Object)clip).name == "ShovelReelUp"));
			AnimationClip val2 = ((IEnumerable<AnimationClip>)previouslyHeldBy.playerBodyAnimator.runtimeAnimatorController.animationClips).FirstOrDefault((Func<AnimationClip, bool>)((AnimationClip clip) => ((Object)clip).name == "HitShovel"));
			if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null && _animatorSpeedCurrentlyModified)
			{
				previouslyHeldBy.playerBodyAnimator.speed = _originalPlayerAnimatorSpeed;
				_animatorSpeedCurrentlyModified = false;
			}
		}

		public override void PocketItem()
		{
			((GrabbableObject)this).PocketItem();
			AnimationClip val = ((IEnumerable<AnimationClip>)previouslyHeldBy.playerBodyAnimator.runtimeAnimatorController.animationClips).FirstOrDefault((Func<AnimationClip, bool>)((AnimationClip clip) => ((Object)clip).name == "ShovelReelUp"));
			AnimationClip val2 = ((IEnumerable<AnimationClip>)previouslyHeldBy.playerBodyAnimator.runtimeAnimatorController.animationClips).FirstOrDefault((Func<AnimationClip, bool>)((AnimationClip clip) => ((Object)clip).name == "HitShovel"));
			if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null && _animatorSpeedCurrentlyModified)
			{
				previouslyHeldBy.playerBodyAnimator.speed = _originalPlayerAnimatorSpeed;
				_animatorSpeedCurrentlyModified = false;
			}
		}
	}
	public static class ShovelExtensions
	{
		public static int CriticalHit(int force, Random random, float critChance)
		{
			if ((float)random.NextDouble() * 100f < Math.Clamp(critChance, 0f, 100f))
			{
				return force * 2;
			}
			return force;
		}
	}
}
namespace XuMiscTools.Patches
{
	internal static class ShovelPatch
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_HitShovel <0>__Shovel_HitShovel;
		}

		public static Random? random;

		public static void Init()
		{
			//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_001b: Expected O, but got Unknown
			object obj = <>O.<0>__Shovel_HitShovel;
			if (obj == null)
			{
				hook_HitShovel val = Shovel_HitShovel;
				<>O.<0>__Shovel_HitShovel = val;
				obj = (object)val;
			}
			Shovel.HitShovel += (hook_HitShovel)obj;
		}

		private static void Shovel_HitShovel(orig_HitShovel orig, Shovel self, bool cancel)
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			if (random == null)
			{
				if ((Object)(object)StartOfRound.Instance != (Object)null)
				{
					random = new Random(StartOfRound.Instance.randomMapSeed + 85);
				}
				else
				{
					random = new Random(69);
				}
			}
			if (self is BetterShovel betterShovel)
			{
				betterShovel.defaultForce = ((Shovel)betterShovel).shovelHitForce;
				if (betterShovel.CritPossible)
				{
					((Shovel)betterShovel).shovelHitForce = ShovelExtensions.CriticalHit(((Shovel)betterShovel).shovelHitForce, random, betterShovel.CritChance);
				}
			}
			orig.Invoke(self, cancel);
			if (self is BetterShovel betterShovel2)
			{
				((Shovel)betterShovel2).shovelHitForce = betterShovel2.defaultForce;
				if (betterShovel2.CanBreakTrees)
				{
					RoundManager.Instance.DestroyTreeOnLocalClient(betterShovel2.WeaponTip.position);
				}
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}