Decompiled source of Dafis Mega Scrap Pack Emporium v2.2.19

DafiScrapComponents.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;

[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("DafiScrapComponents")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A Helper for Dafi's Scrap item Functionality for Lethal Company")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("DafiScrapComponents")]
[assembly: AssemblyTitle("DafiScrapComponents")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public class AudioTest : MonoBehaviour
{
	public AudioClip testClip;

	public AudioSource testSource;

	private void Start()
	{
		if ((Object)(object)testSource == (Object)null)
		{
			testSource = ((Component)this).gameObject.AddComponent<AudioSource>();
		}
		Debug.Log((object)$"Audio Test - Clip loaded: {(Object)(object)testClip != (Object)null}");
		AudioClip obj = testClip;
		Debug.Log((object)$"Audio Test - Clip length: {((obj != null) ? new float?(obj.length) : null)}");
		AudioClip obj2 = testClip;
		Debug.Log((object)("Audio Test - Clip name: " + ((obj2 != null) ? ((Object)obj2).name : null)));
	}

	public void TestPlay()
	{
		if ((Object)(object)testSource != (Object)null && (Object)(object)testClip != (Object)null)
		{
			testSource.PlayOneShot(testClip);
			Debug.Log((object)"Test sound played");
		}
		else
		{
			Debug.LogError((object)$"Cannot play - Source: {(Object)(object)testSource != (Object)null}, Clip: {(Object)(object)testClip != (Object)null}");
		}
	}
}
public class BatteryWeaponScrap : GrabbableObject
{
	[Header("Battery Settings")]
	[SerializeField]
	private bool requiresBatteryToFire = true;

	[Header("Projectile Settings")]
	[SerializeField]
	private GameObject projectilePrefab;

	[SerializeField]
	private Transform projectileSpawnPoint;

	[Header("Audio Settings")]
	[SerializeField]
	private AudioSource weaponAudio;

	[SerializeField]
	private AudioClip fireSound;

	[SerializeField]
	private AudioClip noPowerSound;

	private bool isFiring;

	private bool isButtonHeld;

	private float lastFireTime;

	private float fireDelay = 0.1f;

	public override void Start()
	{
		((GrabbableObject)this).Start();
		if ((Object)(object)weaponAudio == (Object)null)
		{
			weaponAudio = ((Component)this).GetComponent<AudioSource>();
		}
		if (requiresBatteryToFire && (Object)(object)base.itemProperties != (Object)null)
		{
			base.itemProperties.requiresBattery = true;
		}
	}

	public override void ItemActivate(bool used, bool buttonDown = true)
	{
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		((GrabbableObject)this).ItemActivate(used, buttonDown);
		isButtonHeld = buttonDown;
		if (buttonDown && !(Time.time - lastFireTime < fireDelay) && !isFiring)
		{
			if (requiresBatteryToFire && (base.insertedBattery == null || base.insertedBattery.charge < base.itemProperties.batteryUsage))
			{
				weaponAudio.PlayOneShot(noPowerSound);
			}
			else if (((NetworkBehaviour)this).IsOwner)
			{
				FireWeaponServerRpc(GetFireDirection());
				lastFireTime = Time.time;
			}
		}
	}

	private Vector3 GetFireDirection()
	{
		//IL_001c: 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)
		if (!base.isHeld || (Object)(object)base.playerHeldBy == (Object)null)
		{
			return projectileSpawnPoint.forward;
		}
		return ((Component)GameNetworkManager.Instance.localPlayerController.gameplayCamera).transform.forward;
	}

	[ServerRpc]
	private void FireWeaponServerRpc(Vector3 fireDirection)
	{
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: 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)
		if (base.isHeld && (!requiresBatteryToFire || (base.insertedBattery != null && !(base.insertedBattery.charge < base.itemProperties.batteryUsage))))
		{
			Object.Instantiate<GameObject>(projectilePrefab, projectileSpawnPoint.position, Quaternion.LookRotation(fireDirection)).GetComponent<NetworkObject>().Spawn(false);
			if (requiresBatteryToFire && base.insertedBattery != null)
			{
				float charge = base.insertedBattery.charge;
				float num = Mathf.Max(0f, charge - base.itemProperties.batteryUsage);
				base.insertedBattery.charge = num;
				SyncBatteryChargeClientRpc(charge, num);
			}
			FireWeaponClientRpc();
		}
	}

	[ClientRpc]
	private void SyncBatteryChargeClientRpc(float oldCharge, float newCharge)
	{
		if (!((NetworkBehaviour)this).IsOwner && base.insertedBattery != null && Mathf.Approximately(base.insertedBattery.charge, oldCharge))
		{
			base.insertedBattery.charge = newCharge;
			if ((Object)(object)base.playerHeldBy == (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				HUDManager.Instance.batteryMeter.fillAmount = newCharge;
			}
		}
	}

	[ClientRpc]
	private void FireWeaponClientRpc()
	{
		PlayFireEffects();
	}

	private void PlayFireEffects()
	{
		if ((Object)(object)weaponAudio != (Object)null && (Object)(object)fireSound != (Object)null)
		{
			weaponAudio.PlayOneShot(fireSound);
			WalkieTalkie.TransmitOneShotAudio(weaponAudio, fireSound, 1f);
		}
	}

	public override void Update()
	{
		((GrabbableObject)this).Update();
		if (((NetworkBehaviour)this).IsOwner && base.isHeld && requiresBatteryToFire && base.insertedBattery != null)
		{
			HUDManager.Instance.batteryMeter.fillAmount = base.insertedBattery.charge;
		}
	}

	public void OnBatteryRecharged()
	{
		if (base.insertedBattery != null)
		{
			base.insertedBattery.charge = 1f;
			if (((NetworkBehaviour)this).IsOwner && (Object)(object)base.playerHeldBy == (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				HUDManager.Instance.batteryMeter.fillAmount = 1f;
			}
		}
	}
}
[BepInPlugin("com.dafini.consumables", "Consumables Mod", "1.0.0")]
public class ConsumablePlugin : BaseUnityPlugin
{
	[HarmonyPatch(typeof(PlayerControllerB), "DamagePlayer")]
	private class DamagePlayerPatch
	{
		private static bool Prefix(PlayerControllerB __instance, int damageNumber, bool hasDamageSFX, bool callRPC, CauseOfDeath causeOfDeath)
		{
			if (playerInvulnerabilityStatus.TryGetValue(((NetworkBehaviour)__instance).NetworkObjectId, out var value) && value)
			{
				logger.LogInfo((object)("Blocked damage for player " + __instance.playerUsername + " due to invulnerability"));
				return false;
			}
			return true;
		}
	}

	private static ManualLogSource logger;

	private static readonly Dictionary<ulong, bool> playerInvulnerabilityStatus = new Dictionary<ulong, bool>();

	private Harmony harmony;

	private void Awake()
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		logger = ((BaseUnityPlugin)this).Logger;
		harmony = new Harmony("com.dafini.consumables");
		harmony.PatchAll();
		logger.LogInfo((object)"Consumables mod patch loaded!");
	}
}
public class ConsumableScrap : GrabbableObject
{
	[Header("Effect Timer Settings")]
	[SerializeField]
	private bool hasEffectTimer;

	[SerializeField]
	private float effectDuration = 10f;

	[SerializeField]
	private bool hasSecondaryEffects;

	[Header("Audio Settings")]
	[SerializeField]
	private AudioSource itemAudioSource;

	[SerializeField]
	private AudioClip useSound;

	[SerializeField]
	private AudioClip effectEndSound;

	[SerializeField]
	private float soundVolume = 1f;

	[Header("Primary Effect Settings")]
	[SerializeField]
	private float healAmount;

	[SerializeField]
	private bool canOverheal;

	[SerializeField]
	private float moveSpeedBuff;

	[SerializeField]
	private bool grantInvincibility;

	[SerializeField]
	private float jumpHeightBuff;

	[SerializeField]
	private bool rechargeHeldItems;

	[Header("Secondary Effect Settings")]
	[SerializeField]
	private float secondaryHealAmount;

	[SerializeField]
	private bool secondaryCanOverheal;

	[SerializeField]
	private float secondaryMoveSpeedBuff;

	[SerializeField]
	private bool secondaryGrantInvincibility;

	[SerializeField]
	private float secondaryJumpHeightBuff;

	[SerializeField]
	private bool secondaryRechargeHeldItems;

	[Header("Throwable Settings")]
	[SerializeField]
	private bool isThrowable;

	[SerializeField]
	private GameObject thrownObjectPrefab;

	[SerializeField]
	private float throwForce = 10f;

	[SerializeField]
	private float throwUpwardForce = 2f;

	private bool effectActive;

	private float effectTimer;

	private PlayerControllerB affectedPlayer;

	private float originalSpeed;

	private float originalJumpForce;

	private static readonly Dictionary<ulong, bool> playerInvulnerabilityStatus = new Dictionary<ulong, bool>();

	private static readonly Dictionary<ulong, Coroutine> activeEffectCoroutines = new Dictionary<ulong, Coroutine>();

	private static ManualLogSource logger = Logger.CreateLogSource("ConsumableScrap");

	private static readonly Dictionary<ulong, Coroutine> invulnerabilityCoroutines = new Dictionary<ulong, Coroutine>();

	private const float INVULN_UPDATE_RATE = 0.02f;

	private bool hasVerifiedAudio;

	private PlayerActions playerActions;

	public override void Start()
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected O, but got Unknown
		((GrabbableObject)this).Start();
		Debug.Log((object)("[ConsumableScrap] Start - GameObject: " + ((Object)((Component)this).gameObject).name));
		SetupAudioSource();
		VerifyAudioClip();
		playerActions = new PlayerActions();
		playerActions.Enable();
	}

	private void VerifyAudioClip()
	{
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)useSound != (Object)null)
		{
			Debug.Log((object)"[ConsumableScrap] Audio Clip Details:");
			Debug.Log((object)("- Name: " + ((Object)useSound).name));
			Debug.Log((object)$"- Length: {useSound.length} seconds");
			Debug.Log((object)$"- Channels: {useSound.channels}");
			Debug.Log((object)$"- Frequency: {useSound.frequency}");
			Debug.Log((object)$"- Loaded: {useSound.loadState}");
			hasVerifiedAudio = true;
		}
		else
		{
			Debug.LogError((object)"[ConsumableScrap] UseSound clip is null!");
		}
	}

	private void SetupAudioSource()
	{
		try
		{
			if ((Object)(object)itemAudioSource == (Object)null)
			{
				itemAudioSource = ((Component)this).GetComponent<AudioSource>();
			}
			if ((Object)(object)itemAudioSource == (Object)null)
			{
				itemAudioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			}
			itemAudioSource.playOnAwake = false;
			itemAudioSource.spatialBlend = 1f;
			itemAudioSource.maxDistance = 15f;
			itemAudioSource.rolloffMode = (AudioRolloffMode)1;
			itemAudioSource.volume = soundVolume;
			itemAudioSource.priority = 128;
			Debug.Log((object)$"[ConsumableScrap] Audio Source Setup - Volume: {itemAudioSource.volume}, Mute: {itemAudioSource.mute}");
			Debug.Log((object)$"[ConsumableScrap] Audio Source Mixer Group: {(Object)(object)itemAudioSource.outputAudioMixerGroup != (Object)null}");
		}
		catch (Exception arg)
		{
			Debug.LogError((object)$"[ConsumableScrap] Error in SetupAudioSource: {arg}");
		}
	}

	public override void ItemActivate(bool used, bool buttonDown = true)
	{
		((GrabbableObject)this).ItemActivate(used, buttonDown);
		if (buttonDown)
		{
			if (isThrowable)
			{
				ThrowItem();
			}
			else
			{
				UseItem();
			}
		}
	}

	private void UseItem()
	{
		if (!((NetworkBehaviour)this).IsOwner || (Object)(object)base.playerHeldBy == (Object)null)
		{
			return;
		}
		Debug.Log((object)"[ConsumableScrap] UseItem called - Starting audio checks");
		if (!hasVerifiedAudio)
		{
			VerifyAudioClip();
		}
		if ((Object)(object)useSound != (Object)null)
		{
			Debug.Log((object)"[ConsumableScrap] Attempting to play through SFX system");
		}
		if ((Object)(object)itemAudioSource != (Object)null && (Object)(object)useSound != (Object)null)
		{
			try
			{
				Debug.Log((object)"[ConsumableScrap] Attempting Method 1 - Direct Play");
				itemAudioSource.clip = useSound;
				itemAudioSource.volume = soundVolume;
				itemAudioSource.Play();
				Debug.Log((object)"[ConsumableScrap] Attempting Method 2 - PlayOneShot");
				itemAudioSource.PlayOneShot(useSound, soundVolume);
				Debug.Log((object)"[ConsumableScrap] Attempting Method 3 - RoundManager SFX");
				PlayItemSoundServerRpc();
			}
			catch (Exception arg)
			{
				Debug.LogError((object)$"[ConsumableScrap] Error playing sound: {arg}");
			}
		}
		ApplyEffectsServerRpc(((NetworkBehaviour)base.playerHeldBy).NetworkObjectId);
		RemoveItemFromInventory();
	}

	private void RemoveItemFromInventory()
	{
		if ((Object)(object)base.playerHeldBy == (Object)null)
		{
			return;
		}
		int num = Array.IndexOf(base.playerHeldBy.ItemSlots, (GrabbableObject)(object)this);
		if (num == -1)
		{
			return;
		}
		base.playerHeldBy.ItemSlots[num] = null;
		if (base.playerHeldBy.currentItemSlot == num && (Object)(object)base.playerHeldBy.currentlyHeldObjectServer == (Object)(object)this)
		{
			base.playerHeldBy.currentlyHeldObjectServer = null;
			if (((NetworkBehaviour)this).IsOwner)
			{
				base.playerHeldBy.isHoldingObject = false;
				base.playerHeldBy.twoHandedAnimation = false;
				base.playerHeldBy.twoHanded = false;
				base.playerHeldBy.playerBodyAnimator.SetBool("cancelHolding", true);
				((Behaviour)HUDManager.Instance.itemSlotIcons[num]).enabled = false;
				((Behaviour)HUDManager.Instance.holdingTwoHandedItem).enabled = false;
			}
		}
		DestroyItemServerRpc();
	}

	private void PlayItemSound(AudioClip sound)
	{
		if ((Object)(object)sound != (Object)null && (Object)(object)itemAudioSource != (Object)null)
		{
			itemAudioSource.PlayOneShot(sound, soundVolume);
			WalkieTalkie.TransmitOneShotAudio(itemAudioSource, sound, 1f);
		}
	}

	private void ThrowItem()
	{
		//IL_0063: 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_006a: Unknown result type (might be due to invalid IL or missing references)
		if (((NetworkBehaviour)this).IsOwner && !((Object)(object)base.playerHeldBy == (Object)null))
		{
			if ((Object)(object)base.itemProperties.throwSFX != (Object)null && (Object)(object)itemAudioSource != (Object)null)
			{
				PlayItemSound(base.itemProperties.throwSFX);
				PlayThrowSoundServerRpc();
			}
			Vector3 forward = ((Component)GameNetworkManager.Instance.localPlayerController.gameplayCamera).transform.forward;
			ThrowItemServerRpc(forward);
		}
	}

	[ServerRpc]
	private void PlayThrowSoundServerRpc()
	{
		PlayThrowSoundClientRpc();
	}

	[ClientRpc]
	private void PlayThrowSoundClientRpc()
	{
		if (!((NetworkBehaviour)this).IsOwner)
		{
			PlayItemSound(base.itemProperties.throwSFX);
		}
	}

	[ServerRpc]
	private void PlayItemSoundServerRpc()
	{
		Debug.Log((object)"[ConsumableScrap] PlayItemSoundServerRpc called");
		PlayItemSoundClientRpc();
	}

	[ClientRpc]
	private void PlayItemSoundClientRpc()
	{
		if (!((NetworkBehaviour)this).IsOwner)
		{
			Debug.Log((object)"[ConsumableScrap] PlayItemSoundClientRpc received on non-owner");
			if ((Object)(object)itemAudioSource != (Object)null && (Object)(object)useSound != (Object)null)
			{
				itemAudioSource.PlayOneShot(useSound, soundVolume);
				WalkieTalkie.TransmitOneShotAudio(itemAudioSource, useSound, 1f);
			}
		}
	}

	public void TestAudioSetup()
	{
		Debug.Log((object)("[ConsumableScrap] Audio Test - GameObject: " + ((Object)((Component)this).gameObject).name));
		Debug.Log((object)$"[ConsumableScrap] AudioSource exists: {(Object)(object)itemAudioSource != (Object)null}");
		Debug.Log((object)$"[ConsumableScrap] UseSound exists: {(Object)(object)useSound != (Object)null}");
		AudioSource obj = itemAudioSource;
		Debug.Log((object)$"[ConsumableScrap] AudioSource enabled: {((obj != null) ? new bool?(((Behaviour)obj).enabled) : null)}");
		AudioSource obj2 = itemAudioSource;
		Debug.Log((object)$"[ConsumableScrap] AudioSource volume: {((obj2 != null) ? new float?(obj2.volume) : null)}");
		AudioSource obj3 = itemAudioSource;
		Debug.Log((object)$"[ConsumableScrap] AudioSource spatial blend: {((obj3 != null) ? new float?(obj3.spatialBlend) : null)}");
		if ((Object)(object)itemAudioSource != (Object)null && (Object)(object)useSound != (Object)null)
		{
			Debug.Log((object)"[ConsumableScrap] Attempting test sound...");
			itemAudioSource.PlayOneShot(useSound, 1f);
		}
	}

	private void ApplyEffects(PlayerControllerB player, bool isSecondaryEffect)
	{
		float num = (isSecondaryEffect ? secondaryHealAmount : healAmount);
		bool flag = (isSecondaryEffect ? secondaryCanOverheal : canOverheal);
		float num2 = (isSecondaryEffect ? secondaryMoveSpeedBuff : moveSpeedBuff);
		if (!isSecondaryEffect)
		{
			_ = grantInvincibility;
		}
		else
		{
			_ = secondaryGrantInvincibility;
		}
		float num3 = (isSecondaryEffect ? secondaryJumpHeightBuff : jumpHeightBuff);
		bool num4 = (isSecondaryEffect ? secondaryRechargeHeldItems : rechargeHeldItems);
		originalSpeed = player.movementSpeed;
		originalJumpForce = player.jumpForce;
		if (num > 0f)
		{
			int num5 = Mathf.RoundToInt(num);
			int num6 = (flag ? 200 : 100);
			player.health = Mathf.Min(player.health + num5, num6);
			if (((NetworkBehaviour)player).IsOwner)
			{
				HUDManager.Instance.UpdateHealthUI(player.health, true);
				SyncHealthServerRpc(((NetworkBehaviour)player).NetworkObjectId, player.health);
			}
		}
		if (num2 > 0f)
		{
			player.movementSpeed += num2;
		}
		if ((isSecondaryEffect && secondaryGrantInvincibility) || (!isSecondaryEffect && grantInvincibility))
		{
			if (invulnerabilityCoroutines.TryGetValue(((NetworkBehaviour)player).NetworkObjectId, out var value))
			{
				((MonoBehaviour)this).StopCoroutine(value);
			}
			Coroutine value2 = ((MonoBehaviour)this).StartCoroutine(InvulnerabilityEffect(player));
			invulnerabilityCoroutines[((NetworkBehaviour)player).NetworkObjectId] = value2;
		}
		if (num3 > 0f)
		{
			player.jumpForce += num3;
		}
		if (num4)
		{
			RechargeItems(player);
		}
	}

	private IEnumerator InvulnerabilityEffect(PlayerControllerB player)
	{
		WaitForSeconds updateWait = new WaitForSeconds(0.02f);
		float endTime = Time.time + effectDuration;
		while (Time.time < endTime && (Object)(object)player != (Object)null && !player.isPlayerDead)
		{
			if (((NetworkBehaviour)player).IsOwner && player.health < 100)
			{
				player.health = 100;
				HUDManager.Instance.UpdateHealthUI(100, true);
				SyncHealthServerRpc(((NetworkBehaviour)player).NetworkObjectId, 100);
			}
			yield return updateWait;
		}
		invulnerabilityCoroutines.Remove(((NetworkBehaviour)player).NetworkObjectId);
	}

	private void RechargeItems(PlayerControllerB player)
	{
		if (!rechargeHeldItems)
		{
			return;
		}
		bool flag = false;
		GrabbableObject[] itemSlots = player.ItemSlots;
		BatteryWeaponScrap batteryWeaponScrap = default(BatteryWeaponScrap);
		foreach (GrabbableObject val in itemSlots)
		{
			if (!((Object)(object)val != (Object)null) || val.insertedBattery == null)
			{
				continue;
			}
			float charge = val.insertedBattery.charge;
			val.insertedBattery.charge = 10f;
			if (((NetworkBehaviour)player).IsOwner)
			{
				if ((Object)(object)val == (Object)(object)player.currentlyHeldObjectServer)
				{
					HUDManager.Instance.batteryMeter.fillAmount = 1f;
				}
				SyncBatteryChargeServerRpc(((NetworkBehaviour)val).NetworkObjectId, charge, 1f);
			}
			flag = true;
			if (((Component)val).TryGetComponent<BatteryWeaponScrap>(ref batteryWeaponScrap))
			{
				batteryWeaponScrap.OnBatteryRecharged();
			}
		}
		if (flag && (Object)(object)useSound != (Object)null)
		{
			itemAudioSource.PlayOneShot(useSound, soundVolume);
			WalkieTalkie.TransmitOneShotAudio(itemAudioSource, useSound, 1f);
		}
	}

	private void RemoveEffects(PlayerControllerB player)
	{
		if (!((Object)(object)player == (Object)null))
		{
			player.movementSpeed = originalSpeed;
			player.jumpForce = originalJumpForce;
			if (grantInvincibility || secondaryGrantInvincibility)
			{
				SetInvulnerabilityServerRpc(((NetworkBehaviour)player).NetworkObjectId, isInvulnerable: false);
			}
		}
	}

	private IEnumerator EffectDurationCoroutine(ulong playerId)
	{
		yield return (object)new WaitForSeconds(effectDuration);
		PlayerControllerB player = default(PlayerControllerB);
		if (NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(playerId, out var value) && ((Component)value).TryGetComponent<PlayerControllerB>(ref player))
		{
			if (hasSecondaryEffects)
			{
				ApplyEffects(player, isSecondaryEffect: true);
			}
			else
			{
				RemoveEffects(player);
			}
			if ((Object)(object)effectEndSound != (Object)null)
			{
				PlayEndSoundServerRpc();
			}
		}
		effectActive = false;
		activeEffectCoroutines.Remove(playerId);
	}

	[ServerRpc]
	private void ApplyEffectsServerRpc(ulong playerId)
	{
		PlayerControllerB val = default(PlayerControllerB);
		if (!NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(playerId, out var value) || !((Component)value).TryGetComponent<PlayerControllerB>(ref val))
		{
			return;
		}
		ApplyEffectsClientRpc(playerId);
		if (hasEffectTimer)
		{
			if (activeEffectCoroutines.TryGetValue(playerId, out var value2))
			{
				((MonoBehaviour)this).StopCoroutine(value2);
			}
			Coroutine value3 = ((MonoBehaviour)this).StartCoroutine(EffectDurationCoroutine(playerId));
			activeEffectCoroutines[playerId] = value3;
		}
	}

	[ClientRpc]
	private void ApplyEffectsClientRpc(ulong playerId)
	{
		PlayerControllerB player = default(PlayerControllerB);
		if (NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(playerId, out var value) && ((Component)value).TryGetComponent<PlayerControllerB>(ref player))
		{
			ApplyEffects(player, isSecondaryEffect: false);
			effectActive = true;
			if ((Object)(object)useSound != (Object)null)
			{
				PlayUseSoundServerRpc();
			}
		}
	}

	[ServerRpc]
	private void SetInvulnerabilityServerRpc(ulong playerId, bool isInvulnerable)
	{
		playerInvulnerabilityStatus[playerId] = isInvulnerable;
		SetInvulnerabilityClientRpc(playerId, isInvulnerable);
	}

	[ClientRpc]
	private void SetInvulnerabilityClientRpc(ulong playerId, bool isInvulnerable)
	{
		playerInvulnerabilityStatus[playerId] = isInvulnerable;
	}

	[ServerRpc]
	private void SyncHealthServerRpc(ulong playerId, int newHealth)
	{
		SyncHealthClientRpc(playerId, newHealth);
	}

	[ClientRpc]
	private void SyncHealthClientRpc(ulong playerId, int newHealth)
	{
		PlayerControllerB val = default(PlayerControllerB);
		if (!((NetworkBehaviour)this).IsOwner && NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(playerId, out var value) && ((Component)value).TryGetComponent<PlayerControllerB>(ref val))
		{
			val.health = newHealth;
			if ((Object)(object)val == (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				HUDManager.Instance.UpdateHealthUI(newHealth, true);
			}
		}
	}

	[ServerRpc]
	private void SyncBatteryChargeServerRpc(ulong itemId, float oldCharge, float newCharge)
	{
		SyncBatteryChargeClientRpc(itemId, oldCharge, newCharge);
	}

	[ClientRpc]
	private void SyncBatteryChargeClientRpc(ulong itemId, float oldCharge, float newCharge)
	{
		GrabbableObject val = default(GrabbableObject);
		if (!((NetworkBehaviour)this).IsOwner && NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(itemId, out var value) && ((Component)value).TryGetComponent<GrabbableObject>(ref val) && val.insertedBattery != null && Mathf.Approximately(val.insertedBattery.charge, oldCharge))
		{
			val.insertedBattery.charge = newCharge;
		}
	}

	[ServerRpc]
	private void ThrowItemServerRpc(Vector3 throwDirection)
	{
		//IL_0017: 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_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: 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_0040: 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_0048: 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_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_008c: 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)
		if ((Object)(object)thrownObjectPrefab != (Object)null)
		{
			Vector3 val = ((Component)this).transform.position + throwDirection * 0.5f + Vector3.up * 0.5f;
			GameObject val2 = Object.Instantiate<GameObject>(thrownObjectPrefab, val, Quaternion.identity);
			NetworkObject component = val2.GetComponent<NetworkObject>();
			if ((Object)(object)component != (Object)null)
			{
				component.Spawn(false);
				Rigidbody val3 = default(Rigidbody);
				if (val2.TryGetComponent<Rigidbody>(ref val3))
				{
					val3.AddForce(throwDirection * throwForce + Vector3.up * throwUpwardForce, (ForceMode)1);
				}
			}
		}
		RemoveItemAndNotifyClientsServerRpc();
	}

	[ServerRpc]
	private void PlayUseSoundServerRpc()
	{
		PlayUseSoundClientRpc();
	}

	[ClientRpc]
	private void PlayUseSoundClientRpc()
	{
		if ((Object)(object)useSound != (Object)null && (Object)(object)itemAudioSource != (Object)null)
		{
			itemAudioSource.PlayOneShot(useSound, soundVolume);
			WalkieTalkie.TransmitOneShotAudio(itemAudioSource, useSound, 1f);
		}
	}

	private void PlayEndSound()
	{
		if ((Object)(object)effectEndSound != (Object)null && (Object)(object)itemAudioSource != (Object)null)
		{
			PlayItemSound(effectEndSound);
			PlayEndSoundServerRpc();
		}
	}

	[ServerRpc]
	private void PlayEndSoundServerRpc()
	{
		PlayEndSoundClientRpc();
	}

	[ClientRpc]
	private void PlayEndSoundClientRpc()
	{
		if ((Object)(object)effectEndSound != (Object)null && (Object)(object)itemAudioSource != (Object)null)
		{
			itemAudioSource.PlayOneShot(effectEndSound, soundVolume);
			WalkieTalkie.TransmitOneShotAudio(itemAudioSource, effectEndSound, 1f);
		}
	}

	[ServerRpc]
	private void DestroyItemServerRpc()
	{
		if ((Object)(object)((NetworkBehaviour)this).NetworkObject != (Object)null && ((NetworkBehaviour)this).NetworkObject.IsSpawned)
		{
			((NetworkBehaviour)this).NetworkObject.Despawn(true);
		}
		DestroyItemClientRpc();
	}

	[ServerRpc]
	private void RemoveItemAndNotifyClientsServerRpc()
	{
		if ((Object)(object)((NetworkBehaviour)this).NetworkObject != (Object)null && ((NetworkBehaviour)this).NetworkObject.IsSpawned)
		{
			((NetworkBehaviour)this).NetworkObject.Despawn(true);
		}
		RemoveItemClientRpc();
	}

	[ClientRpc]
	private void DestroyItemClientRpc()
	{
		if (!((NetworkBehaviour)this).IsOwner)
		{
			RemoveItemFromInventory();
		}
		Object.Destroy((Object)(object)((Component)this).gameObject);
	}

	[ClientRpc]
	private void RemoveItemClientRpc()
	{
		if (!((NetworkBehaviour)this).IsOwner)
		{
			RemoveItemFromInventory();
		}
		Object.Destroy((Object)(object)((Component)this).gameObject);
	}

	public override void OnDestroy()
	{
		((NetworkBehaviour)this).OnDestroy();
		foreach (Coroutine value in invulnerabilityCoroutines.Values)
		{
			if (value != null)
			{
				((MonoBehaviour)this).StopCoroutine(value);
			}
		}
		invulnerabilityCoroutines.Clear();
		if ((Object)(object)affectedPlayer != (Object)null)
		{
			RemoveEffects(affectedPlayer);
		}
		foreach (Coroutine value2 in activeEffectCoroutines.Values)
		{
			if (value2 != null)
			{
				((MonoBehaviour)this).StopCoroutine(value2);
			}
		}
		activeEffectCoroutines.Clear();
		if ((Object)(object)affectedPlayer != (Object)null && (grantInvincibility || secondaryGrantInvincibility) && playerInvulnerabilityStatus.ContainsKey(((NetworkBehaviour)affectedPlayer).NetworkObjectId))
		{
			playerInvulnerabilityStatus.Remove(((NetworkBehaviour)affectedPlayer).NetworkObjectId);
		}
	}
}
public class ThrownObject : NetworkBehaviour
{
	[Header("Collision Settings")]
	[SerializeField]
	private bool destroyOnCollision = true;

	[SerializeField]
	private LayerMask collisionLayers;

	[SerializeField]
	private float collisionCheckRadius = 0.1f;

	[Header("Timer Settings")]
	[SerializeField]
	private bool useDetonationTimer;

	[SerializeField]
	private float detonationTime = 3f;

	[Header("Explosion Settings")]
	[SerializeField]
	private bool causesExplosion = true;

	[SerializeField]
	private float explosionRadius = 5f;

	[SerializeField]
	private int explosionDamage = 50;

	[SerializeField]
	private LayerMask explosionLayers;

	[SerializeField]
	private GameObject explosionEffectPrefab;

	[Header("Audio")]
	[SerializeField]
	private AudioSource audioSource;

	[SerializeField]
	private AudioClip explosionSound;

	[SerializeField]
	private float soundVolume = 1f;

	private float timer;

	private bool hasExploded;

	private RaycastHit[] explosionHits;

	private void Start()
	{
		if ((Object)(object)audioSource == (Object)null)
		{
			audioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
		}
		if (explosionHits == null)
		{
			explosionHits = (RaycastHit[])(object)new RaycastHit[20];
		}
	}

	private void Update()
	{
		if (!((NetworkBehaviour)this).IsOwner || hasExploded)
		{
			return;
		}
		if (useDetonationTimer)
		{
			timer += Time.deltaTime;
			if (timer >= detonationTime)
			{
				ExplodeServerRpc();
				return;
			}
		}
		CheckCollisions();
	}

	private void CheckCollisions()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		if (LayerMask.op_Implicit(collisionLayers) != 0 && Physics.OverlapSphere(((Component)this).transform.position, collisionCheckRadius, LayerMask.op_Implicit(collisionLayers)).Length != 0 && destroyOnCollision)
		{
			if (causesExplosion)
			{
				ExplodeServerRpc();
			}
			else
			{
				DestroyObjectServerRpc();
			}
		}
	}

	[ServerRpc]
	private void ExplodeServerRpc()
	{
		//IL_0016: 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_0032: 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_005d: 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_007b: Unknown result type (might be due to invalid IL or missing references)
		if (hasExploded)
		{
			return;
		}
		hasExploded = true;
		int num = Physics.SphereCastNonAlloc(((Component)this).transform.position, explosionRadius, Vector3.up, explosionHits, 0.1f, LayerMask.op_Implicit(explosionLayers));
		for (int i = 0; i < num; i++)
		{
			if (!Physics.Linecast(((Component)this).transform.position, ((RaycastHit)(ref explosionHits[i])).point, StartOfRound.Instance.collidersAndRoomMask))
			{
				ProcessExplosionHit(explosionHits[i]);
			}
		}
		ExplodeClientRpc(((Component)this).transform.position);
		DestroyObjectServerRpc();
	}

	private void ProcessExplosionHit(RaycastHit hit)
	{
		//IL_0006: 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_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: 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_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_008c: 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_0095: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0183: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		float num = Vector3.Distance(((Component)this).transform.position, ((RaycastHit)(ref hit)).point);
		float num2 = 1f - num / explosionRadius;
		int num3 = Mathf.RoundToInt((float)explosionDamage * num2);
		PlayerControllerB component = ((Component)((RaycastHit)(ref hit)).collider).GetComponent<PlayerControllerB>();
		Vector3 val;
		if ((Object)(object)component != (Object)null)
		{
			val = default(Vector3);
			component.DamagePlayer(num3, true, true, (CauseOfDeath)1, 0, false, val);
			CharacterController val2 = default(CharacterController);
			if (((Component)component).gameObject.TryGetComponent<CharacterController>(ref val2))
			{
				val = ((Component)component).transform.position - ((Component)this).transform.position;
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				component.externalForces += normalized * ((float)num3 * 2f);
			}
			return;
		}
		EnemyAI val3 = ((Component)((RaycastHit)(ref hit)).collider).GetComponent<EnemyAI>();
		if ((Object)(object)val3 == (Object)null)
		{
			EnemyAICollisionDetect component2 = ((Component)((RaycastHit)(ref hit)).collider).GetComponent<EnemyAICollisionDetect>();
			if ((Object)(object)component2 != (Object)null && (Object)(object)component2.mainScript != (Object)null)
			{
				val3 = component2.mainScript;
			}
		}
		if ((Object)(object)val3 != (Object)null)
		{
			IHittable component3 = ((Component)val3).GetComponent<IHittable>();
			if (component3 != null)
			{
				val = ((Component)val3).transform.position - ((Component)this).transform.position;
				Vector3 normalized2 = ((Vector3)(ref val)).normalized;
				component3.Hit(num3, normalized2, (PlayerControllerB)null, true, -1);
			}
			else
			{
				val3.HitEnemy(num3, (PlayerControllerB)null, false, -1);
			}
			Rigidbody val4 = default(Rigidbody);
			if (((Component)val3).gameObject.TryGetComponent<Rigidbody>(ref val4))
			{
				val = ((Component)val3).transform.position - ((Component)this).transform.position;
				_ = ((Vector3)(ref val)).normalized;
				val4.AddExplosionForce((float)num3 * 100f, ((Component)this).transform.position, explosionRadius);
			}
		}
	}

	[ServerRpc]
	private void DamagePlayerServerRpc(ulong playerId, int damage)
	{
		//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)
		PlayerControllerB val = default(PlayerControllerB);
		if (NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(playerId, out var value) && ((Component)value).TryGetComponent<PlayerControllerB>(ref val))
		{
			val.DamagePlayer(damage, true, true, (CauseOfDeath)3, 0, false, default(Vector3));
		}
	}

	[ServerRpc]
	private void DamageEnemyServerRpc(ulong enemyId, int damage)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		EnemyAI val = default(EnemyAI);
		if (NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(enemyId, out var value) && ((Component)value).TryGetComponent<EnemyAI>(ref val))
		{
			IHittable component = ((Component)val).GetComponent<IHittable>();
			if (component != null)
			{
				component.Hit(damage, Vector3.zero, (PlayerControllerB)null, true, -1);
			}
			else
			{
				val.HitEnemy(damage, (PlayerControllerB)null, false, -1);
			}
		}
	}

	[ClientRpc]
	private void ExplodeClientRpc(Vector3 position)
	{
		//IL_0014: 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)
		if ((Object)(object)explosionEffectPrefab != (Object)null)
		{
			Object.Instantiate<GameObject>(explosionEffectPrefab, position, Quaternion.identity);
		}
		if ((Object)(object)explosionSound != (Object)null && (Object)(object)audioSource != (Object)null)
		{
			audioSource.PlayOneShot(explosionSound, soundVolume);
			WalkieTalkie.TransmitOneShotAudio(audioSource, explosionSound, 1f);
		}
	}

	[ServerRpc]
	private void DestroyObjectServerRpc()
	{
		if ((Object)(object)((NetworkBehaviour)this).NetworkObject != (Object)null && ((NetworkBehaviour)this).NetworkObject.IsSpawned)
		{
			((NetworkBehaviour)this).NetworkObject.Despawn(true);
		}
		Object.Destroy((Object)(object)((Component)this).gameObject);
	}
}
public class WeaponProjectile : NetworkBehaviour
{
	[Header("Movement Settings")]
	[SerializeField]
	private float projectileSpeed = 20f;

	[SerializeField]
	private float lifetime = 5f;

	[SerializeField]
	private bool penetratesTargets;

	[Header("Collision Settings")]
	[SerializeField]
	private LayerMask collisionLayers;

	[Header("Damage Settings")]
	[SerializeField]
	private int damageAmount = 50;

	[Header("Audio")]
	[SerializeField]
	private AudioSource projectileAudio;

	[SerializeField]
	private AudioClip[] impactSounds;

	[Header("Impact Effects")]
	[Tooltip("Optional effect prefab that spawns when projectile is destroyed")]
	[SerializeField]
	private GameObject impactEffectPrefab;

	[SerializeField]
	private float effectDestroyDelay = 2f;

	[SerializeField]
	private bool attachEffectToSurface = true;

	[SerializeField]
	private Vector3 effectOffset = Vector3.zero;

	private float aliveTime;

	private bool hasHit;

	private Vector3 startPosition;

	private Quaternion startRotation;

	private bool initialized;

	public override void OnNetworkSpawn()
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: 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_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)
		((NetworkBehaviour)this).OnNetworkSpawn();
		initialized = true;
		startPosition = ((Component)this).transform.position;
		startRotation = ((Component)this).transform.rotation;
		if (((LayerMask)(ref collisionLayers)).value == 0)
		{
			collisionLayers = LayerMask.op_Implicit(LayerMask.GetMask(new string[5] { "Default", "Ragdolls", "Props", "InteractableObjects", "Enemies" }));
		}
		if ((Object)(object)projectileAudio == (Object)null)
		{
			projectileAudio = ((Component)this).gameObject.AddComponent<AudioSource>();
			projectileAudio.spatialBlend = 1f;
			projectileAudio.maxDistance = 20f;
			projectileAudio.rolloffMode = (AudioRolloffMode)1;
		}
	}

	private void Update()
	{
		if (initialized && ((NetworkBehaviour)this).IsSpawned)
		{
			MoveBullet();
			aliveTime += Time.deltaTime;
			if (aliveTime >= lifetime && ((NetworkBehaviour)this).IsServer)
			{
				DestroyProjectileClientRpc();
				((NetworkBehaviour)this).NetworkObject.Despawn(true);
			}
		}
	}

	private void MoveBullet()
	{
		//IL_0006: 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_001c: 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_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)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: 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_0045: 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_007c: 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)
		Vector3 val = ((Component)this).transform.forward * (projectileSpeed * Time.deltaTime);
		Vector3 position = ((Component)this).transform.position + val;
		RaycastHit hit = default(RaycastHit);
		if (Physics.Raycast(new Ray(((Component)this).transform.position, ((Component)this).transform.forward), ref hit, ((Vector3)(ref val)).magnitude, LayerMask.op_Implicit(collisionLayers), (QueryTriggerInteraction)2))
		{
			HandleCollision(hit);
			if (!penetratesTargets)
			{
				return;
			}
		}
		((Component)this).transform.position = position;
	}

	private void HandleCollision(RaycastHit hit)
	{
		//IL_003f: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: 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)
		if (hasHit && !penetratesTargets)
		{
			return;
		}
		bool flag = false;
		PlayerControllerB component = ((Component)((RaycastHit)(ref hit)).collider).GetComponent<PlayerControllerB>();
		if ((Object)(object)component != (Object)null)
		{
			if (((NetworkBehaviour)this).IsServer)
			{
				component.DamagePlayer(damageAmount, true, true, (CauseOfDeath)7, 0, false, default(Vector3));
			}
			flag = true;
		}
		EnemyAI val = ((Component)((RaycastHit)(ref hit)).collider).GetComponent<EnemyAI>();
		if ((Object)(object)val == (Object)null)
		{
			EnemyAICollisionDetect component2 = ((Component)((RaycastHit)(ref hit)).collider).GetComponent<EnemyAICollisionDetect>();
			if ((Object)(object)component2 != (Object)null && (Object)(object)component2.mainScript != (Object)null)
			{
				val = component2.mainScript;
			}
		}
		if ((Object)(object)val != (Object)null)
		{
			IHittable val2 = default(IHittable);
			if (((Component)val).TryGetComponent<IHittable>(ref val2))
			{
				val2.Hit(damageAmount, ((Component)this).transform.forward, (PlayerControllerB)null, true, -1);
			}
			else
			{
				val.HitEnemy(damageAmount, (PlayerControllerB)null, false, -1);
			}
			flag = true;
		}
		if (!flag && ((Component)((RaycastHit)(ref hit)).collider).gameObject.layer != LayerMask.NameToLayer("Ragdolls"))
		{
			flag = true;
		}
		if (flag)
		{
			PlayImpactSoundServerRpc();
			SpawnImpactEffectServerRpc(((RaycastHit)(ref hit)).point, ((RaycastHit)(ref hit)).normal);
			hasHit = true;
			if (!penetratesTargets && ((NetworkBehaviour)this).IsServer)
			{
				DestroyProjectileClientRpc();
				((NetworkBehaviour)this).NetworkObject.Despawn(true);
			}
		}
	}

	[ServerRpc(RequireOwnership = false)]
	private void SpawnImpactEffectServerRpc(Vector3 hitPosition, Vector3 hitNormal)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		SpawnImpactEffectClientRpc(hitPosition, hitNormal);
	}

	[ClientRpc]
	private void SpawnImpactEffectClientRpc(Vector3 hitPosition, Vector3 hitNormal)
	{
		//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_0018: 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_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: 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_0049: 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_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_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)impactEffectPrefab != (Object)null)
		{
			Vector3 val = hitPosition + hitNormal * 0.01f + effectOffset;
			GameObject val2 = Object.Instantiate<GameObject>(impactEffectPrefab, val, Quaternion.LookRotation(hitNormal));
			RaycastHit val3 = default(RaycastHit);
			if (attachEffectToSurface && Physics.Raycast(hitPosition + hitNormal * 0.1f, -hitNormal, ref val3, 0.2f) && !((Component)((RaycastHit)(ref val3)).collider).CompareTag("Player") && !((Component)((RaycastHit)(ref val3)).collider).CompareTag("Enemy") && ((Component)((RaycastHit)(ref val3)).collider).gameObject.layer != LayerMask.NameToLayer("Ragdoll"))
			{
				val2.transform.SetParent(((RaycastHit)(ref val3)).transform, true);
			}
			Object.Destroy((Object)(object)val2, effectDestroyDelay);
		}
	}

	[ServerRpc(RequireOwnership = false)]
	private void PlayImpactSoundServerRpc()
	{
		PlayImpactSoundClientRpc();
	}

	[ClientRpc]
	private void PlayImpactSoundClientRpc()
	{
		if ((Object)(object)projectileAudio != (Object)null && impactSounds != null && impactSounds.Length != 0)
		{
			int num = Random.Range(0, impactSounds.Length);
			projectileAudio.PlayOneShot(impactSounds[num]);
		}
	}

	[ClientRpc]
	private void DestroyProjectileClientRpc()
	{
		if ((Object)(object)((Component)this).gameObject != (Object)null)
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}
	}
}