Decompiled source of SourceSauce v0.0.7

ThatTF2SourceSauce.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using GameNetcodeStuff;
using LethalLib.Extras;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ThatTF2SourceSauce")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ThatTF2SourceSauce")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e551068f-cb4d-401b-8b2b-b977b01893d5")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace ThatTF2SourceSauce
{
	public class AnimationAudioPlayer : MonoBehaviour
	{
		public AudioClip[] clips = (AudioClip[])(object)new AudioClip[1];

		public AudioSource[] sources = (AudioSource[])(object)new AudioSource[1];

		public AudioSource source = null;

		public void PlaySound(int clipID)
		{
			source.clip = clips[clipID];
			source.Play();
		}

		public void SetAudioSource(int id)
		{
			source = sources[id];
		}
	}
	public class AnimationCopier : MonoBehaviour
	{
		public Transform target;

		public Dictionary<string, Transform> bones = new Dictionary<string, Transform>();

		private void Start()
		{
			if ((Object)(object)target == (Object)null)
			{
				Debug.LogError((object)"Target is not assigned.");
			}
			else
			{
				PopulateBonesDictionary(((Component)this).transform, bones);
			}
		}

		private void LateUpdate()
		{
			//IL_007c: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)target == (Object)null || bones == null)
			{
				return;
			}
			foreach (KeyValuePair<string, Transform> bone in bones)
			{
				string key = bone.Key;
				Transform value = bone.Value;
				Transform val = FindBoneByName(target, key);
				if ((Object)(object)val != (Object)null && (Object)(object)value != (Object)null)
				{
					value.position = val.position;
					value.rotation = val.rotation;
					value.localScale = val.localScale;
				}
			}
		}

		private Transform FindBoneByName(Transform root, string name)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			Transform result = null;
			Stack<Transform> stack = new Stack<Transform>();
			stack.Push(root);
			while (stack.Count > 0)
			{
				Transform val = stack.Pop();
				if (((Object)val).name == name)
				{
					result = val;
					break;
				}
				foreach (Transform item2 in val)
				{
					Transform item = item2;
					stack.Push(item);
				}
			}
			return result;
		}

		private void PopulateBonesDictionary(Transform root, Dictionary<string, Transform> boneDict)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			foreach (Transform item in root)
			{
				Transform val = item;
				if (!boneDict.ContainsKey(((Object)val).name))
				{
					boneDict.Add(((Object)val).name, val);
				}
				PopulateBonesDictionary(val, boneDict);
			}
		}
	}
	public class SourceSauceOverseer : MonoBehaviour
	{
		public static SourceSauceOverseer Instance;

		public string path = string.Empty;

		private AssetBundle viewModelsBundle;

		public bool jobDone;

		public HUDManager hudManager;

		private bool isCoroutineRunning = false;

		public GameObject sentryPrefab;

		public GameObject stickyBomb;

		private void Awake()
		{
			Instance = this;
			Object.DontDestroyOnLoad((Object)(object)this);
		}

		private void Update()
		{
			if ((Object)(object)hudManager == (Object)null)
			{
				hudManager = Object.FindObjectOfType<HUDManager>();
				if ((Object)(object)hudManager == (Object)null)
				{
					jobDone = false;
				}
			}
			if (!jobDone && !isCoroutineRunning && (Object)(object)hudManager != (Object)null)
			{
				((MonoBehaviour)this).StartCoroutine(LoadAndExtractAssetBundles());
			}
		}

		private IEnumerator LoadAndExtractAssetBundles()
		{
			isCoroutineRunning = true;
			string assetBundlePath = Path.Combine(path, "tf_viewmodels");
			AssetBundleCreateRequest viewModelsBundleRequest = AssetBundle.LoadFromFileAsync(assetBundlePath);
			yield return viewModelsBundleRequest;
			viewModelsBundle = viewModelsBundleRequest.assetBundle;
			ExtractAssets();
			isCoroutineRunning = false;
		}

		private void ExtractAssets()
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)viewModelsBundle != (Object)null)
			{
				GameObject val = viewModelsBundle.LoadAsset<GameObject>("SillySourceStuff");
				if ((Object)(object)val != (Object)null && (Object)(object)GameNetworkManager.Instance != (Object)null && !jobDone)
				{
					PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
					GameObject val2 = Object.Instantiate<GameObject>(val, localPlayerController.playerModelArmsMetarig);
					WeaponViewmodelReplacer component = val2.GetComponent<WeaponViewmodelReplacer>();
					component.target = localPlayerController;
					val2.transform.localPosition = Vector3.zero;
					val2.transform.localRotation = Quaternion.Euler(90f, 0f, 0f);
					component.LCViewModel = ((Component)localPlayerController.playerModelArmsMetarig.parent.GetChild(0)).GetComponent<SkinnedMeshRenderer>();
					jobDone = true;
				}
			}
		}

		private void OnDestroy()
		{
			AssetBundle obj = viewModelsBundle;
			if (obj != null)
			{
				obj.Unload(false);
			}
		}
	}
	[BepInPlugin("ChubbzCrew.SourceSauce", "TF2 Source Sauce", "0.0.1")]
	[BepInProcess("Lethal Company.exe")]
	public class TF2SourceSauceHost : BaseUnityPlugin
	{
		public AssetBundle weaponBundle;

		public AssetBundle buildsBundle;

		public void OnDestroy()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loading TF2 Source Sauce");
			GameObject val = new GameObject("SourceSauceOverseer");
			SourceSauceOverseer sourceSauceOverseer = val.AddComponent<SourceSauceOverseer>();
			sourceSauceOverseer.path = Path.Combine(Paths.PluginPath, "ChubbzCrew-SourceSauce");
			string text = Path.Combine(sourceSauceOverseer.path, "tf2_weapons");
			weaponBundle = AssetBundle.LoadFromFile(text);
			sourceSauceOverseer.stickyBomb = weaponBundle.LoadAsset<GameObject>("Assets/TF2Weapons/Spawnables/Sticky.prefab");
			if ((Object)(object)sourceSauceOverseer.stickyBomb == (Object)null)
			{
				Debug.Log((object)"no fucking clue why, stickies aren't being loaded. ");
			}
			AnimationCurve spawnCurve = new AnimationCurve((Keyframe[])(object)new Keyframe[3]
			{
				new Keyframe(0f, 1f),
				new Keyframe(0.5f, 2f),
				new Keyframe(1f, 10f)
			});
			InitWeapon("sandman", "tf_Sandman", 4, (LevelTypes)(-1), spawnCurve);
			InitWeapon("atomizer", "tf_Atomizer", 3, (LevelTypes)(-1), spawnCurve);
			InitWeapon("atomizer_blue", "tf_BlueAtomizer", 3, (LevelTypes)(-1), spawnCurve);
			InitWeapon("wrench", "tf_Wrench", 5, (LevelTypes)(-1), spawnCurve);
			InitWeapon("aus_wrench", "tf_ausWrench", 5, (LevelTypes)(-1), spawnCurve);
			InitWeapon("pda", "tf_PDA", 5, (LevelTypes)(-1), spawnCurve);
			InitWeapon("toolbox", "tf_Toolbox", 0, (LevelTypes)(-1), null);
			InitWeapon("stickybomb", "tf_Stickybomb", 5, (LevelTypes)(-1), spawnCurve);
			InitWeapon("sapper", "tf_Sapper", 5, (LevelTypes)(-1), spawnCurve);
		}

		public void InitWeapon(string folder, string name, int rarity, LevelTypes levels, AnimationCurve spawnCurve)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			Item val = weaponBundle.LoadAsset<Item>("Assets/TF2Weapons/" + folder + "/" + name + ".asset");
			if (!((Object)(object)val != (Object)null))
			{
				return;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Loaded " + ((Object)val).name + " Asset"));
			NetworkPrefabs.RegisterNetworkPrefab(val.spawnPrefab);
			Utilities.FixMixerGroups(val.spawnPrefab);
			Items.RegisterScrap(val, rarity, levels);
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"Registered {((Object)val).name} as scrap with a rarity of {rarity}");
			if (spawnCurve != null)
			{
				SpawnableMapObjectDef val2 = ScriptableObject.CreateInstance<SpawnableMapObjectDef>();
				val2.spawnableMapObject = new SpawnableMapObject();
				val2.spawnableMapObject.prefabToSpawn = val.spawnPrefab;
				MapObjects.RegisterMapObject(val2, levels, (Func<SelectableLevel, AnimationCurve>)((SelectableLevel Level) => spawnCurve));
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Registered " + ((Object)val).name + "'s SpawnableMapObjectDef"));
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)(((Object)val).name + " won't spawn naturally"));
			}
		}
	}
	public static class PluginMetadata
	{
		public const string PluginId = "ChubbzCrew.SourceSauce";

		public const string PluginName = "TF2 Source Sauce";

		public const string PluginVersion = "0.0.1";
	}
	public class WeaponViewmodelReplacer : MonoBehaviour
	{
		public List<WeaponModel> weaponModels = new List<WeaponModel>();

		public WeaponModel currentModel;

		public PlayerControllerB target;

		public SkinnedMeshRenderer LCViewModel;

		public GrabbableObject lastItem;

		public GrabbableObject oldItem;

		public List<RuntimeAnimatorController> anims;

		public GrabbableObject[] objs = (GrabbableObject[])(object)new GrabbableObject[4];

		public void Start()
		{
			objs = (GrabbableObject[])(object)new GrabbableObject[target.ItemSlots.Length];
		}

		public void PopulateListHacky(string itemName, Animator viewModel, AnimationCopier weaponModel, int runtimeAnimRef)
		{
			WeaponModel item = new WeaponModel
			{
				name = itemName,
				viewModel = viewModel,
				weaponModel = weaponModel,
				animator = anims[runtimeAnimRef]
			};
			weaponModels.Add(item);
		}

		public void Update()
		{
			GrabbableObject[] array = objs;
			foreach (GrabbableObject item in array)
			{
				if (WeaponIsSpecial(item))
				{
					SetItemVisibility(item, !PlayerHasItem(item));
				}
			}
			objs = (GrabbableObject[])(object)new GrabbableObject[target.ItemSlots.Length];
			if (!((Object)(object)target == (Object)null) && target.ItemSlots != null && target.ItemSlots.Length > target.currentItemSlot)
			{
				GrabbableObject val = target.ItemSlots[target.currentItemSlot];
				if (!((Object)(object)val == (Object)(object)lastItem))
				{
					HandleItemSwap(val);
				}
			}
		}

		private void HandleItemSwap(GrabbableObject currentItem)
		{
			oldItem = lastItem;
			lastItem = currentItem;
			if (!WeaponIsSpecial(currentItem))
			{
				foreach (WeaponModel weaponModel in weaponModels)
				{
					DeactivateViewModel(weaponModel);
				}
				SetItemVisibility(currentItem, visible: true);
				SetItemVisibility(oldItem, !PlayerHasItem(oldItem));
				DeactivateCurrentModel();
				return;
			}
			if ((Object)(object)oldItem != (Object)null)
			{
				SetItemVisibility(oldItem, !PlayerHasItem(oldItem));
			}
			if ((Object)(object)lastItem != (Object)null)
			{
				SetItemVisibility(lastItem, !PlayerHasItem(lastItem));
				UpdateViewmodelForItem(currentItem);
			}
			else
			{
				DeactivateCurrentModel();
				SetItemVisibility(oldItem, !PlayerHasItem(oldItem));
			}
		}

		private void SetItemVisibility(GrabbableObject item, bool visible)
		{
			if (!((Object)(object)item == (Object)null))
			{
				Renderer[] componentsInChildren = ((Component)item).GetComponentsInChildren<Renderer>(true);
				Renderer[] array = componentsInChildren;
				foreach (Renderer val in array)
				{
					val.enabled = visible;
				}
			}
		}

		private void UpdateViewmodelForItem(GrabbableObject currentItem)
		{
			((Component)LCViewModel).gameObject.SetActive(true);
			if ((Object)(object)oldItem != (Object)null && !PlayerHasItem(oldItem))
			{
				SetItemVisibility(oldItem, visible: true);
			}
			if ((Object)(object)lastItem != (Object)null)
			{
				SetItemVisibility(lastItem, !PlayerHasItem(lastItem));
			}
			foreach (WeaponModel weaponModel in weaponModels)
			{
				DeactivateViewModel(weaponModel);
			}
			foreach (WeaponModel weaponModel2 in weaponModels)
			{
				if (((Object)currentItem.itemProperties).name == weaponModel2.name)
				{
					currentModel = weaponModel2;
					((Component)LCViewModel).gameObject.SetActive(false);
					((Component)weaponModel2.viewModel).gameObject.SetActive(true);
					((Component)weaponModel2.weaponModel).gameObject.SetActive(true);
					weaponModel2.weaponModel.target = ((Component)weaponModel2.viewModel).gameObject.transform;
					weaponModel2.viewModel.runtimeAnimatorController = weaponModel2.animator;
					if ((Object)(object)lastItem != (Object)null && !PlayerHasItem(lastItem))
					{
						SetItemVisibility(lastItem, visible: false);
					}
					return;
				}
			}
			DeactivateCurrentModel();
			((Component)LCViewModel).gameObject.SetActive(true);
		}

		public void DeactivateViewModel(WeaponModel model)
		{
			if (model != null)
			{
				((Component)model.viewModel).gameObject.SetActive(false);
				((Component)model.weaponModel).gameObject.SetActive(false);
			}
		}

		private void DeactivateCurrentModel()
		{
			DeactivateViewModel(currentModel);
			currentModel = null;
			((Component)LCViewModel).gameObject.SetActive(true);
		}

		public bool PlayerHasItem(GrabbableObject item)
		{
			GrabbableObject[] itemSlots = target.ItemSlots;
			foreach (GrabbableObject val in itemSlots)
			{
				if ((Object)(object)val == (Object)(object)item)
				{
					return true;
				}
			}
			return false;
		}

		public bool WeaponIsSpecial(GrabbableObject item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return false;
			}
			foreach (WeaponModel weaponModel in weaponModels)
			{
				if (weaponModel.name == ((Object)item.itemProperties).name)
				{
					return true;
				}
			}
			return false;
		}
	}
	[Serializable]
	public class WeaponModel
	{
		public string name;

		public Animator viewModel;

		public AnimationCopier weaponModel;

		public RuntimeAnimatorController animator;
	}
}
namespace ThatTF2SourceSauce.EngieBuilds
{
	public class Toolbox : GrabbableObject
	{
		public enum ToolboxType
		{
			Sentry,
			Dispenser,
			Teleporter1,
			Teleporter2
		}

		public uint level;

		public uint health;

		public ToolboxType Type { get; set; }

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
		}
	}
	public class BuildBase : NetworkBehaviour, IHittable
	{
		public uint level;

		public GameObject Level1Model;

		public GameObject Level2Model;

		public GameObject Level3Model;

		public virtual void LateUpdate()
		{
			Level1Model.SetActive(level == 0);
			Level2Model.SetActive(level == 1);
			Level3Model.SetActive(level == 2);
		}

		public bool Hit(int force, Vector3 hitDirection, PlayerControllerB playerWhoHit = null, bool playHitSFX = false, int hitID = -1)
		{
			return false;
		}
	}
	public class SentryGun : BuildBase
	{
		public Animator currentAnimator;

		public Transform gunPivotYaw;

		public Transform gunPivotPitch;

		public Vector2 viewAngle;

		public MeshCollider fieldOfView;
	}
}
namespace ThatTF2SourceSauce.Weapons
{
	public class PDAItem : GrabbableObject
	{
		public override void Update()
		{
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			if (base.currentUseCooldown >= 0f)
			{
				base.currentUseCooldown -= Time.deltaTime;
			}
			if (((NetworkBehaviour)this).IsOwner)
			{
				if (base.isBeingUsed && base.itemProperties.requiresBattery)
				{
					if (base.insertedBattery.charge > 0f)
					{
						if (!base.itemProperties.itemIsTrigger)
						{
							Battery insertedBattery = base.insertedBattery;
							insertedBattery.charge -= Time.deltaTime / base.itemProperties.batteryUsage;
						}
					}
					else if (!base.insertedBattery.empty)
					{
						base.insertedBattery.empty = true;
						if (base.isBeingUsed)
						{
							Debug.Log((object)"Use up batteries local");
							base.isBeingUsed = false;
							((GrabbableObject)this).UseUpBatteries();
							base.isSendingItemRPC++;
							((GrabbableObject)this).UseUpItemBatteriesServerRpc();
						}
					}
				}
				if (!base.wasOwnerLastFrame)
				{
					base.wasOwnerLastFrame = true;
				}
			}
			else if (base.wasOwnerLastFrame)
			{
				base.wasOwnerLastFrame = false;
			}
			if (base.isHeld || !((Object)(object)base.parentObject == (Object)null))
			{
				return;
			}
			if (base.fallTime < 1f)
			{
				base.reachedFloorTarget = false;
				((GrabbableObject)this).FallWithCurve();
				if (((Component)this).transform.localPosition.y - base.targetFloorPosition.y < 0.1f && !base.hasHitGround)
				{
					((GrabbableObject)this).PlayDropSFX();
					((GrabbableObject)this).OnHitGround();
				}
				return;
			}
			if (!base.reachedFloorTarget)
			{
				base.reachedFloorTarget = true;
				if (base.floorYRot == -1)
				{
					((Component)this).transform.rotation = Quaternion.Euler(base.itemProperties.restingRotation.x, ((Component)this).transform.eulerAngles.y, base.itemProperties.restingRotation.z);
				}
				else
				{
					((Component)this).transform.rotation = Quaternion.Euler(base.itemProperties.restingRotation.x, (float)(base.floorYRot + base.itemProperties.floorYOffset) + 90f, base.itemProperties.restingRotation.z);
				}
			}
			((Component)this).transform.localPosition = base.targetFloorPosition;
		}
	}
	public class MeleeGeneric : GrabbableObject
	{
		public float swingSpeed = 1f;

		public float swingDelay = 0.2f;

		public int hitForce = 1;

		public float attackDistance = 2f;

		public AudioClip swingSound;

		public AudioClip hitSound;

		public AudioSource meleeAudio;

		public bool isHoldingButton;

		private bool isSwinging = false;

		private Coroutine swingCoroutine;

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			isHoldingButton = buttonDown;
			if (!((Object)(object)base.playerHeldBy == (Object)null) && !isSwinging && buttonDown)
			{
				if (swingCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(swingCoroutine);
				}
				swingCoroutine = ((MonoBehaviour)this).StartCoroutine(SwingWeapon());
			}
		}

		private IEnumerator SwingWeapon()
		{
			while (isHoldingButton)
			{
				isSwinging = true;
				base.playerHeldBy.activatingItem = true;
				PlayRandomSwingAnim();
				SwingWeaponServerRpc();
				yield return (object)new WaitForSeconds(swingDelay);
				meleeAudio.PlayOneShot(swingSound);
				ApplyHit();
				yield return (object)new WaitForSeconds(swingSpeed - swingDelay);
				isSwinging = false;
				base.playerHeldBy.activatingItem = false;
			}
		}

		private void ApplyHit()
		{
			//IL_0011: 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_004a: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit[] array = Physics.SphereCastAll(((Component)base.playerHeldBy.gameplayCamera).transform.position, 0.5f, ((Component)base.playerHeldBy.gameplayCamera).transform.forward, attackDistance);
			bool flag = false;
			RaycastHit[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				RaycastHit val = array2[i];
				IHittable component = ((Component)((RaycastHit)(ref val)).collider).GetComponent<IHittable>();
				if (component != null && (Object)(object)((RaycastHit)(ref val)).transform != (Object)(object)((Component)base.playerHeldBy).transform)
				{
					component.Hit(hitForce, ((Component)base.playerHeldBy.gameplayCamera).transform.forward, base.playerHeldBy, true, 1);
					if (!flag)
					{
						flag = true;
						meleeAudio.PlayOneShot(hitSound);
						HitWeaponServerRpc();
					}
				}
			}
		}

		public override void DiscardItem()
		{
			if ((Object)(object)base.playerHeldBy != (Object)null)
			{
				base.playerHeldBy.activatingItem = false;
			}
			((GrabbableObject)this).DiscardItem();
		}

		[ServerRpc]
		private void SwingWeaponServerRpc()
		{
			if (((NetworkBehaviour)this).IsServer)
			{
				SwingWeaponClientRpc();
			}
		}

		[ClientRpc]
		private void SwingWeaponClientRpc()
		{
			if (!((NetworkBehaviour)this).IsOwner)
			{
				meleeAudio.PlayOneShot(swingSound);
			}
		}

		[ServerRpc]
		private void HitWeaponServerRpc()
		{
			if (((NetworkBehaviour)this).IsServer)
			{
				HitWeaponClientRpc();
			}
		}

		[ClientRpc]
		private void HitWeaponClientRpc()
		{
			if (!((NetworkBehaviour)this).IsOwner)
			{
				meleeAudio.PlayOneShot(hitSound);
			}
		}

		public void PlayRandomSwingAnim()
		{
			if (!((Object)(object)base.playerHeldBy != (Object)(object)GameNetworkManager.Instance.localPlayerController) || !((Object)(object)((Component)base.playerHeldBy).GetComponentInChildren<WeaponViewmodelReplacer>() != (Object)null))
			{
				int num = Random.Range(0, 3);
				((Component)base.playerHeldBy).GetComponentInChildren<WeaponViewmodelReplacer>().currentModel.viewModel.SetTrigger("Swing" + num);
			}
		}
	}
	public class ProjectileWeaponGeneric : GrabbableObject
	{
		public List<GameObject> projectiles;

		public byte maxProjectiles;

		public float fireRate;

		public AudioClip fireSound;

		public AudioSource audio;

		public bool isHoldingButton;

		private bool isFiring = false;

		private Coroutine fireCoroutine;

		private WeaponViewmodelReplacer view;

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			if (!Object.op_Implicit((Object)(object)view) && (Object)(object)base.playerHeldBy == (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				view = ((Component)base.playerHeldBy).GetComponentInChildren<WeaponViewmodelReplacer>();
			}
			isHoldingButton = buttonDown;
			if (!((Object)(object)base.playerHeldBy == (Object)null) && !isFiring && buttonDown)
			{
				if (fireCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(fireCoroutine);
				}
				fireCoroutine = ((MonoBehaviour)this).StartCoroutine(FireWeapon());
			}
		}

		private IEnumerator FireWeapon()
		{
			while (isHoldingButton)
			{
				isFiring = true;
				if (base.insertedBattery.charge > 0f)
				{
					base.playerHeldBy.activatingItem = true;
					PlayFireAnim();
					audio.PlayOneShot(fireSound);
					FireProjectile();
					base.insertedBattery.charge = Mathf.Clamp(base.insertedBattery.charge - base.itemProperties.batteryUsage, 0f, 1f);
					yield return (object)new WaitForSeconds(fireRate);
				}
				else
				{
					PlayFireAnim();
					yield return (object)new WaitForSeconds(fireRate);
				}
				isFiring = false;
				base.playerHeldBy.activatingItem = false;
			}
		}

		public void PlayFireAnim()
		{
			if (!((Object)(object)view == (Object)null) && view.currentModel != null)
			{
				view.currentModel.viewModel.SetTrigger("Fire");
			}
		}

		private void FireProjectile()
		{
		}

		public override void DiscardItem()
		{
			if ((Object)(object)base.playerHeldBy != (Object)null)
			{
				base.playerHeldBy.activatingItem = false;
			}
			((GrabbableObject)this).DiscardItem();
		}
	}
	public class SapperItem : GrabbableObject
	{
		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			if (buttonDown)
			{
				PlaceSapperServerRPC();
			}
		}

		[ServerRpc]
		private void PlaceSapperServerRPC()
		{
			if (((NetworkBehaviour)this).IsServer)
			{
				PlaceSapperClientRPC();
			}
		}

		[ClientRpc]
		private void PlaceSapperClientRPC()
		{
			//IL_0007: 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)
			Landmine.SpawnExplosion(((Component)this).transform.position + Vector3.up, true, 5.7f, 6f, 50, 0f, (GameObject)null, false);
		}
	}
}
namespace ThatTF2SourceSauce.Spawnables
{
	internal class SapperObject
	{
	}
	public class Stickybomb : NetworkBehaviour
	{
		public Rigidbody rb;

		private NetworkVariable<Vector3> networkPosition = new NetworkVariable<Vector3>(default(Vector3), (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		private NetworkVariable<Vector3> networkVelocity = new NetworkVariable<Vector3>(default(Vector3), (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		private float syncRate = 0.1f;

		private float lastSyncTime;

		public void Awake()
		{
			rb = ((Component)this).GetComponent<Rigidbody>();
		}

		public void OnCollisionEnter(Collision collision)
		{
			if (!((Object)(object)rb == (Object)null))
			{
				rb.constraints = (RigidbodyConstraints)126;
				((Component)this).transform.parent = collision.transform;
			}
		}

		private void FixedUpdate()
		{
			//IL_0089: 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_004b: 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)
			if (!Object.op_Implicit((Object)(object)((NetworkBehaviour)this).NetworkManager))
			{
				return;
			}
			if (((NetworkBehaviour)this).IsServer)
			{
				if (Time.time - lastSyncTime >= syncRate)
				{
					networkPosition.Value = rb.position;
					networkVelocity.Value = rb.velocity;
					lastSyncTime = Time.time;
				}
			}
			else
			{
				rb.position = networkPosition.Value;
				rb.velocity = networkVelocity.Value;
			}
		}
	}
}