Decompiled source of SCPWeapons v1.0.0

BepInEx/plugins/SCPWeapons/com.github.xuuxiaolan.scpweapons.dll

Decompiled 19 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using Dawn;
using Dawn.Utils;
using GameNetcodeStuff;
using Microsoft.CodeAnalysis;
using On;
using On.GameNetcodeStuff;
using Unity.Netcode;
using UnityEngine;
using com.github.xuuxiaolan.scpweapons.NetcodePatcher;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("com.github.xuuxiaolan.scpweapons")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+b3746da4e89449df61df621c68dbc3a39303d6aa")]
[assembly: AssemblyProduct("SCPWeapons")]
[assembly: AssemblyTitle("com.github.xuuxiaolan.scpweapons")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 SCPWeapons
{
	public class FrozenKnife : KnifeItem
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_HitEnemy <0>__GatherCharge;

			public static hook_IHittable_Hit <1>__EditDamageDealtToPlayer;
		}

		private Queue<GameObject> freezeEffects = new Queue<GameObject>();

		private NetworkVariable<float> charge = new NetworkVariable<float>(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)1);

		private static readonly int BatteryBlinkHash = Animator.StringToHash("blink");

		private Collider[] colliderHits = (Collider[])(object)new Collider[32];

		private List<EnemyAI> frozenEnemies = new List<EnemyAI>();

		[field: SerializeField]
		public GameObject FreezeEffect { get; private set; }

		public static void Init()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0030: 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_003b: Expected O, but got Unknown
			object obj = <>O.<0>__GatherCharge;
			if (obj == null)
			{
				hook_HitEnemy val = GatherCharge;
				<>O.<0>__GatherCharge = val;
				obj = (object)val;
			}
			EnemyAI.HitEnemy += (hook_HitEnemy)obj;
			object obj2 = <>O.<1>__EditDamageDealtToPlayer;
			if (obj2 == null)
			{
				hook_IHittable_Hit val2 = EditDamageDealtToPlayer;
				<>O.<1>__EditDamageDealtToPlayer = val2;
				obj2 = (object)val2;
			}
			PlayerControllerB.IHittable_Hit += (hook_IHittable_Hit)obj2;
		}

		private static bool EditDamageDealtToPlayer(orig_IHittable_Hit orig, PlayerControllerB self, int force, Vector3 hitDirection, PlayerControllerB playerWhoHit, bool playHitSFX, int hitID)
		{
			//IL_004b: 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)
			if (!self.AllowPlayerDeath())
			{
				return false;
			}
			if (hitID == 5 && (Object)(object)playerWhoHit != (Object)null && (Object)(object)playerWhoHit.currentlyHeldObjectServer != (Object)null && playerWhoHit.currentlyHeldObjectServer is FrozenKnife)
			{
				self.DamagePlayerFromOtherClientServerRpc(1, hitDirection, (int)playerWhoHit.playerClientId);
				return false;
			}
			return orig.Invoke(self, force, hitDirection, playerWhoHit, playHitSFX, hitID);
		}

		private static void GatherCharge(orig_HitEnemy orig, EnemyAI self, int force, PlayerControllerB playerWhoHit, bool playHitSFX, int hitID)
		{
			bool isEnemyDead = self.isEnemyDead;
			orig.Invoke(self, force, playerWhoHit, playHitSFX, hitID);
			if (!isEnemyDead && (Object)(object)playerWhoHit != (Object)null && (Object)(object)playerWhoHit.currentlyHeldObjectServer != (Object)null && playerWhoHit.currentlyHeldObjectServer is FrozenKnife frozenKnife && ((NetworkBehaviour)frozenKnife).IsOwner)
			{
				NetworkVariable<float> obj = frozenKnife.charge;
				obj.Value += 10f;
			}
		}

		public void Awake()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0020: 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_004d: 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)
			GameObject val = new GameObject("FreezeEffectHolder");
			((GrabbableObject)this).itemProperties.positionOffset = new Vector3(-0.2f, 0.22f, 0f);
			((GrabbableObject)this).itemProperties.toolTips = new string[1] { "Freeze Enemies : [ Q ]" };
			for (int i = 0; i < 32; i++)
			{
				GameObject val2 = Object.Instantiate<GameObject>(FreezeEffect, Vector3.zero, Quaternion.identity, val.transform);
				val2.SetActive(false);
				freezeEffects.Enqueue(val2);
			}
		}

		public override void ItemInteractLeftRight(bool right)
		{
			((GrabbableObject)this).ItemInteractLeftRight(right);
			if (!right && charge.Value >= 100f)
			{
				ActivateEventAndFreezeNearbyCreatures();
			}
		}

		public override void EquipItem()
		{
			((KnifeItem)this).EquipItem();
			((GrabbableObject)this).playerHeldBy.equippedUsableItemQE = true;
		}

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

		public override void LateUpdate()
		{
			((GrabbableObject)this).LateUpdate();
			if (!((Object)(object)((GrabbableObject)this).playerHeldBy == (Object)null) && ((GrabbableObject)this).isHeld && !((GrabbableObject)this).isPocketed && PlayerControllerBExtensions.IsLocalPlayer(((GrabbableObject)this).playerHeldBy))
			{
				HUDManager.Instance.batteryMeter.fillAmount = charge.Value / 131.5789f;
				((Component)HUDManager.Instance.batteryMeter).gameObject.SetActive(true);
				((Behaviour)HUDManager.Instance.batteryIcon).enabled = true;
				HUDManager.Instance.batteryBlinkUI.SetBool(BatteryBlinkHash, charge.Value >= 100f);
			}
		}

		private void ActivateEventAndFreezeNearbyCreatures()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			int count = Physics.OverlapSphereNonAlloc(((Component)((GrabbableObject)this).playerHeldBy).transform.position, 15f, colliderHits, MoreLayerMasks.PlayersAndEnemiesMask, (QueryTriggerInteraction)2);
			colliderHits = colliderHits.Take(count).ToArray();
			Collider[] array = colliderHits;
			PlayerControllerB val2 = default(PlayerControllerB);
			EnemyAICollisionDetect val3 = default(EnemyAICollisionDetect);
			foreach (Collider val in array)
			{
				if (((Component)val).TryGetComponent<PlayerControllerB>(ref val2))
				{
					if (!((Object)(object)val2 == (Object)(object)((GrabbableObject)this).playerHeldBy))
					{
						((MonoBehaviour)this).StartCoroutine(FreezePlayer(val2));
					}
				}
				else if (((Component)val).TryGetComponent<EnemyAICollisionDetect>(ref val3) && !frozenEnemies.Contains(val3.mainScript))
				{
					frozenEnemies.Add(val3.mainScript);
					((MonoBehaviour)this).StartCoroutine(FreezeEnemy(val3));
				}
			}
			frozenEnemies.Clear();
			if (((NetworkBehaviour)this).IsOwner)
			{
				charge.Value = 0f;
			}
		}

		private IEnumerator FreezePlayer(PlayerControllerB player)
		{
			GameObject obj = freezeEffects.Dequeue();
			obj.transform.position = ((Component)player).transform.position;
			obj.SetActive(true);
			float timeElapsed = 0f;
			while (timeElapsed < 10f && !player.isPlayerDead)
			{
				timeElapsed += Time.deltaTime;
				player.disableMoveInput = true;
				yield return null;
			}
			player.disableMoveInput = false;
			obj.GetComponent<ParticleSystem>().Stop(true);
			yield return (object)new WaitForSeconds(2f);
			obj.SetActive(false);
			freezeEffects.Enqueue(obj);
		}

		private IEnumerator FreezeEnemy(EnemyAICollisionDetect enemyAICollisionDetect)
		{
			GameObject obj = freezeEffects.Dequeue();
			obj.transform.position = ((Component)enemyAICollisionDetect).transform.position;
			obj.SetActive(true);
			float timeElapsed = 0f;
			while (timeElapsed < 10f && !enemyAICollisionDetect.mainScript.isEnemyDead)
			{
				timeElapsed += Time.deltaTime;
				if (((NetworkBehaviour)enemyAICollisionDetect.mainScript).IsOwner && enemyAICollisionDetect.mainScript.agent.isOnNavMesh)
				{
					enemyAICollisionDetect.mainScript.agent.isStopped = true;
				}
				yield return null;
			}
			obj.GetComponent<ParticleSystem>().Stop(true);
			if (((NetworkBehaviour)enemyAICollisionDetect.mainScript).IsOwner)
			{
				enemyAICollisionDetect.mainScript.agent.isStopped = false;
			}
			yield return (object)new WaitForSeconds(2f);
			obj.SetActive(false);
			freezeEffects.Enqueue(obj);
		}

		protected override void __initializeVariables()
		{
			if (charge == null)
			{
				throw new Exception("FrozenKnife.charge cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)charge).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)charge, "charge");
			((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)charge);
			((KnifeItem)this).__initializeVariables();
		}

		protected override void __initializeRpcs()
		{
			((KnifeItem)this).__initializeRpcs();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "FrozenKnife";
		}
	}
	public class InvincibleKatana : Shovel
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_HitShovel <0>__ModifyHitIfKatana;

			public static hook_IHittable_Hit <1>__EditDamageDealtToPlayer;

			public static hook_NextItemSlot <2>__StopFromSwitchingIfKatana;
		}

		private PlayerControllerB? heldTodayByPlayer;

		private float fakeHealth;

		private Coroutine? discardRoutine;

		public override void EquipItem()
		{
			((GrabbableObject)this).EquipItem();
			heldTodayByPlayer = ((GrabbableObject)this).playerHeldBy;
		}

		public override void Update()
		{
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			((GrabbableObject)this).Update();
			if (StartOfRound.Instance.inShipPhase)
			{
				heldTodayByPlayer = null;
			}
			else if (!((Object)(object)heldTodayByPlayer != (Object)(object)GameNetworkManager.Instance.localPlayerController))
			{
				HUDManager.Instance.UpdateHealthUI(Mathf.RoundToInt(fakeHealth), false);
				fakeHealth += 25f * Time.deltaTime;
				if (fakeHealth >= 100f)
				{
					fakeHealth = 0f;
				}
				GrabbableObject currentlyHeldObjectServer = GameNetworkManager.Instance.localPlayerController.currentlyHeldObjectServer;
				if ((Object)(object)currentlyHeldObjectServer != (Object)null && (Object)(object)currentlyHeldObjectServer.itemProperties != (Object)(object)((GrabbableObject)this).itemProperties && currentlyHeldObjectServer.itemProperties.isDefensiveWeapon && discardRoutine == null)
				{
					HUDManagerExtensions.DisplayTip(HUDManager.Instance, new HUDDisplayTip("Invincible Katana", "Holding the mightiest of weapons, you see no need to hold any others.", (AlertType)0));
					discardRoutine = ((MonoBehaviour)this).StartCoroutine(DiscardAfterHalfSecond());
				}
			}
		}

		private IEnumerator DiscardAfterHalfSecond()
		{
			yield return (object)new WaitForSeconds(0.5f);
			yield return (object)new WaitForEndOfFrame();
			if ((Object)(object)heldTodayByPlayer == (Object)null || (Object)(object)heldTodayByPlayer.currentlyHeldObjectServer == (Object)null || heldTodayByPlayer.currentlyHeldObjectServer is InvincibleKatana)
			{
				discardRoutine = null;
				yield break;
			}
			heldTodayByPlayer.DiscardHeldObject(false, (NetworkObject)null, default(Vector3), true);
			discardRoutine = null;
		}

		public static void Init()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0030: 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_003b: Expected O, but got Unknown
			//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_005b: Expected O, but got Unknown
			object obj = <>O.<0>__ModifyHitIfKatana;
			if (obj == null)
			{
				hook_HitShovel val = ModifyHitIfKatana;
				<>O.<0>__ModifyHitIfKatana = val;
				obj = (object)val;
			}
			Shovel.HitShovel += (hook_HitShovel)obj;
			object obj2 = <>O.<1>__EditDamageDealtToPlayer;
			if (obj2 == null)
			{
				hook_IHittable_Hit val2 = EditDamageDealtToPlayer;
				<>O.<1>__EditDamageDealtToPlayer = val2;
				obj2 = (object)val2;
			}
			PlayerControllerB.IHittable_Hit += (hook_IHittable_Hit)obj2;
			object obj3 = <>O.<2>__StopFromSwitchingIfKatana;
			if (obj3 == null)
			{
				hook_NextItemSlot val3 = StopFromSwitchingIfKatana;
				<>O.<2>__StopFromSwitchingIfKatana = val3;
				obj3 = (object)val3;
			}
			PlayerControllerB.NextItemSlot += (hook_NextItemSlot)obj3;
		}

		private static bool EditDamageDealtToPlayer(orig_IHittable_Hit orig, PlayerControllerB self, int force, Vector3 hitDirection, PlayerControllerB playerWhoHit, bool playHitSFX, int hitID)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			if (!self.AllowPlayerDeath())
			{
				return false;
			}
			if ((Object)(object)playerWhoHit != (Object)null && (Object)(object)playerWhoHit.currentlyHeldObjectServer != (Object)null && playerWhoHit.currentlyHeldObjectServer is InvincibleKatana && Random.Range(0f, 1f) <= 0.9f)
			{
				return false;
			}
			return orig.Invoke(self, force, hitDirection, playerWhoHit, playHitSFX, hitID);
		}

		private static int StopFromSwitchingIfKatana(orig_NextItemSlot orig, PlayerControllerB self, bool forward)
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			int num = -1;
			for (int i = 0; i < self.ItemSlots.Length; i++)
			{
				if (self.ItemSlots[i] is InvincibleKatana)
				{
					num = i;
					break;
				}
			}
			int num2 = orig.Invoke(self, forward);
			if (num != -1 && (Object)(object)self.ItemSlots[num2] != (Object)null && (Object)(object)self.ItemSlots[num] != (Object)null && self.ItemSlots[num2].itemProperties.isDefensiveWeapon && !(self.ItemSlots[num2] is InvincibleKatana))
			{
				HUDManagerExtensions.DisplayTip(HUDManager.Instance, new HUDDisplayTip("Invincible Katana", "You only want to use the finest of weapons.", (AlertType)0));
				return num;
			}
			return num2;
		}

		private static void ModifyHitIfKatana(orig_HitShovel orig, Shovel self, bool cancel)
		{
			if (self is InvincibleKatana)
			{
				if (Random.Range(0f, 1f) <= 0.9f)
				{
					self.shovelHitForce = 0;
				}
				else
				{
					self.shovelHitForce = 1;
				}
			}
			orig.Invoke(self, cancel);
		}

		protected override void __initializeVariables()
		{
			((Shovel)this).__initializeVariables();
		}

		protected override void __initializeRpcs()
		{
			((Shovel)this).__initializeRpcs();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "InvincibleKatana";
		}
	}
	[BepInPlugin("com.github.xuuxiaolan.scpweapons", "SCPWeapons", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class SCPWeapons : BaseUnityPlugin
	{
		internal static ManualLogSource Logger { get; private set; }

		internal static PersistentDataContainer PersistentData { get; private set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			InvincibleKatana.Init();
			FrozenKnife.Init();
			Logger.LogInfo((object)"com.github.xuuxiaolan.scpweapons v1.0.0 has loaded!");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "com.github.xuuxiaolan.scpweapons";

		public const string PLUGIN_NAME = "SCPWeapons";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace __GEN
{
	internal class NetworkVariableSerializationHelper
	{
		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeSerialization()
		{
			NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<float>();
			NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<float>();
		}
	}
}
namespace com.github.xuuxiaolan.scpweapons.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}