Decompiled source of XuMiscTools v1.3.0

XuMiscTools.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using DigitalRuby.ThunderAndLightning;
using GameNetcodeStuff;
using IL;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;
using XuMiscTools.Patches;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("XuXiaolan")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("The coolest mod ever made")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0+66483ba8c4e327e8c1ff5698170d1d834e4fcb38")]
[assembly: AssemblyProduct("XuMiscTools")]
[assembly: AssemblyTitle("com.github.xuxiaolan.xumisctools")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/XuuXiao/xumisctools")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
[BepInPlugin("com.github.xuxiaolan.xumisctools", "XuMiscTools", "1.2.0")]
public class Plugin : BaseUnityPlugin
{
	public static ManualLogSource Log;

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

	public const string PLUGIN_NAME = "XuMiscTools";

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

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

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

		[Space(2f)]
		[Header("Force Settings")]
		[Tooltip("The force direction of the damage.")]
		public ForceDirection forceDirection;

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

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

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

		[Space(2f)]
		[Header("Cause of Death")]
		[Tooltip("Cause of death displayed in ScanNode after death.")]
		public CauseOfDeath causeOfDeath;

		[Space(2f)]
		[Header("Trigger Settings")]
		[Tooltip("Whether to trigger for enemies.")]
		public bool triggerForEnemies;

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

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

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

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

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

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

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

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

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

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

		[Space(2f)]
		[Header("Death Prefab Settings")]
		[Tooltip("Prefab to spawn when the player dies.")]
		public GameObject? deathPrefabForPlayer;

		[Tooltip("Prefab to spawn when the enemy dies.")]
		public GameObject? deathPrefabForEnemy;

		private static float lastDamageTime = float.NegativeInfinity;

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

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

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

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

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

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

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

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

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

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

		private void ApplyDamageToPlayer(PlayerControllerB player)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = CalculateForceDirection(player, forceMagnitudeAfterDamage);
			Vector3 val2 = CalculateForceDirection(player, forceMagnitudeAfterDeath);
			player.DamagePlayer(damageToDealForPlayers, playDefaultPlayerDamageSFX, true, causeOfDeath, (int)deathAnimation, false, val2);
			PlayDamageSound(((Component)player).transform, playerClosestAudioSources.ContainsKey(player) ? playerClosestAudioSources[player] : null);
			if (!player.isPlayerDead)
			{
				player.externalForces += val;
			}
			else if ((Object)(object)deathPrefabForPlayer != (Object)null && (Object)(object)deathPrefabForPlayer.GetComponent<NetworkObject>() != (Object)null)
			{
				SpawnDeathPrefabServerRpc(((Component)player).transform.position, ((Component)player).transform.rotation, forPlayer: true);
			}
			else if ((Object)(object)deathPrefabForPlayer != (Object)null)
			{
				Object.Instantiate<GameObject>(deathPrefabForPlayer, ((Component)player).transform.position, ((Component)player).transform.rotation);
			}
		}

		private void ApplyDamageToEnemy(EnemyAI enemy)
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			enemy.HitEnemy(damageToDealForEnemies, (PlayerControllerB)null, false, -1);
			PlayDamageSound(((Component)enemy).transform, enemyClosestAudioSources.ContainsKey(enemy) ? enemyClosestAudioSources[enemy] : null);
			if (enemy.isEnemyDead)
			{
				if ((Object)(object)deathPrefabForEnemy != (Object)null && (Object)(object)deathPrefabForEnemy.GetComponent<NetworkObject>() != (Object)null)
				{
					SpawnDeathPrefabServerRpc(((Component)enemy).transform.position, ((Component)enemy).transform.rotation, forPlayer: false);
				}
				else if ((Object)(object)deathPrefabForEnemy != (Object)null)
				{
					Object.Instantiate<GameObject>(deathPrefabForEnemy, ((Component)enemy).transform.position, ((Component)enemy).transform.rotation);
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		private void SpawnDeathPrefabServerRpc(Vector3 position, Quaternion rotation, bool forPlayer)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (forPlayer)
			{
				Object.Instantiate<GameObject>(deathPrefabForPlayer, position, rotation);
				GameObject? obj = deathPrefabForPlayer;
				if (obj != null)
				{
					obj.GetComponent<NetworkObject>().Spawn(false);
				}
			}
			else
			{
				Object.Instantiate<GameObject>(deathPrefabForEnemy, position, rotation);
				GameObject? obj2 = deathPrefabForEnemy;
				if (obj2 != null)
				{
					obj2.GetComponent<NetworkObject>().Spawn(false);
				}
			}
		}

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

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

		private AudioSource GetClosestAudioSource(Transform targetTransform)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			AudioSource val = damageAudioSources[0];
			float num = Vector3.Distance(((Component)val).transform.position, targetTransform.position);
			foreach (AudioSource damageAudioSource in damageAudioSources)
			{
				float num2 = Vector3.Distance(((Component)damageAudioSource).transform.position, targetTransform.position);
				if (num2 < num)
				{
					val = damageAudioSource;
					num = num2;
				}
			}
			return val;
		}

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

		public static Transform? TryFindRoot(Transform child)
		{
			Transform val = child;
			while ((Object)(object)val != (Object)null)
			{
				if ((Object)(object)((Component)val).GetComponent<NetworkObject>() != (Object)null)
				{
					return val;
				}
				val = ((Component)val).transform.parent;
			}
			return null;
		}
	}
	public class LightningScript : MonoBehaviour
	{
		[Header("Sound/Audio Settings.")]
		[Tooltip("The volume of the lightning bolts, recommend to keep at 0.2 or lower.")]
		public float VolumeController = 0.2f;

		[Tooltip("Audio clip played when lightning strikes, if null, defaults to lightning sounds.")]
		public List<AudioClip>? LightningStrikeSound = new List<AudioClip>();

		[Space(2f)]
		[Header("Position and strike settings.")]
		[Tooltip("Whether you'd want the position of the bolts to be determined based on a range from the GameObject or a predefined list of positions.")]
		public bool UseGameObjectPosition = true;

		[Tooltip("Range of the lightning bolts being striken from GameObject position.")]
		public float BoltRangeFromGameObject = 10f;

		[Tooltip("If using predefined list of positions, this is for random-ness of the lightning bolt strike positions from said positions.")]
		public List<GameObject>? BoltPositions;

		[Tooltip("Interval cooldown between each lightning strike.")]
		public float StrikeInterval = 5f;

		[Space(2f)]
		[Header("Miscellanous settings.")]
		[Tooltip("Multiplier for the size of the glow's width.")]
		public float GlowWidthMultiplier = 1.5f;

		[Tooltip("The number of lightning bolts generated onto a spot.")]
		public int NumberOfBolts = 1;

		[Header("Duration of the lightning strike, split into a min and max duration.")]
		public float DurationMinimum = 0.6f;

		public float DurationMaximum = 1.2f;

		[Header("Length of the trunk of the lightning strike, split into a min and max length.")]
		public float TrunkMinimum = 0.6f;

		public float TrunkMaximum = 1.2f;

		[Header("Pre-lightning strike settings")]
		[Tooltip("Whether to play the pre-lightning strike effect, this delays when lightning strikes.")]
		public bool PlayPreLightningEffects = true;

		[Space(2f)]
		[Header("Explosion settings.")]
		[Tooltip("Range of the lethal killing explosion.")]
		public float KillRange = 1f;

		[Tooltip("Range of the non-lethal damage dealt to the player.")]
		public float DamageRange = 5f;

		[Tooltip("Damage dealt to the player when the lightning strikes.")]
		public int NonLethalDamage = 20;

		[Tooltip("Force from the explosion towards the player.")]
		public float PhysicsForce = 5f;

		[Tooltip("Whether to play the explosion effects.")]
		public bool PlayExplosionEffects = true;

		[Tooltip("Prefab to override the default explosion particle effect.")]
		public GameObject? OverridePrefab;

		[Tooltip("Whether lightning strikes through cars.")]
		public bool HitsThroughCar;

		private Random random = new Random();

		private StormyWeather stormy;

		private LightningBoltPrefabScript localLightningBoltPrefabScript;

		private AudioSource audioSource;

		public void OnEnable()
		{
			random = new Random(StartOfRound.Instance.randomMapSeed + 85);
			stormy = Object.FindObjectOfType<StormyWeather>(true);
			localLightningBoltPrefabScript = Object.Instantiate<LightningBoltPrefabScript>(stormy.targetedThunder);
			((Behaviour)localLightningBoltPrefabScript).enabled = true;
			audioSource = Object.Instantiate<AudioSource>(stormy.targetedStrikeAudio);
			if ((Object)(object)stormy == (Object)null)
			{
				Plugin.Log.LogWarning((object)"StormyWeather not found");
			}
			else if ((Object)(object)localLightningBoltPrefabScript == (Object)null)
			{
				Plugin.Log.LogWarning((object)"localLightningBoltPrefabScript not found");
			}
			else
			{
				((MonoBehaviour)this).StartCoroutine(SpawnLightningBoltCoroutine());
			}
		}

		private IEnumerator SpawnLightningBoltCoroutine()
		{
			while (true)
			{
				Vector3 strikePosition = DetermineStrikePosition();
				((MonoBehaviour)this).StartCoroutine(SpawnLightningBolt(strikePosition));
				yield return (object)new WaitForSeconds(Mathf.Clamp(StrikeInterval, 0f, 9999f));
			}
		}

		public IEnumerator SpawnLightningBolt(Vector3 strikePosition)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (PlayPreLightningEffects)
			{
				audioSource.clip = stormy.staticElectricityAudio;
				ParticleSystem staticElectricityParticle = stormy.staticElectricityParticle;
				ShapeModule shape = staticElectricityParticle.shape;
				((ShapeModule)(ref shape)).meshRenderer = null;
				((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0;
				((ShapeModule)(ref shape)).radius = 0.1f;
				audioSource.Play();
				yield return (object)new WaitForSeconds(audioSource.clip.length);
			}
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor((float)(random.NextDouble() * 64.0 - 32.0), 0f, (float)(random.NextDouble() * 64.0 - 32.0));
			Vector3 val2 = strikePosition + Vector3.up * 160f + val;
			Plugin.Log.LogInfo((object)$"{val2} -> {strikePosition}");
			((LightningBoltPrefabScriptBase)localLightningBoltPrefabScript).GlowWidthMultiplier = GlowWidthMultiplier;
			((LightningBoltPrefabScriptBase)localLightningBoltPrefabScript).DurationRange = new RangeOfFloats
			{
				Minimum = DurationMinimum,
				Maximum = DurationMaximum
			};
			((LightningBoltPrefabScriptBase)localLightningBoltPrefabScript).TrunkWidthRange = new RangeOfFloats
			{
				Minimum = TrunkMinimum,
				Maximum = TrunkMaximum
			};
			((LightningBoltScript)localLightningBoltPrefabScript).Camera = GameNetworkManager.Instance.localPlayerController.gameplayCamera;
			localLightningBoltPrefabScript.Source.transform.position = val2;
			localLightningBoltPrefabScript.Destination.transform.position = strikePosition;
			((LightningBoltPrefabScriptBase)localLightningBoltPrefabScript).AutomaticModeSeconds = 0.2f;
			((LightningBoltPrefabScriptBase)localLightningBoltPrefabScript).Generations = NumberOfBolts;
			((LightningBoltPrefabScriptBase)localLightningBoltPrefabScript).CreateLightningBoltsNow();
			((Component)audioSource).transform.position = strikePosition + Vector3.up * 0.5f;
			((Behaviour)audioSource).enabled = true;
			if (GameNetworkManager.Instance.localPlayerController.isInsideFactory)
			{
				audioSource.volume = 0f;
			}
			else
			{
				audioSource.volume = VolumeController;
			}
			if (LightningStrikeSound != null && LightningStrikeSound.Count > 0)
			{
				audioSource.clip = LightningStrikeSound[Random.Range(0, LightningStrikeSound.Count)];
			}
			stormy.PlayThunderEffects(strikePosition, audioSource);
			Landmine.SpawnExplosion(strikePosition, PlayExplosionEffects, KillRange, DamageRange, NonLethalDamage, PhysicsForce, OverridePrefab, HitsThroughCar);
		}

		public Vector3 DetermineStrikePosition()
		{
			//IL_0013: 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_0092: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			if (UseGameObjectPosition)
			{
				return RoundManager.Instance.GetRandomPositionInRadius(((Component)this).transform.position, 0f, BoltRangeFromGameObject, random);
			}
			if (BoltPositions != null && BoltPositions.Count > 0)
			{
				return RoundManager.Instance.GetRandomPositionInRadius(BoltPositions[random.Next(BoltPositions.Count)].transform.position, 0f, BoltRangeFromGameObject, random);
			}
			return ((Component)this).transform.position;
		}

		public void OnDisable()
		{
			((MonoBehaviour)this).StopAllCoroutines();
		}
	}
	[RequireComponent(typeof(AudioSource))]
	public class TeleportTrigger : NetworkBehaviour
	{
		public enum ForceDirection
		{
			Forward,
			Backward,
			Up,
			Down,
			Left,
			Right,
			Center
		}

		[Header("Teleport Settings")]
		[Tooltip("Teleport Triggers to teleport to.")]
		public List<TeleportTrigger> otherTriggers = new List<TeleportTrigger>();

		[Tooltip("OPTIONAL position to teleport to (uses the otherTrigger's forward vector if not set).")]
		public GameObject? positionForTeleport;

		[Space(2f)]
		[Header("Force Settings")]
		[Tooltip("The force direction of the damage.")]
		public ForceDirection forceDirection;

		[Tooltip("Strength of the directional force.")]
		public float forceMagnitude = 1f;

		[Tooltip("The force magnitude on THE PLAYER after the teleport.")]
		public float forceMagnitudeAfterTeleport;

		[Space(2f)]
		[Header("Trigger Settings")]
		[Tooltip("Whether to trigger for enemies.")]
		public bool triggerForEnemies;

		[Tooltip("Whether to trigger for players.")]
		public bool triggerForPlayers;

		[Space(2f)]
		[Header("Audio Settings")]
		[Tooltip("This object's own audiosource")]
		public AudioSource audioSource;

		[Tooltip("Whether to play sound at teleport position that enemies can hear.")]
		public bool soundAttractsDogs;

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

		private List<AudioSource> audioSources = new List<AudioSource>();

		private Random random = new Random();

		private InteractTrigger? interactTrigger;

		private void OnEnable()
		{
			foreach (TeleportTrigger otherTrigger in otherTriggers)
			{
				audioSources.Add(otherTrigger.audioSource);
			}
			random = new Random(StartOfRound.Instance.randomMapSeed + 85);
			((UnityEvent<PlayerControllerB>)(object)interactTrigger?.onInteract).AddListener((UnityAction<PlayerControllerB>)OnInteract);
		}

		public void OnInteract(PlayerControllerB player)
		{
			if (!((Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)(object)player))
			{
				TeleportPlayerServerRpc(Array.IndexOf(StartOfRound.Instance.allPlayerScripts, player));
			}
		}

		private void OnTriggerEnter(Collider other)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB player = default(PlayerControllerB);
			if (triggerForPlayers && ((Component)other).CompareTag("Player") && Object.op_Implicit((Object)(object)GameNetworkManager.Instance.localPlayerController) == ((Component)other).TryGetComponent<PlayerControllerB>(ref player))
			{
				TeleportPlayer(player);
			}
			else
			{
				if (!triggerForEnemies)
				{
					return;
				}
				Transform val = TryFindRoot(((Component)other).transform);
				EnemyAI val2 = default(EnemyAI);
				if ((Object)(object)val != (Object)null && ((Component)val).TryGetComponent<EnemyAI>(ref val2) && !val2.isEnemyDead)
				{
					int index = random.Next(0, teleportClips.Count);
					Vector3 val3 = CalculateForceDirection(forceMagnitude, index);
					Vector3 val4 = ((!((Object)(object)positionForTeleport != (Object)null)) ? (((Component)otherTriggers[index]).transform.position + val3) : (positionForTeleport.transform.position + val3));
					if (soundAttractsDogs)
					{
						RoundManager.Instance.PlayAudibleNoise(((Component)audioSources[index]).transform.position, audioSources[index].maxDistance, audioSources[index].volume, 0, false, 0);
					}
					RoundManager.PlayRandomClip(audioSources[index], teleportClips.ToArray(), true, audioSources[index].volume, 0, teleportClips.Count);
					val2.agent.Warp(RoundManager.Instance.GetRandomNavMeshPositionInRadius(val4, 2.5f, default(NavMeshHit)));
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void TeleportPlayerServerRpc(int playerIndex)
		{
			TeleportPlayerClientRpc(playerIndex);
		}

		[ClientRpc]
		public void TeleportPlayerClientRpc(int playerIndex)
		{
			TeleportPlayer(StartOfRound.Instance.allPlayerScripts[playerIndex]);
		}

		public void TeleportPlayer(PlayerControllerB player)
		{
			//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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_004a: 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_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			int index = random.Next(0, otherTriggers.Count);
			Vector3 val = CalculateForceDirection(forceMagnitude, index);
			if ((Object)(object)positionForTeleport != (Object)null)
			{
				((Component)player).transform.position = positionForTeleport.transform.position + val;
			}
			else
			{
				((Component)player).transform.position = val + ((Component)otherTriggers[index]).transform.position;
			}
			if (soundAttractsDogs)
			{
				RoundManager.Instance.PlayAudibleNoise(((Component)audioSources[index]).transform.position, audioSources[index].maxDistance, audioSources[index].volume, 0, false, 0);
			}
			audioSources[index].PlayOneShot(teleportClips[index], audioSources[index].volume);
			Vector3 val2 = CalculateForceDirection(forceMagnitudeAfterTeleport, index);
			player.externalForces += val2;
		}

		private Vector3 CalculateForceDirection(float baseForce, int index)
		{
			//IL_000d: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			TeleportTrigger teleportTrigger = otherTriggers[index];
			Vector3 val = Vector3.zero;
			if ((Object)(object)positionForTeleport != (Object)null)
			{
				return Vector3.zero;
			}
			switch (forceDirection)
			{
			case ForceDirection.Forward:
				val = ((Component)teleportTrigger).transform.forward;
				break;
			case ForceDirection.Backward:
				val = -((Component)teleportTrigger).transform.forward;
				break;
			case ForceDirection.Up:
				val = ((Component)teleportTrigger).transform.up;
				break;
			case ForceDirection.Down:
				val = -((Component)teleportTrigger).transform.up;
				break;
			case ForceDirection.Left:
				val = -((Component)teleportTrigger).transform.right;
				break;
			case ForceDirection.Right:
				val = ((Component)teleportTrigger).transform.right;
				break;
			case ForceDirection.Center:
				val = Vector3.zero;
				break;
			}
			return ((Vector3)(ref val)).normalized * baseForce;
		}

		public static Transform? TryFindRoot(Transform child)
		{
			Transform val = child;
			while ((Object)(object)val != (Object)null)
			{
				if ((Object)(object)((Component)val).GetComponent<NetworkObject>() != (Object)null)
				{
					return val;
				}
				val = ((Component)val).transform.parent;
			}
			return null;
		}
	}
}
namespace XuMiscTools.Patches
{
	public class RoundManagerPatches
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Manipulator <0>__ILHook_RoundManager_SpawnOutsideHazards;
		}

		internal static void Init()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			object obj = <>O.<0>__ILHook_RoundManager_SpawnOutsideHazards;
			if (obj == null)
			{
				Manipulator val = ILHook_RoundManager_SpawnOutsideHazards;
				<>O.<0>__ILHook_RoundManager_SpawnOutsideHazards = val;
				obj = (object)val;
			}
			RoundManager.SpawnOutsideHazards += (Manipulator)obj;
		}

		private static void ILHook_RoundManager_SpawnOutsideHazards(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<RoundManager>(x, "spawnDenialPoints"),
				(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, 18)
			}))
			{
				Plugin.Log.LogError((object)"[ILHook_RoundManager_SpawnOutsideHazards] Could not match first predicates!");
				return;
			}
			if (!val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[10]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<RoundManager>(x, "currentLevel"),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<SelectableLevel>(x, "spawnableOutsideObjects"),
				(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, 9),
				(Instruction x) => ILPatternMatchingExt.MatchLdelemRef(x),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<SpawnableOutsideObjectWithRarity>(x, "spawnableObject"),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<SpawnableOutsideObject>(x, "objectWidth"),
				(Instruction x) => ILPatternMatchingExt.MatchConvR4(x),
				(Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, 6f),
				(Instruction x) => ILPatternMatchingExt.MatchAdd(x)
			}))
			{
				Plugin.Log.LogError((object)"[ILHook_RoundManager_SpawnOutsideHazards] Could not match second predicates!");
				return;
			}
			ILCursor val2 = new ILCursor(val).GotoNext((MoveType)2, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, 6f),
				(Instruction x) => ILPatternMatchingExt.MatchAdd(x)
			});
			ILLabel val3 = il.DefineLabel(val.Next);
			ILLabel val4 = il.DefineLabel(val2.Next);
			val.Emit(OpCodes.Ldarg_0);
			val.Emit(OpCodes.Ldloc_S, (byte)18);
			val.EmitDelegate<Func<RoundManager, int, bool>>((Func<RoundManager, int, bool>)((RoundManager self, int n) => ((Object)self.spawnDenialPoints[n].gameObject).name.Contains("_XuPatch")));
			val.Emit(OpCodes.Brfalse_S, (object)val3);
			val.Emit(OpCodes.Ldarg_0);
			val.Emit(OpCodes.Ldloc_S, (byte)18);
			val.EmitDelegate<Func<RoundManager, int, float>>((Func<RoundManager, int, float>)((RoundManager self, int n) => self.spawnDenialPoints[n].transform.localScale.x));
			val.Emit(OpCodes.Br_S, (object)val4);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}