Decompiled source of ShockwaveGrenade v0.1.0

ShockwaveGrenade.dll

Decompiled 2 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.Rendering.HighDefinition;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ShockwaveGrenade")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+31b5772e5e3f23ce0215b676606995a042f4e285")]
[assembly: AssemblyProduct("ShockwaveGrenade")]
[assembly: AssemblyTitle("ShockwaveGrenade")]
[assembly: AssemblyVersion("0.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 ShockwaveGrenade
{
	internal class Blast : MonoBehaviour
	{
		private const int RoomMask = 256;

		private const int EnemyMask = 524288;

		private const float RingTime = 0.4f;

		private Vector3 _from;

		private Vector3 _to;

		private float _t;

		private float _duration;

		private float _arc;

		private BlastParams _p;

		private PlayerControllerB _thrower;

		internal static Vector3 LastBlastPosition;

		internal static float LastBlastTime = -1f;

		public static void Fly(Vector3 from, Vector3 to, BlastParams p, PlayerControllerB thrower)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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)
			GameObject val = (GameObject)(((Object)(object)Registry.ModelAsset != (Object)null) ? ((object)Object.Instantiate<GameObject>(Registry.ModelAsset)) : ((object)new GameObject()));
			((Object)val).name = "ShockwaveProjectile";
			Collider[] componentsInChildren = val.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren[i]);
			}
			Blast blast = val.AddComponent<Blast>();
			float num = Vector3.Distance(from, to);
			blast._from = from;
			blast._to = to;
			blast._p = p;
			blast._thrower = thrower;
			blast._duration = Mathf.Clamp(num / 14f, 0.2f, 1.1f);
			blast._arc = Mathf.Clamp(num * 0.12f, 0.1f, 1.5f);
			val.transform.position = from;
			PlayAt(Registry.ThrowClip, from, 0.8f, 20f);
		}

		private void Update()
		{
			//IL_002c: 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_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_0058: 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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			_t += Time.deltaTime;
			float num = Mathf.Clamp01(_t / _duration);
			((Component)this).transform.position = Vector3.Lerp(_from, _to, num) + Vector3.up * (_arc * 4f * num * (1f - num));
			((Component)this).transform.rotation = Quaternion.Euler(0f, _t * 720f, 0f);
			if (!(num < 1f))
			{
				try
				{
					Explode(_to, _p, _thrower);
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"Shockwave: blast failed: {arg}");
				}
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		internal static void Explode(Vector3 pos, BlastParams p, PlayerControllerB thrower)
		{
			//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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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_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_016a: 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_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_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			LastBlastPosition = pos;
			LastBlastTime = Time.time;
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			AudioSource val = PlayAt(Registry.BlastClip, pos, 1f, 60f);
			if ((Object)(object)val != (Object)null && (Object)(object)Registry.BlastClip != (Object)null)
			{
				WalkieTalkie.TransmitOneShotAudio(val, Registry.BlastClip, 0.9f);
			}
			SpawnRing(pos, p.Radius);
			if (p.Noise > 0f && (Object)(object)RoundManager.Instance != (Object)null)
			{
				RoundManager.Instance.PlayAudibleNoise(pos, p.Noise, 0.9f, 0, false, 0);
			}
			if (Plugin.ScreenShake.Value && (Object)(object)localPlayerController != (Object)null && (Object)(object)HUDManager.Instance != (Object)null && Vector3.Distance(((Component)localPlayerController).transform.position, pos) < 14f)
			{
				HUDManager.Instance.ShakeCamera((ScreenShakeType)0);
			}
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val2 in allPlayerScripts)
			{
				if (InRange(val2, pos, p, thrower))
				{
					PlayAt(Registry.WhooshClip, ((Component)val2).transform.position + Vector3.up, ((Object)(object)val2 == (Object)(object)localPlayerController) ? 0.6f : 0.8f, 25f);
					if ((Object)(object)val2 == (Object)(object)localPlayerController)
					{
						Launch(localPlayerController, pos, p);
					}
				}
			}
			if (p.Stun > 0f)
			{
				HashSet<EnemyAI> hashSet = new HashSet<EnemyAI>();
				Collider[] array = Physics.OverlapSphere(pos, p.Radius, 524288);
				for (int i = 0; i < array.Length; i++)
				{
					EnemyAICollisionDetect component = ((Component)array[i]).GetComponent<EnemyAICollisionDetect>();
					if (!((Object)(object)component == (Object)null) && !((Object)(object)component.mainScript == (Object)null) && hashSet.Add(component.mainScript) && !Physics.Linecast(pos + Vector3.up * 0.5f, ((Component)component.mainScript).transform.position + Vector3.up * 0.5f, 256, (QueryTriggerInteraction)1))
					{
						component.mainScript.SetEnemyStunned(true, p.Stun, thrower);
					}
				}
			}
			if (p.PushCruiser)
			{
				VehicleController val3 = Object.FindObjectOfType<VehicleController>();
				if ((Object)(object)val3 != (Object)null && ((NetworkBehaviour)val3).IsOwner && !val3.magnetedToShip && (Object)(object)val3.mainRigidbody != (Object)null && Vector3.Distance(((Component)val3).transform.position, pos) < p.Radius * 2f)
				{
					val3.mainRigidbody.AddExplosionForce(p.Up * 50f, pos, p.Radius * 2f, 3f, (ForceMode)1);
				}
			}
		}

		private static bool InRange(PlayerControllerB pl, Vector3 pos, BlastParams p, PlayerControllerB thrower)
		{
			//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_0077: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)pl == (Object)null || !pl.isPlayerControlled || pl.isPlayerDead)
			{
				return false;
			}
			if (!p.LaunchOthers && (Object)(object)pl != (Object)(object)thrower)
			{
				return false;
			}
			if (pl.inVehicleAnimation || (Object)(object)pl.inAnimationWithEnemy != (Object)null)
			{
				return false;
			}
			if (StartOfRound.Instance.inShipPhase && pl.isInHangarShipRoom)
			{
				return false;
			}
			if (Vector3.Distance(((Component)pl).transform.position, pos) > p.Radius)
			{
				return false;
			}
			return !Physics.Linecast(pos + Vector3.up * 0.3f, ((Component)pl).transform.position + Vector3.up * 1f, 256, (QueryTriggerInteraction)1);
		}

		private static void Launch(PlayerControllerB me, Vector3 pos, BlastParams p)
		{
			//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_000c: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((Component)me).transform.position - pos;
			val.y = 0f;
			if (((Vector3)(ref val)).magnitude < 1.5f)
			{
				val = (((Object)(object)me.gameplayCamera != (Object)null) ? ((Component)me.gameplayCamera).transform.forward : ((Component)me).transform.forward);
				val.y = 0f;
			}
			val = ((((Vector3)(ref val)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref val)).normalized : Vector3.zero);
			FallGuard.Launch(me, Vector3.up * p.Up + val * p.Out, p.After, p.Max);
		}

		private static AudioSource PlayAt(AudioClip clip, Vector3 pos, float volume, float maxDistance)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)clip == (Object)null)
			{
				return null;
			}
			GameObject val = new GameObject("ShockwaveSound");
			val.transform.position = pos;
			AudioSource obj = val.AddComponent<AudioSource>();
			obj.outputAudioMixerGroup = Registry.Mixer;
			obj.spatialBlend = 1f;
			obj.rolloffMode = (AudioRolloffMode)1;
			obj.minDistance = 2f;
			obj.maxDistance = maxDistance;
			obj.dopplerLevel = 0f;
			obj.PlayOneShot(clip, volume);
			Object.Destroy((Object)(object)val, clip.length + 0.5f);
			return obj;
		}

		private static void SpawnRing(Vector3 pos, float radius)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_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_0074: 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_0084: 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_009c: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("ShockwaveRingFx");
			val.transform.position = pos + Vector3.up * 0.15f;
			if ((Object)(object)Registry.RingAsset != (Object)null)
			{
				Object.Instantiate<GameObject>(Registry.RingAsset, val.transform, false).transform.localPosition = Vector3.zero;
			}
			GameObject val2 = new GameObject("Flash");
			val2.transform.SetParent(val.transform, false);
			val2.transform.localPosition = Vector3.up * 0.5f;
			Light obj = val2.AddComponent<Light>();
			obj.type = (LightType)2;
			obj.color = Registry.CoreColor;
			obj.shadows = (LightShadows)0;
			HDAdditionalLightData val3 = val2.AddComponent<HDAdditionalLightData>();
			val3.SetColor(Registry.CoreColor, -1f);
			val3.EnableShadows(false);
			val3.SetRange(radius * 1.5f);
			val.AddComponent<RingFx>().Init(radius, 0.4f, val3);
		}
	}
	internal class RingFx : MonoBehaviour
	{
		private float _radius;

		private float _time;

		private float _t;

		private HDAdditionalLightData _light;

		private Renderer[] _renderers;

		private MaterialPropertyBlock _mpb;

		public void Init(float radius, float time, HDAdditionalLightData light)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			_radius = radius;
			_time = time;
			_light = light;
			_renderers = ((Component)this).GetComponentsInChildren<Renderer>();
			_mpb = new MaterialPropertyBlock();
			Apply(0f);
		}

		private void Update()
		{
			_t += Time.deltaTime;
			float u = Mathf.Clamp01(_t / _time);
			Apply(u);
			if (_t > _time + 0.1f)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		private void Apply(float u)
		{
			//IL_0053: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			float num = 1f - (1f - u) * (1f - u);
			((Component)this).transform.localScale = new Vector3(Mathf.Max(0.05f, _radius * num), 1f + 2f * (1f - u), Mathf.Max(0.05f, _radius * num));
			float num2 = 1f - u;
			Renderer[] renderers = _renderers;
			foreach (Renderer obj in renderers)
			{
				obj.GetPropertyBlock(_mpb);
				_mpb.SetColor("_UnlitColor", new Color(0.35f, 0.45f, 1f, 1f) * (num2 * 3f));
				obj.SetPropertyBlock(_mpb);
			}
			if ((Object)(object)_light != (Object)null)
			{
				_light.SetIntensity(3000f * num2 * num2, (LightUnit)0);
			}
		}
	}
	[HarmonyPatch]
	internal static class FallGuard
	{
		private static float _launchTime = -100f;

		private static float _openUntil = -100f;

		private static float _afterLanding = 1f;

		private static bool _landed = true;

		internal static int Blocked;

		internal static bool IsOpen => Time.time < _openUntil;

		internal static void Reset()
		{
			_openUntil = -100f;
			_landed = true;
		}

		internal static void Launch(PlayerControllerB me, Vector3 impulse, float afterLanding, float maxSeconds)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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)
			if (me.isClimbingLadder || me.inSpecialInteractAnimation)
			{
				me.CancelSpecialTriggerAnimations();
			}
			me.ResetFallGravity();
			me.externalForceAutoFade += impulse;
			_launchTime = Time.time;
			_openUntil = Time.time + Mathf.Max(0.5f, maxSeconds);
			_afterLanding = Mathf.Max(0f, afterLanding);
			_landed = false;
			Plugin.Log.LogInfo((object)$"Shockwave: launched with {impulse} (no fall damage for up to {maxSeconds:F0} s).");
		}

		private static bool IsLocal(PlayerControllerB p)
		{
			if ((Object)(object)p != (Object)null && (Object)(object)GameNetworkManager.Instance != (Object)null)
			{
				return (Object)(object)p == (Object)(object)GameNetworkManager.Instance.localPlayerController;
			}
			return false;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Update")]
		[HarmonyPostfix]
		private static void AfterUpdate(PlayerControllerB __instance)
		{
			if (!_landed && IsLocal(__instance) && !(Time.time - _launchTime < 0.25f) && !((Object)(object)__instance.thisController == (Object)null) && __instance.thisController.isGrounded)
			{
				_landed = true;
				_openUntil = Mathf.Min(_openUntil, Time.time + _afterLanding);
				Plugin.Log.LogInfo((object)$"Shockwave: landed after {Time.time - _launchTime:F2} s.");
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "PlayerHitGroundEffects")]
		[HarmonyPrefix]
		private static void BeforeHitGround(PlayerControllerB __instance)
		{
			if (IsOpen && IsLocal(__instance) && __instance.takingFallDamage)
			{
				__instance.takingFallDamage = false;
				Blocked++;
				Plugin.Log.LogInfo((object)$"Shockwave: fall damage blocked (fall speed {__instance.fallValueUncapped:F1}).");
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "DamagePlayer")]
		[HarmonyPrefix]
		private static bool BeforeDamage(PlayerControllerB __instance, int damageNumber, CauseOfDeath causeOfDeath, bool fallDamage)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			if (!IsOpen || !IsLocal(__instance))
			{
				return true;
			}
			if ((int)causeOfDeath != 2 && !fallDamage)
			{
				return true;
			}
			Blocked++;
			Plugin.Log.LogInfo((object)$"Shockwave: {damageNumber} fall damage blocked.");
			return false;
		}
	}
	public class ShockwaveGrenadeItem : GrabbableObject
	{
		private const int ThrowMask = 268437761;

		private const float Cooldown = 0.75f;

		internal int Used;

		private float _lastThrow = -10f;

		private bool _gone;

		private Renderer[] _renderers;

		private MaterialPropertyBlock _mpb;

		internal int ChargesLeft => Mathf.Max(0, Net.Charges - Used);

		public override void Start()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			((GrabbableObject)this).Start();
			_renderers = ((Component)this).GetComponentsInChildren<Renderer>(true);
			_mpb = new MaterialPropertyBlock();
		}

		public override int GetItemDataToSave()
		{
			return Used;
		}

		public override void LoadItemSaveData(int saveData)
		{
			Used = Mathf.Max(0, saveData);
		}

		public override void EquipItem()
		{
			((GrabbableObject)this).EquipItem();
			((GrabbableObject)this).SetControlTipsForItem();
		}

		public override void SetControlTipsForItem()
		{
			if (((NetworkBehaviour)this).IsOwner && !((Object)(object)base.playerHeldBy == (Object)null) && !((Object)(object)base.playerHeldBy != (Object)(object)GameNetworkManager.Instance.localPlayerController))
			{
				HUDManager.Instance.ChangeControlTipMultiple(new string[1] { $"Throw shockwave ({ChargesLeft} left) : [LMB]" }, true, base.itemProperties);
			}
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			//IL_0076: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			((GrabbableObject)this).ItemActivate(used, buttonDown);
			if (buttonDown && !_gone && !((Object)(object)base.playerHeldBy == (Object)null))
			{
				PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
				if (!((Object)(object)base.playerHeldBy != (Object)(object)localPlayerController) && !(Time.time - _lastThrow < 0.75f) && ChargesLeft > 0)
				{
					_lastThrow = Time.time;
					Transform transform = ((Component)base.playerHeldBy.gameplayCamera).transform;
					Vector3 val = transform.position + transform.forward * 0.6f - transform.up * 0.25f + transform.right * 0.2f;
					Vector3 val2 = ThrowDestination(transform);
					Plugin.Log.LogInfo((object)$"Shockwave: throw from {val} to {val2} ({ChargesLeft} left before this one).");
					Net.RequestThrow(this, val, val2);
				}
			}
		}

		internal static Vector3 ThrowDestination(Transform cam)
		{
			//IL_0003: 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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			Ray val = default(Ray);
			((Ray)(ref val))..ctor(cam.position, cam.forward);
			RaycastHit val3 = default(RaycastHit);
			Vector3 val2 = (Physics.Raycast(val, ref val3, 12f, 268437761, (QueryTriggerInteraction)1) ? ((Ray)(ref val)).GetPoint(((RaycastHit)(ref val3)).distance - 0.05f) : ((Ray)(ref val)).GetPoint(10f));
			Ray val4 = default(Ray);
			((Ray)(ref val4))..ctor(val2, Vector3.down);
			if (!Physics.Raycast(val4, ref val3, 30f, 268437761, (QueryTriggerInteraction)1))
			{
				return ((Ray)(ref val4)).GetPoint(30f);
			}
			return ((RaycastHit)(ref val3)).point + Vector3.up * 0.05f;
		}

		internal void OnThrown(int chargesLeft)
		{
			Used = Mathf.Max(0, Net.Charges - chargesLeft);
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			bool flag = (Object)(object)base.playerHeldBy != (Object)null && (Object)(object)base.playerHeldBy == (Object)(object)localPlayerController && base.isHeld;
			if (flag && chargesLeft > 0)
			{
				((GrabbableObject)this).SetControlTipsForItem();
			}
			if (chargesLeft > 0 || _gone)
			{
				return;
			}
			_gone = true;
			if (flag)
			{
				base.playerHeldBy.DespawnHeldObject();
				HUDManager instance = HUDManager.Instance;
				if (instance != null)
				{
					instance.ClearControlTips();
				}
			}
			else if (Net.IsHost && !base.isHeld && (Object)(object)((NetworkBehaviour)this).NetworkObject != (Object)null && ((NetworkBehaviour)this).NetworkObject.IsSpawned)
			{
				((NetworkBehaviour)this).NetworkObject.Despawn(true);
			}
		}

		public override void LateUpdate()
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			((GrabbableObject)this).LateUpdate();
			if (_renderers == null)
			{
				return;
			}
			float num = 4f * (0.7f + 0.3f * Mathf.Sin(Time.time * 4f));
			Renderer[] renderers = _renderers;
			foreach (Renderer val in renderers)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Material[] sharedMaterials = val.sharedMaterials;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					if (!((Object)(object)sharedMaterials[j] == (Object)null) && ((Object)sharedMaterials[j]).name.StartsWith("M_Shock_Core"))
					{
						val.GetPropertyBlock(_mpb, j);
						_mpb.SetColor("_EmissiveColor", Registry.CoreColor * num);
						val.SetPropertyBlock(_mpb, j);
					}
				}
			}
		}
	}
	internal struct BlastParams
	{
		public float Up;

		public float Out;

		public float Radius;

		public float Stun;

		public float After;

		public float Max;

		public float Noise;

		public bool LaunchOthers;

		public bool PushCruiser;

		public static BlastParams FromConfig()
		{
			return new BlastParams
			{
				Up = Plugin.UpForce.Value,
				Out = Plugin.OutForce.Value,
				Radius = Plugin.BlastRadius.Value,
				Stun = Plugin.EnemyStunSeconds.Value,
				After = Plugin.NoFallDamageAfterLanding.Value,
				Max = Plugin.NoFallDamageMaxSeconds.Value,
				Noise = Plugin.NoiseRange.Value,
				LaunchOthers = Plugin.LaunchOthers.Value,
				PushCruiser = Plugin.PushCruiser.Value
			};
		}

		public void Write(FastBufferWriter w)
		{
			//IL_000a: 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_0020: 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_0036: 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_004c: 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_0062: 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_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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: 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)
			((FastBufferWriter)(ref w)).WriteValueSafe<float>(ref Up, default(ForPrimitives));
			((FastBufferWriter)(ref w)).WriteValueSafe<float>(ref Out, default(ForPrimitives));
			((FastBufferWriter)(ref w)).WriteValueSafe<float>(ref Radius, default(ForPrimitives));
			((FastBufferWriter)(ref w)).WriteValueSafe<float>(ref Stun, default(ForPrimitives));
			((FastBufferWriter)(ref w)).WriteValueSafe<float>(ref After, default(ForPrimitives));
			((FastBufferWriter)(ref w)).WriteValueSafe<float>(ref Max, default(ForPrimitives));
			((FastBufferWriter)(ref w)).WriteValueSafe<float>(ref Noise, default(ForPrimitives));
			((FastBufferWriter)(ref w)).WriteValueSafe<bool>(ref LaunchOthers, default(ForPrimitives));
			((FastBufferWriter)(ref w)).WriteValueSafe<bool>(ref PushCruiser, default(ForPrimitives));
		}

		public static BlastParams Read(FastBufferReader r)
		{
			//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_002a: 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_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_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_0075: 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_008c: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			BlastParams result = default(BlastParams);
			((FastBufferReader)(ref r)).ReadValueSafe<float>(ref result.Up, default(ForPrimitives));
			((FastBufferReader)(ref r)).ReadValueSafe<float>(ref result.Out, default(ForPrimitives));
			((FastBufferReader)(ref r)).ReadValueSafe<float>(ref result.Radius, default(ForPrimitives));
			((FastBufferReader)(ref r)).ReadValueSafe<float>(ref result.Stun, default(ForPrimitives));
			((FastBufferReader)(ref r)).ReadValueSafe<float>(ref result.After, default(ForPrimitives));
			((FastBufferReader)(ref r)).ReadValueSafe<float>(ref result.Max, default(ForPrimitives));
			((FastBufferReader)(ref r)).ReadValueSafe<float>(ref result.Noise, default(ForPrimitives));
			((FastBufferReader)(ref r)).ReadValueSafe<bool>(ref result.LaunchOthers, default(ForPrimitives));
			((FastBufferReader)(ref r)).ReadValueSafe<bool>(ref result.PushCruiser, default(ForPrimitives));
			return result;
		}
	}
	internal static class Net
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__OnThrowRequest;

			public static HandleNamedMessageDelegate <1>__OnThrow;

			public static HandleNamedMessageDelegate <2>__OnConfig;
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static HandleNamedMessageDelegate <>9__11_0;

			public static Func<ulong, bool> <>9__15_0;

			public static Action<FastBufferWriter> <>9__18_0;

			internal void <Register>b__11_0(ulong sender, FastBufferReader r)
			{
				SendConfig(sender);
			}

			internal bool <HostThrow>b__15_0(ulong c)
			{
				return c != 0;
			}

			internal void <SendConfig>b__18_0(FastBufferWriter w)
			{
				//IL_0011: 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_002e: 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)
				int value = Plugin.Price.Value;
				((FastBufferWriter)(ref w)).WriteValueSafe<int>(ref value, default(ForPrimitives));
				value = Plugin.Charges.Value;
				((FastBufferWriter)(ref w)).WriteValueSafe<int>(ref value, default(ForPrimitives));
			}
		}

		private const string MsgThrowRequest = "DanielLC.Shockwave.ThrowRequest";

		private const string MsgThrow = "DanielLC.Shockwave.Throw";

		private const string MsgConfigRequest = "DanielLC.Shockwave.ConfigRequest";

		private const string MsgConfig = "DanielLC.Shockwave.Config";

		private static readonly string[] All = new string[4] { "DanielLC.Shockwave.ThrowRequest", "DanielLC.Shockwave.Throw", "DanielLC.Shockwave.ConfigRequest", "DanielLC.Shockwave.Config" };

		private static bool _registered;

		private static int? _hostCharges;

		public static bool IsHost
		{
			get
			{
				if ((Object)(object)NetworkManager.Singleton != (Object)null)
				{
					return NetworkManager.Singleton.IsServer;
				}
				return false;
			}
		}

		public static int Charges => Math.Max(1, _hostCharges ?? Plugin.Charges.Value);

		public static void Register()
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			//IL_004f: 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_005a: Expected O, but got Unknown
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			//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)
			//IL_0084: Expected O, but got Unknown
			NetworkManager singleton = NetworkManager.Singleton;
			if (_registered || (Object)(object)singleton == (Object)null || singleton.CustomMessagingManager == null)
			{
				return;
			}
			CustomMessagingManager customMessagingManager = singleton.CustomMessagingManager;
			_hostCharges = null;
			if (singleton.IsServer)
			{
				object obj = <>O.<0>__OnThrowRequest;
				if (obj == null)
				{
					HandleNamedMessageDelegate val = OnThrowRequest;
					<>O.<0>__OnThrowRequest = val;
					obj = (object)val;
				}
				customMessagingManager.RegisterNamedMessageHandler("DanielLC.Shockwave.ThrowRequest", (HandleNamedMessageDelegate)obj);
				object obj2 = <>c.<>9__11_0;
				if (obj2 == null)
				{
					HandleNamedMessageDelegate val2 = delegate(ulong sender, FastBufferReader r)
					{
						SendConfig(sender);
					};
					<>c.<>9__11_0 = val2;
					obj2 = (object)val2;
				}
				customMessagingManager.RegisterNamedMessageHandler("DanielLC.Shockwave.ConfigRequest", (HandleNamedMessageDelegate)obj2);
			}
			else
			{
				object obj3 = <>O.<1>__OnThrow;
				if (obj3 == null)
				{
					HandleNamedMessageDelegate val3 = OnThrow;
					<>O.<1>__OnThrow = val3;
					obj3 = (object)val3;
				}
				customMessagingManager.RegisterNamedMessageHandler("DanielLC.Shockwave.Throw", (HandleNamedMessageDelegate)obj3);
				object obj4 = <>O.<2>__OnConfig;
				if (obj4 == null)
				{
					HandleNamedMessageDelegate val4 = OnConfig;
					<>O.<2>__OnConfig = val4;
					obj4 = (object)val4;
				}
				customMessagingManager.RegisterNamedMessageHandler("DanielLC.Shockwave.Config", (HandleNamedMessageDelegate)obj4);
				Send("DanielLC.Shockwave.ConfigRequest", 0uL, null);
			}
			_registered = true;
		}

		public static void Unregister()
		{
			CustomMessagingManager val = (((Object)(object)NetworkManager.Singleton != (Object)null) ? NetworkManager.Singleton.CustomMessagingManager : null);
			if (val != null)
			{
				string[] all = All;
				foreach (string text in all)
				{
					try
					{
						val.UnregisterNamedMessageHandler(text);
					}
					catch (Exception)
					{
					}
				}
			}
			_registered = false;
			_hostCharges = null;
		}

		public static void RequestThrow(ShockwaveGrenadeItem item, Vector3 from, Vector3 to)
		{
			//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_002e: 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)
			if (IsHost)
			{
				HostThrow(((NetworkBehaviour)item).NetworkObjectId, from, to, 0uL);
				return;
			}
			Send("DanielLC.Shockwave.ThrowRequest", 0uL, delegate(FastBufferWriter w)
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				ulong networkObjectId = ((NetworkBehaviour)item).NetworkObjectId;
				((FastBufferWriter)(ref w)).WriteValueSafe<ulong>(ref networkObjectId, default(ForPrimitives));
				((FastBufferWriter)(ref w)).WriteValueSafe(ref from);
				((FastBufferWriter)(ref w)).WriteValueSafe(ref to);
			});
		}

		private static void OnThrowRequest(ulong sender, FastBufferReader r)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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)
			ulong itemId = default(ulong);
			((FastBufferReader)(ref r)).ReadValueSafe<ulong>(ref itemId, default(ForPrimitives));
			Vector3 val = default(Vector3);
			((FastBufferReader)(ref r)).ReadValueSafe(ref val);
			Vector3 to = default(Vector3);
			((FastBufferReader)(ref r)).ReadValueSafe(ref to);
			HostThrow(itemId, val, to, sender);
		}

		private static void HostThrow(ulong itemId, Vector3 from, Vector3 to, ulong sender)
		{
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: 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_00ea: 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_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: 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_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager singleton = NetworkManager.Singleton;
			if (!singleton.SpawnManager.SpawnedObjects.TryGetValue(itemId, out var value))
			{
				return;
			}
			ShockwaveGrenadeItem component = ((Component)value).GetComponent<ShockwaveGrenadeItem>();
			if ((Object)(object)component == (Object)null || component.ChargesLeft <= 0)
			{
				Plugin.Log.LogInfo((object)"Shockwave: throw refused (no charges).");
				return;
			}
			if ((Object)(object)((GrabbableObject)component).playerHeldBy == (Object)null || ((GrabbableObject)component).playerHeldBy.actualClientId != sender)
			{
				Plugin.Log.LogInfo((object)"Shockwave: throw refused (sender isn't holding it).");
				return;
			}
			int left = component.ChargesLeft - 1;
			BlastParams p = BlastParams.FromConfig();
			ulong actualClientId = ((GrabbableObject)component).playerHeldBy.actualClientId;
			List<ulong> list = singleton.ConnectedClientsIds.Where((ulong c) => c != 0).ToList();
			if (list.Count > 0)
			{
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(128, (Allocator)2, 1024);
				try
				{
					((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref itemId, default(ForPrimitives));
					((FastBufferWriter)(ref val)).WriteValueSafe(ref from);
					((FastBufferWriter)(ref val)).WriteValueSafe(ref to);
					((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref left, default(ForPrimitives));
					((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref actualClientId, default(ForPrimitives));
					p.Write(val);
					singleton.CustomMessagingManager.SendNamedMessage("DanielLC.Shockwave.Throw", (IReadOnlyList<ulong>)list, val, (NetworkDelivery)3);
				}
				finally
				{
					((FastBufferWriter)(ref val)).Dispose();
				}
			}
			ApplyThrow(itemId, from, to, left, actualClientId, p);
		}

		private static void OnThrow(ulong sender, FastBufferReader r)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			ulong itemId = default(ulong);
			((FastBufferReader)(ref r)).ReadValueSafe<ulong>(ref itemId, default(ForPrimitives));
			Vector3 val = default(Vector3);
			((FastBufferReader)(ref r)).ReadValueSafe(ref val);
			Vector3 to = default(Vector3);
			((FastBufferReader)(ref r)).ReadValueSafe(ref to);
			int left = default(int);
			((FastBufferReader)(ref r)).ReadValueSafe<int>(ref left, default(ForPrimitives));
			ulong throwerClient = default(ulong);
			((FastBufferReader)(ref r)).ReadValueSafe<ulong>(ref throwerClient, default(ForPrimitives));
			BlastParams p = BlastParams.Read(r);
			ApplyThrow(itemId, val, to, left, throwerClient, p);
		}

		private static void ApplyThrow(ulong itemId, Vector3 from, Vector3 to, int left, ulong throwerClient, BlastParams p)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB thrower = StartOfRound.Instance?.allPlayerScripts?.FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB x) => (Object)(object)x != (Object)null && x.actualClientId == throwerClient && x.isPlayerControlled));
			Blast.Fly(from, to, p, thrower);
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton != (Object)null && singleton.SpawnManager.SpawnedObjects.TryGetValue(itemId, out var value))
			{
				((Component)value).GetComponent<ShockwaveGrenadeItem>()?.OnThrown(left);
			}
		}

		private static void SendConfig(ulong client)
		{
			Send("DanielLC.Shockwave.Config", client, delegate(FastBufferWriter w)
			{
				//IL_0011: 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_002e: 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)
				int value = Plugin.Price.Value;
				((FastBufferWriter)(ref w)).WriteValueSafe<int>(ref value, default(ForPrimitives));
				value = Plugin.Charges.Value;
				((FastBufferWriter)(ref w)).WriteValueSafe<int>(ref value, default(ForPrimitives));
			});
		}

		private static void OnConfig(ulong sender, FastBufferReader r)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			int num = default(int);
			((FastBufferReader)(ref r)).ReadValueSafe<int>(ref num, default(ForPrimitives));
			int num2 = default(int);
			((FastBufferReader)(ref r)).ReadValueSafe<int>(ref num2, default(ForPrimitives));
			_hostCharges = num2;
			Registry.ApplyPrice(num);
			Plugin.Log.LogInfo((object)$"Shockwave: host settings: price {num}, {num2} charges.");
		}

		private static void Send(string name, ulong to, Action<FastBufferWriter> write)
		{
			//IL_003c: 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)
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || singleton.CustomMessagingManager == null)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(128, (Allocator)2, 1024);
			try
			{
				write?.Invoke(val);
				singleton.CustomMessagingManager.SendNamedMessage(name, to, val, (NetworkDelivery)3);
			}
			finally
			{
				((FastBufferWriter)(ref val)).Dispose();
			}
		}
	}
	[HarmonyPatch]
	internal static class NetPatches
	{
		[HarmonyPatch(typeof(StartOfRound), "Start")]
		[HarmonyPostfix]
		private static void StartOfRoundStart()
		{
			Net.Register();
			if (Net.IsHost)
			{
				Registry.ApplyPrice(Plugin.Price.Value);
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "OnDestroy")]
		[HarmonyPrefix]
		private static void StartOfRoundDestroy()
		{
			Net.Unregister();
			FallGuard.Reset();
		}
	}
	public static class PluginInfo
	{
		public const string Guid = "daniel.lethalcompany.shockwavegrenade";

		public const string Name = "Shockwave Grenade";

		public const string Version = "0.1.0";
	}
	[BepInPlugin("daniel.lethalcompany.shockwavegrenade", "Shockwave Grenade", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		internal static ConfigEntry<int> Price;

		internal static ConfigEntry<int> Charges;

		internal static ConfigEntry<bool> LaunchOthers;

		internal static ConfigEntry<float> BlastRadius;

		internal static ConfigEntry<float> UpForce;

		internal static ConfigEntry<float> OutForce;

		internal static ConfigEntry<float> EnemyStunSeconds;

		internal static ConfigEntry<float> NoFallDamageAfterLanding;

		internal static ConfigEntry<float> NoFallDamageMaxSeconds;

		internal static ConfigEntry<bool> PushCruiser;

		internal static ConfigEntry<float> NoiseRange;

		internal static ConfigEntry<bool> ScreenShake;

		private readonly Harmony _harmony = new Harmony("daniel.lethalcompany.shockwavegrenade");

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			Price = ((BaseUnityPlugin)this).Config.Bind<int>("Store (host)", "Price", 120, "Store price in credits (Daniel, q_9b6b2aa2babd49ba).");
			Charges = ((BaseUnityPlugin)this).Config.Bind<int>("Store (host)", "Charges", 3, "Throws per grenade. It stays in your hand until the last one.");
			LaunchOthers = ((BaseUnityPlugin)this).Config.Bind<bool>("Shockwave (host)", "Launch other players", true, "Launch every player in range, not only the thrower.");
			BlastRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Shockwave (host)", "Blast radius", 6f, "Metres.");
			UpForce = ((BaseUnityPlugin)this).Config.Bind<float>("Shockwave (host)", "Up force", 50f, "Upward push. 50 is about 8 m high on open ground.");
			OutForce = ((BaseUnityPlugin)this).Config.Bind<float>("Shockwave (host)", "Out force", 20f, "Push away from the blast. 20 is about 8-9 m sideways.");
			EnemyStunSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Shockwave (host)", "Enemy stun seconds", 1.5f, "Stun enemies in range for this long (0 = off). Enemies are never moved.");
			NoFallDamageAfterLanding = ((BaseUnityPlugin)this).Config.Bind<float>("Shockwave (host)", "No fall damage after landing", 1f, "Seconds of fall-damage protection left after your first landing.");
			NoFallDamageMaxSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Shockwave (host)", "No fall damage max seconds", 10f, "The protection never lasts longer than this after a launch.");
			PushCruiser = ((BaseUnityPlugin)this).Config.Bind<bool>("Shockwave (host)", "Push Cruiser", false, "Push the Company Cruiser too (like a landmine does).");
			NoiseRange = ((BaseUnityPlugin)this).Config.Bind<float>("Shockwave (host)", "Noise range", 15f, "Monsters within this range hear the blast.");
			ScreenShake = ((BaseUnityPlugin)this).Config.Bind<bool>("Local", "Screen shake", true, "Shake your camera a little when a blast goes off near you.");
			_harmony.PatchAll(typeof(Plugin).Assembly);
			Registry.Load();
			Log.LogInfo((object)"Shockwave Grenade 0.1.0 loaded.");
		}
	}
	internal static class Registry
	{
		private static readonly string[] Templates = new string[3] { "Stun grenade", "Easter egg", "Whoopie cushion" };

		internal static readonly Color CoreColor = new Color(0.3f, 0.4f, 1f);

		internal const float CoreGlow = 4f;

		internal const float LightLumen = 40f;

		internal const float LightRange = 2f;

		internal static readonly Vector3 HoldPosition = new Vector3(0f, 0.075f, 0.01f);

		internal static readonly Vector3 HoldRotation;

		private static GameObject _container;

		private static bool _shopRegistered;

		internal static GameObject ModelAsset { get; private set; }

		internal static GameObject RingAsset { get; private set; }

		internal static AudioClip BlastClip { get; private set; }

		internal static AudioClip WhooshClip { get; private set; }

		internal static AudioClip ThrowClip { get; private set; }

		internal static AudioMixerGroup Mixer { get; private set; }

		public static GameObject Prefab { get; private set; }

		public static Item Item { get; private set; }

		public static void Load()
		{
			try
			{
				using (Stream stream = Res("shockwave_grenade"))
				{
					AssetBundle val = ((stream != null) ? AssetBundle.LoadFromStream(stream) : null);
					if ((Object)(object)val == (Object)null)
					{
						Plugin.Log.LogError((object)"Shockwave: the embedded bundle is missing.");
						return;
					}
					ModelAsset = val.LoadAsset<GameObject>("ShockwaveGrenadeModel");
					RingAsset = val.LoadAsset<GameObject>("ShockwaveRing");
				}
				BlastClip = Wav.Load(Res("blast.wav"), "ShockwaveBlast");
				WhooshClip = Wav.Load(Res("whoosh.wav"), "ShockwaveWhoosh");
				ThrowClip = Wav.Load(Res("throw.wav"), "ShockwaveThrow");
				Plugin.Log.LogInfo((object)($"Shockwave: assets loaded (model {(Object)(object)ModelAsset != (Object)null}, ring {(Object)(object)RingAsset != (Object)null}, " + $"sounds {(Object)(object)BlastClip != (Object)null}/{(Object)(object)WhooshClip != (Object)null}/{(Object)(object)ThrowClip != (Object)null})."));
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Shockwave: assets failed to load: {arg}");
			}
		}

		private static Stream Res(string name)
		{
			return Assembly.GetExecutingAssembly().GetManifestResourceStream("ShockwaveGrenade." + name);
		}

		internal static void BuildPrefab()
		{
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Expected O, but got Unknown
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Expected O, but got Unknown
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Invalid comparison between Unknown and I4
			//IL_02f0: 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_04de: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0501: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Prefab != (Object)null)
			{
				return;
			}
			if ((Object)(object)ModelAsset == (Object)null)
			{
				Plugin.Log.LogError((object)"Shockwave: no model, so no item.");
				return;
			}
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null)
			{
				Plugin.Log.LogError((object)"Shockwave: no NetworkManager at GameNetworkManager.Start.");
				return;
			}
			List<GrabbableObject> candidates = (from p in singleton.NetworkConfig.Prefabs.Prefabs
				select (!((Object)(object)p.Prefab != (Object)null)) ? null : p.Prefab.GetComponent<GrabbableObject>() into g
				where (Object)(object)g != (Object)null && (Object)(object)g.itemProperties != (Object)null
				select g).ToList();
			GrabbableObject val = Templates.Select((string n) => ((IEnumerable<GrabbableObject>)candidates).FirstOrDefault((Func<GrabbableObject, bool>)((GrabbableObject g) => g.itemProperties.itemName == n))).FirstOrDefault<GrabbableObject>((Func<GrabbableObject, bool>)((GrabbableObject g) => (Object)(object)g != (Object)null)) ?? ((IEnumerable<GrabbableObject>)candidates).FirstOrDefault((Func<GrabbableObject, bool>)((GrabbableObject g) => !g.itemProperties.twoHanded));
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogError((object)"Shockwave: no vanilla item to base the grenade on.");
				return;
			}
			_container = new GameObject("ShockwaveGrenade.Prefabs");
			_container.SetActive(false);
			((Object)_container).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)_container);
			GameObject val2 = new GameObject("ShockwaveGrenade");
			val2.transform.SetParent(_container.transform, false);
			val2.layer = ((Component)val).gameObject.layer;
			val2.tag = ((Component)val).gameObject.tag;
			NetworkObject obj = val2.AddComponent<NetworkObject>();
			AccessTools.Field(typeof(NetworkObject), "GlobalObjectIdHash").SetValue(obj, StableHash("daniel.lethalcompany.shockwavegrenade.ShockwaveGrenade"));
			AudioSource component = ((Component)val).GetComponent<AudioSource>();
			AudioSource val3 = val2.AddComponent<AudioSource>();
			val3.playOnAwake = false;
			if ((Object)(object)component != (Object)null)
			{
				Mixer = component.outputAudioMixerGroup;
				val3.outputAudioMixerGroup = component.outputAudioMixerGroup;
				val3.spatialBlend = component.spatialBlend;
				val3.rolloffMode = component.rolloffMode;
				val3.minDistance = component.minDistance;
				val3.maxDistance = component.maxDistance;
				val3.dopplerLevel = component.dopplerLevel;
				val3.volume = component.volume;
				if ((int)component.rolloffMode == 2)
				{
					val3.SetCustomCurve((AudioSourceCurveType)0, component.GetCustomCurve((AudioSourceCurveType)0));
				}
			}
			GameObject val4 = Object.Instantiate<GameObject>(ModelAsset, val2.transform, false);
			((Object)val4).name = "Model";
			val4.transform.localPosition = Vector3.zero;
			Transform[] componentsInChildren = val4.GetComponentsInChildren<Transform>(true);
			for (int num = 0; num < componentsInChildren.Length; num++)
			{
				((Component)componentsInChildren[num]).gameObject.layer = val2.layer;
			}
			BoxCollider obj2 = val2.AddComponent<BoxCollider>();
			obj2.center = Vector3.zero;
			obj2.size = new Vector3(0.16f, 0.16f, 0.16f);
			((Collider)obj2).isTrigger = (Object)(object)((Component)val).GetComponent<Collider>() != (Object)null && ((Component)val).GetComponent<Collider>().isTrigger;
			ScanNodeProperties componentInChildren = ((Component)val).GetComponentInChildren<ScanNodeProperties>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				ScanNodeProperties component2 = Object.Instantiate<GameObject>(((Component)componentInChildren).gameObject, val2.transform, false).GetComponent<ScanNodeProperties>();
				((Component)component2).transform.localPosition = Vector3.zero;
				component2.headerText = "Shockwave grenade";
				component2.subText = "Launches the crew. No fall damage.";
				component2.scrapValue = 0;
				component2.nodeType = 0;
			}
			Item itemProperties = val.itemProperties;
			Item = Object.Instantiate<Item>(itemProperties);
			((Object)Item).name = "ShockwaveGrenadeItem";
			Item.itemName = "Shockwave grenade";
			Item.spawnPrefab = val2;
			Item.isScrap = false;
			Item.minValue = (Item.maxValue = 0);
			Item.creditsWorth = Plugin.Price.Value;
			Item.highestSalePercentage = 80;
			Item.twoHanded = false;
			Item.requiresBattery = false;
			Item.isConductiveMetal = false;
			Item.isDefensiveWeapon = false;
			Item.holdButtonUse = false;
			Item.syncUseFunction = false;
			Item.saveItemVariable = true;
			Item.canBeGrabbedBeforeGameStart = true;
			Item.itemIsTrigger = false;
			Item.automaticallySetUsingPower = false;
			Item.meshVariants = (Mesh[])(object)new Mesh[0];
			Item.materialVariants = (Material[])(object)new Material[0];
			Item.spawnPositionTypes = new List<ItemGroup>();
			Item.toolTips = new string[1] { "Throw shockwave : [LMB]" };
			Item.verticalOffset = 0.065f;
			Item.restingRotation = Vector3.zero;
			Item.positionOffset = HoldPosition;
			Item.rotationOffset = HoldRotation;
			Item.weight = Mathf.Clamp(itemProperties.weight, 1f, 3.75f);
			ShockwaveGrenadeItem shockwaveGrenadeItem = val2.AddComponent<ShockwaveGrenadeItem>();
			((GrabbableObject)shockwaveGrenadeItem).itemProperties = Item;
			((GrabbableObject)shockwaveGrenadeItem).grabbable = true;
			((GrabbableObject)shockwaveGrenadeItem).grabbableToEnemies = true;
			((GrabbableObject)shockwaveGrenadeItem).isInFactory = false;
			((GrabbableObject)shockwaveGrenadeItem).scrapValue = 0;
			((GrabbableObject)shockwaveGrenadeItem).mainObjectRenderer = val4.GetComponentInChildren<MeshRenderer>();
			AddGlow(val4);
			Prefab = val2;
			singleton.AddNetworkPrefab(val2);
			RegisterWithLethalLib();
			Plugin.Log.LogInfo((object)$"Shockwave: item built from \"{itemProperties.itemName}\" (hold anim {Item.grabAnim}, weight {Item.weight:F2}).");
		}

		private static void RegisterWithLethalLib()
		{
			if (!_shopRegistered)
			{
				TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
				((Object)val).name = "ShockwaveGrenadeInfo";
				val.clearPreviousText = true;
				val.displayText = "SHOCKWAVE GRENADE\n\nThrow it [LMB] and it goes off where it lands, launching everyone within 6 m high into the air and away from the blast. Nobody takes fall damage until they land. Nearby monsters are stunned for a moment, but they hear it.\n\n3 throws per grenade. It won't save you from a bottomless pit.\n\n";
				Items.RegisterShopItem(Item, (TerminalNode)null, (TerminalNode)null, val, Plugin.Price.Value);
				_shopRegistered = true;
			}
		}

		internal static void ApplyPrice(int price)
		{
			if ((Object)(object)Item == (Object)null || price <= 0)
			{
				return;
			}
			Item.creditsWorth = price;
			Terminal val = Object.FindObjectOfType<Terminal>();
			if (val?.buyableItemsList == null)
			{
				return;
			}
			Item[] buyableItemsList = val.buyableItemsList;
			foreach (Item val2 in buyableItemsList)
			{
				if ((Object)(object)val2 != (Object)null && val2.itemName == Item.itemName)
				{
					val2.creditsWorth = price;
				}
			}
		}

		private static void AddGlow(GameObject model)
		{
			//IL_0005: 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_001c: 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_003b: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Glow");
			val.transform.SetParent(model.transform, false);
			val.transform.localPosition = new Vector3(0f, 0.05f, 0f);
			val.layer = model.layer;
			Light obj = val.AddComponent<Light>();
			obj.type = (LightType)2;
			obj.color = CoreColor;
			obj.range = 2f;
			obj.shadows = (LightShadows)0;
			HDAdditionalLightData obj2 = val.AddComponent<HDAdditionalLightData>();
			obj2.SetIntensity(40f, (LightUnit)0);
			obj2.SetRange(2f);
			obj2.SetColor(CoreColor, -1f);
			obj2.EnableShadows(false);
		}

		private static uint StableHash(string s)
		{
			using MD5 mD = MD5.Create();
			return BitConverter.ToUInt32(mD.ComputeHash(Encoding.UTF8.GetBytes(s)), 0);
		}

		static Registry()
		{
			//IL_0032: 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_004b: 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_0055: 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_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_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)
			Quaternion val = Quaternion.FromToRotation(Vector3.up, new Vector3(0.13f, -0.84f, -0.54f));
			HoldRotation = ((Quaternion)(ref val)).eulerAngles;
		}
	}
	internal static class Wav
	{
		public static AudioClip Load(Stream s, string name)
		{
			if (s == null)
			{
				Plugin.Log.LogError((object)("Shockwave: sound " + name + " is missing."));
				return null;
			}
			using (s)
			{
				using BinaryReader binaryReader = new BinaryReader(s);
				binaryReader.ReadBytes(12);
				int num = 1;
				int num2 = 44100;
				int num3 = 16;
				byte[] array = null;
				while (binaryReader.BaseStream.Position < binaryReader.BaseStream.Length - 8)
				{
					string text = Encoding.ASCII.GetString(binaryReader.ReadBytes(4));
					int num4 = binaryReader.ReadInt32();
					if (text == "fmt ")
					{
						binaryReader.ReadInt16();
						num = binaryReader.ReadInt16();
						num2 = binaryReader.ReadInt32();
						binaryReader.ReadInt32();
						binaryReader.ReadInt16();
						num3 = binaryReader.ReadInt16();
						if (num4 > 16)
						{
							binaryReader.ReadBytes(num4 - 16);
						}
					}
					else
					{
						if (text == "data")
						{
							array = binaryReader.ReadBytes(num4);
							break;
						}
						binaryReader.ReadBytes(num4);
					}
				}
				if (array == null || num3 != 16)
				{
					Plugin.Log.LogError((object)("Shockwave: sound " + name + " isn't 16-bit PCM."));
					return null;
				}
				int num5 = array.Length / 2;
				float[] array2 = new float[num5];
				for (int i = 0; i < num5; i++)
				{
					array2[i] = (float)BitConverter.ToInt16(array, i * 2) / 32768f;
				}
				AudioClip obj = AudioClip.Create(name, num5 / num, num, num2, false);
				obj.SetData(array2, 0);
				return obj;
			}
		}
	}
	[HarmonyPatch]
	internal static class RegistryPatches
	{
		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		[HarmonyPostfix]
		private static void GameNetworkManagerStart()
		{
			Build("GameNetworkManager.Start");
		}

		[HarmonyPatch(typeof(MenuManager), "Start")]
		[HarmonyPostfix]
		private static void MenuManagerStart()
		{
			Build("MenuManager.Start");
		}

		private static void Build(string from)
		{
			if ((Object)(object)Registry.Prefab != (Object)null)
			{
				return;
			}
			Plugin.Log.LogInfo((object)("Shockwave: building the item (" + from + ")."));
			try
			{
				Registry.BuildPrefab();
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Shockwave: building the item failed: {arg}");
			}
		}
	}
}