Decompiled source of MCWitchMod v1.0.0

Witch.dll

Decompiled 13 hours 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.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using REPOLib.Modules;
using UnityEngine;
using UnityEngine.Events;

[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("Luca")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Witch enemy behaviour for R.E.P.O.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+e12179f370d51531a479d8ec5f1a80c099af6e5b")]
[assembly: AssemblyProduct("Witch")]
[assembly: AssemblyTitle("Witch")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Witch
{
	public class LandingCircle : MonoBehaviour
	{
		private LineRenderer _line;

		private float _lifetime;

		private float _elapsed;

		private Color _color;

		public static LandingCircle Create(Vector3 center, float radius, Color color, float lifetime)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0013: 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)
			GameObject val = new GameObject("LandingCircle");
			LandingCircle landingCircle = val.AddComponent<LandingCircle>();
			landingCircle.Initialize(center, radius, color, lifetime);
			return landingCircle;
		}

		private void Initialize(Vector3 center, float radius, Color color, float lifetime)
		{
			//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)
			//IL_006b: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			//IL_00c1: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: 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)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			_color = color;
			_lifetime = lifetime;
			_line = ((Component)this).gameObject.AddComponent<LineRenderer>();
			_line.useWorldSpace = true;
			_line.loop = true;
			_line.positionCount = 48;
			_line.startWidth = 0.08f;
			_line.endWidth = 0.08f;
			_line.startColor = color;
			_line.endColor = color;
			Shader val = Shader.Find("Sprites/Default");
			if ((Object)(object)val == (Object)null)
			{
				val = Shader.Find("Unlit/Color");
			}
			if ((Object)(object)val != (Object)null)
			{
				((Renderer)_line).material = new Material(val);
				((Renderer)_line).material.color = color;
			}
			for (int i = 0; i < 48; i++)
			{
				float num = (float)i * MathF.PI * 2f / 48f;
				Vector3 val2 = center + new Vector3(Mathf.Cos(num) * radius, 0.05f, Mathf.Sin(num) * radius);
				_line.SetPosition(i, val2);
			}
		}

		private void Update()
		{
			//IL_0061: 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_0075: 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)
			_elapsed += Time.deltaTime;
			if (_elapsed >= _lifetime)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			float num = _lifetime - _elapsed;
			if (num < 1f)
			{
				float a = (Mathf.Sin(_elapsed * 20f) + 1f) * 0.5f;
				Color color = _color;
				color.a = a;
				_line.startColor = color;
				_line.endColor = color;
			}
		}
	}
	[BepInPlugin("com.luca.witch", "Witch", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInProcess("REPO.exe")]
	public sealed class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		private Harmony _harmony;

		internal static ConfigEntry<int> MaxHealth;

		internal static ConfigEntry<int> HealAmount;

		internal static ConfigEntry<float> HealCooldown;

		internal static ConfigEntry<float> AttackCooldown;

		internal static ConfigEntry<float> AttackRange;

		internal static ConfigEntry<float> ThrowSpeed;

		internal static ConfigEntry<float> HealthPackDropChance;

		internal static ConfigEntry<float> PoisonChance;

		private void Awake()
		{
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			MaxHealth = ((BaseUnityPlugin)this).Config.Bind<int>("Witch", "MaxHealth", 250, "女巫最大生命值");
			HealAmount = ((BaseUnityPlugin)this).Config.Bind<int>("Witch", "HealAmount", 60, "每次回血量");
			HealCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Witch", "HealCooldown", 8f, "回血间隔(秒)");
			AttackCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Witch", "AttackCooldown", 4f, "攻击冷却(秒)");
			AttackRange = ((BaseUnityPlugin)this).Config.Bind<float>("Witch", "AttackRange", 8f, "攻击/索敌范围(米)");
			ThrowSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Witch", "ThrowSpeed", 8f, "药水初速度(m/s)");
			HealthPackDropChance = ((BaseUnityPlugin)this).Config.Bind<float>("Witch", "HealthPackDropChance", 0.3f, "医疗包掉落爆率(0.3=30%,1=100%)");
			PoisonChance = ((BaseUnityPlugin)this).Config.Bind<float>("Witch", "PoisonChance", 0.5f, "毒药水概率(0.5=1:1,0=全伤害,1=全毒)");
			_harmony = new Harmony("com.luca.witch");
			_harmony.PatchAll();
			Log.LogInfo((object)"Witch behaviour plugin loaded.");
		}
	}
	public sealed class WitchBehaviour : MonoBehaviour
	{
		private enum SoundType
		{
			Notice,
			Ambient,
			Death,
			Drink,
			Hurt,
			Throw
		}

		public const float WarnDuration = 1f;

		public const float LandingRadius = 1.2f;

		[SerializeField]
		private GameObject potionPrefab;

		[SerializeField]
		private Transform throwOrigin;

		[SerializeField]
		private GameObject healPotionPrefab;

		[SerializeField]
		private Transform healOrigin;

		[SerializeField]
		private GameObject healthPackDrop;

		[SerializeField]
		private Sound soundNotice;

		[SerializeField]
		private Sound soundAmbient;

		[SerializeField]
		private Sound soundDeath;

		[SerializeField]
		private Sound soundDrink;

		[SerializeField]
		private Sound soundHurt;

		[SerializeField]
		private Sound soundThrow;

		private Enemy _enemy;

		private EnemyHealth _health;

		private EnemyBombThrower _bombThrower;

		private float _attackTimer;

		private float _healTimer;

		private float _ambientTimer;

		private float _footstepTimer;

		private bool _hasNoticedPlayer;

		private PrefabRef _potionNetworkRef;

		private PrefabRef _healthPackNetworkRef;

		private PhotonView _photonView;

		private static readonly Color LandingDamageColor = new Color(1f, 0.35f, 0.35f, 1f);

		private static readonly Color LandingPoisonColor = new Color(0.45f, 0.85f, 0.45f, 1f);

		private void Start()
		{
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Expected O, but got Unknown
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected O, but got Unknown
			_enemy = ((Component)this).GetComponent<Enemy>() ?? ((Component)this).GetComponentInParent<Enemy>();
			_health = _enemy?.Health ?? ((Component)this).GetComponent<EnemyHealth>();
			_bombThrower = ((Component)this).GetComponent<EnemyBombThrower>();
			_photonView = ((Component)this).GetComponent<PhotonView>();
			if ((Object)(object)_enemy == (Object)null || (Object)(object)_health == (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"WitchBehaviour requires Enemy and EnemyHealth on the same or parent object.");
				}
				((Behaviour)this).enabled = false;
				return;
			}
			_health.health = Plugin.MaxHealth.Value;
			_health.OnSpawn();
			_healTimer = Plugin.HealCooldown.Value;
			EnemyHealth health = _health;
			if (health.onHurt == null)
			{
				health.onHurt = new UnityEvent();
			}
			_health.onHurt.AddListener(new UnityAction(OnHurtSound));
			PhotonTransformView[] componentsInChildren = ((Component)this).GetComponentsInChildren<PhotonTransformView>(true);
			PhotonTransformView[] array = componentsInChildren;
			foreach (PhotonTransformView val in array)
			{
				FieldInfo field = typeof(PhotonTransformView).GetField("m_PositionModel", BindingFlags.Instance | BindingFlags.NonPublic);
				FieldInfo field2 = typeof(PhotonTransformView).GetField("m_RotationModel", BindingFlags.Instance | BindingFlags.NonPublic);
				object obj = ((field != null) ? field.GetValue(val) : null);
				object obj2 = ((field2 != null) ? field2.GetValue(val) : null);
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)$"[Witch] PTV on '{((Object)((Component)val).gameObject).name}': positionModel={obj != null}, rotationModel={obj2 != null}, photonView={(Object)(object)((MonoBehaviourPun)val).photonView != (Object)null}, isMine={(Object)(object)((MonoBehaviourPun)val).photonView != (Object)null && ((MonoBehaviourPun)val).photonView.IsMine}");
				}
			}
			if ((Object)(object)potionPrefab != (Object)null)
			{
				_potionNetworkRef = NetworkPrefabs.RegisterNetworkPrefab(potionPrefab);
			}
			if ((Object)(object)healthPackDrop != (Object)null)
			{
				_healthPackNetworkRef = NetworkPrefabs.RegisterNetworkPrefab(healthPackDrop);
			}
			ManualLogSource log3 = Plugin.Log;
			if (log3 != null)
			{
				log3.LogInfo((object)$"WitchBehaviour initialized. Health = {_health.health}");
			}
		}

		private void OnDestroy()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			if ((Object)(object)_health != (Object)null && _health.onHurt != null)
			{
				_health.onHurt.RemoveListener(new UnityAction(OnHurtSound));
			}
		}

		private void Update()
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer() || (Object)(object)_enemy == (Object)null || (Object)(object)_health == (Object)null)
			{
				return;
			}
			UpdateAmbient();
			UpdateFootsteps();
			if (_enemy.IsStunned())
			{
				_healTimer = Plugin.HealCooldown.Value;
				return;
			}
			if (_attackTimer > 0f)
			{
				_attackTimer -= Time.deltaTime;
			}
			if (_attackTimer <= 0f)
			{
				PlayerAvatar val = FindNearestTarget();
				if ((Object)(object)val != (Object)null)
				{
					if (!_hasNoticedPlayer)
					{
						_hasNoticedPlayer = true;
						PlayWitchSound(SoundType.Notice);
					}
					_attackTimer = Plugin.AttackCooldown.Value;
					((MonoBehaviour)this).StartCoroutine(ThrowPotionRoutine(val));
				}
			}
			_healTimer -= Time.deltaTime;
			if (_healTimer <= 0f)
			{
				_healTimer = Plugin.HealCooldown.Value;
				if (_health.healthCurrent < Plugin.MaxHealth.Value)
				{
					TryHeal();
				}
			}
		}

		private void UpdateAmbient()
		{
			if (soundAmbient != null)
			{
				_ambientTimer -= Time.deltaTime;
				if (_ambientTimer <= 0f)
				{
					_ambientTimer = Random.Range(3f, 6f);
					PlayWitchSound(SoundType.Ambient);
				}
			}
		}

		private void UpdateFootsteps()
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_bombThrower == (Object)null || (Object)(object)_bombThrower.anim == (Object)null || !((Object)(object)_enemy.Rigidbody != (Object)null) || !((Object)(object)_enemy.Rigidbody.rb != (Object)null))
			{
				return;
			}
			Vector3 velocity = _enemy.Rigidbody.rb.velocity;
			if (!(((Vector3)(ref velocity)).magnitude > 0.5f))
			{
				return;
			}
			_footstepTimer -= Time.deltaTime;
			if (_footstepTimer <= 0f)
			{
				_footstepTimer = Random.Range(0.35f, 0.5f);
				if (_bombThrower.anim.soundFootstepBootLight != null)
				{
					_bombThrower.anim.soundFootstepBootLight.Play(((Component)this).transform.position, 1f, 1f, 1f, 1f);
				}
			}
		}

		private void OnHurtSound()
		{
			PlayWitchSound(SoundType.Hurt);
		}

		private void PlayWitchSound(SoundType type)
		{
			if (SemiFunc.IsMultiplayer() && (Object)(object)_photonView != (Object)null)
			{
				_photonView.RPC("PlaySoundRPC", (RpcTarget)0, new object[1] { (int)type });
			}
			else
			{
				PlaySoundRPC((int)type);
			}
		}

		[PunRPC]
		public void PlaySoundRPC(int type)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			switch ((SoundType)type)
			{
			case SoundType.Notice:
			{
				Sound obj4 = soundNotice;
				if (obj4 != null)
				{
					obj4.Play(((Component)this).transform.position, 1f, 1f, 1f, 1f);
				}
				break;
			}
			case SoundType.Ambient:
			{
				Sound obj6 = soundAmbient;
				if (obj6 != null)
				{
					obj6.Play(((Component)this).transform.position, 1f, 1f, 1f, 1f);
				}
				break;
			}
			case SoundType.Death:
			{
				Sound obj2 = soundDeath;
				if (obj2 != null)
				{
					obj2.Play(((Component)this).transform.position, 1f, 1f, 1f, 1f);
				}
				break;
			}
			case SoundType.Drink:
			{
				Sound obj5 = soundDrink;
				if (obj5 != null)
				{
					obj5.Play(((Component)this).transform.position, 1f, 1f, 1f, 1f);
				}
				break;
			}
			case SoundType.Hurt:
			{
				Sound obj3 = soundHurt;
				if (obj3 != null)
				{
					obj3.Play(((Component)this).transform.position, 1f, 1f, 1f, 1f);
				}
				break;
			}
			case SoundType.Throw:
			{
				Sound obj = soundThrow;
				if (obj != null)
				{
					obj.Play(((Component)this).transform.position, 1f, 1f, 1f, 1f);
				}
				break;
			}
			}
		}

		[PunRPC]
		public void ShowLandingCircleRPC(Vector3 pos, int type)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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)
			Color color = ((type == 0) ? LandingDamageColor : LandingPoisonColor);
			LandingCircle.Create(pos, 1.2f, color, 3f);
		}

		private IEnumerator ThrowPotionRoutine(PlayerAvatar target)
		{
			FacePlayer(target);
			float waitTime = 0f;
			while (waitTime < 1f && !IsFacingTarget(target))
			{
				waitTime += Time.deltaTime;
				yield return null;
			}
			if (!((Object)(object)target == (Object)null) && !target.deadSet && !target.isDisabled && !((Object)(object)_enemy == (Object)null) && !_enemy.IsStunned())
			{
				WitchPotionProjectile.PotionType type = ((Random.value < Plugin.PoisonChance.Value) ? WitchPotionProjectile.PotionType.Poison : WitchPotionProjectile.PotionType.Damage);
				Vector3 startPos = (((Object)(object)throwOrigin != (Object)null) ? throwOrigin.position : (((Component)this).transform.position + Vector3.up * 1.5f));
				Vector3 velocity = CalculateThrowVelocity(startPos, ((Component)target).transform.position);
				Vector3 val = CalculateLandingPoint(startPos, velocity);
				if (SemiFunc.IsMultiplayer() && (Object)(object)_photonView != (Object)null)
				{
					_photonView.RPC("ShowLandingCircleRPC", (RpcTarget)0, new object[2]
					{
						val,
						(int)type
					});
				}
				else
				{
					ShowLandingCircleRPC(val, (int)type);
				}
				yield return (object)new WaitForSeconds(1f);
				ThrowPotion(startPos, velocity, type);
			}
		}

		private void FacePlayer(PlayerAvatar target)
		{
			if ((Object)(object)_bombThrower == (Object)null || (Object)(object)target == (Object)null)
			{
				return;
			}
			try
			{
				Type nestedType = typeof(EnemyBombThrower).GetNestedType("RotationState", BindingFlags.NonPublic);
				MethodInfo method = typeof(EnemyBombThrower).GetMethod("RotationStateSet", BindingFlags.Instance | BindingFlags.NonPublic);
				if (!(nestedType == null) && !(method == null))
				{
					object obj = Enum.Parse(nestedType, "LookTargetDirectly");
					method.Invoke(_bombThrower, new object[1] { obj });
				}
			}
			catch
			{
			}
		}

		private bool IsFacingTarget(PlayerAvatar target)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)target == (Object)null)
			{
				return false;
			}
			Vector3 val = ((Component)target).transform.position - ((Component)this).transform.position;
			val.y = 0f;
			if (((Vector3)(ref val)).sqrMagnitude < 0.01f)
			{
				return true;
			}
			return Vector3.Angle(((Component)this).transform.forward, val) <= 25f;
		}

		private void ThrowPotion(Vector3 startPos, Vector3 velocity, WitchPotionProjectile.PotionType type)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_003f: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_009e: 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_008f: 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_011d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)potionPrefab == (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"WitchBehaviour.potionPrefab is not assigned.");
				}
				return;
			}
			Vector3 val = velocity;
			val.y = 0f;
			Quaternion val2 = ((((Vector3)(ref val)).sqrMagnitude > 0.01f) ? Quaternion.LookRotation(val) : Quaternion.identity);
			Quaternion val3 = val2 * Quaternion.Euler(0f, 90f, 0f);
			object[] array = new object[2]
			{
				(int)type,
				velocity
			};
			GameObject val4 = ((_potionNetworkRef != null) ? NetworkPrefabs.SpawnNetworkPrefab(_potionNetworkRef, startPos, val3, (byte)0, array) : Object.Instantiate<GameObject>(potionPrefab, startPos, val3));
			if ((Object)(object)val4 == (Object)null)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)"[Witch] Failed to spawn potion.");
				}
				return;
			}
			WitchPotionProjectile componentInChildren = val4.GetComponentInChildren<WitchPotionProjectile>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogWarning((object)"potionPrefab is missing WitchPotionProjectile component.");
				}
				Object.Destroy((Object)(object)val4);
				return;
			}
			componentInChildren.enemyHost = _enemy;
			componentInChildren.potionType = type;
			PlayWitchSound(SoundType.Throw);
			if (!SemiFunc.IsMultiplayer())
			{
				componentInChildren.Launch(velocity);
			}
		}

		private Vector3 CalculateLandingPoint(Vector3 start, Vector3 velocity)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_00ba: 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_0093: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = start;
			Vector3 val2 = velocity;
			float y = Physics.gravity.y;
			float num = 0.04f;
			LayerMask val3 = LayerMask.op_Implicit(LayerMask.GetMask(new string[5] { "Default", "PhysGrabObject", "PhysGrabObjectCart", "PhysGrabObjectHinge", "StaticGrabObject" }));
			for (int i = 0; i < 250; i++)
			{
				Vector3 val4 = val;
				val2.y += y * num;
				val += val2 * num;
				Vector3 val5 = val - val4;
				float magnitude = ((Vector3)(ref val5)).magnitude;
				if (magnitude > 0.001f && Physics.Raycast(val4, ((Vector3)(ref val5)).normalized, magnitude, LayerMask.op_Implicit(val3)))
				{
					return val4;
				}
			}
			return val;
		}

		private Vector3 CalculateThrowVelocity(Vector3 start, Vector3 target)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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_0042: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = target - start;
			float y = val.y;
			val.y = 0f;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (magnitude < 0.1f)
			{
				return Vector3.up * Plugin.ThrowSpeed.Value;
			}
			Vector3 val2 = val / magnitude;
			float num = Mathf.Abs(Physics.gravity.y);
			float value = Plugin.ThrowSpeed.Value;
			float num2 = num * magnitude * magnitude / (2f * value * value);
			float num3 = magnitude * magnitude - 4f * num2 * (y + num2);
			float num4;
			if (num3 < 0f)
			{
				num4 = 1f;
			}
			else
			{
				num4 = (magnitude - Mathf.Sqrt(num3)) / (2f * num2);
				if (num4 < 0f)
				{
					num4 = 0f;
				}
			}
			float num5 = 1f / Mathf.Sqrt(1f + num4 * num4);
			float num6 = num4 * num5;
			Vector3 result = val2 * (value * num5);
			result.y = value * num6;
			return result;
		}

		private PlayerAvatar FindNearestTarget()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: 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)
			if ((Object)(object)_bombThrower != (Object)null)
			{
				PlayerAvatar playerTarget = _bombThrower.playerTarget;
				if ((Object)(object)playerTarget != (Object)null && !playerTarget.isDisabled && !playerTarget.deadSet && (Object)(object)playerTarget.playerHealth != (Object)null)
				{
					float num = Vector3.Distance(((Component)this).transform.position, ((Component)playerTarget).transform.position);
					if (num <= Plugin.AttackRange.Value)
					{
						return playerTarget;
					}
				}
				return null;
			}
			PlayerAvatar result = null;
			float num2 = Plugin.AttackRange.Value;
			foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
			{
				if (!((Object)(object)player == (Object)null) && !player.isDisabled && !player.deadSet && !((Object)(object)player.playerHealth == (Object)null))
				{
					float num3 = Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position);
					if (num3 <= num2)
					{
						num2 = num3;
						result = player;
					}
				}
			}
			return result;
		}

		private void TryHeal()
		{
			int num = Mathf.Min(Plugin.HealAmount.Value, Plugin.MaxHealth.Value - _health.healthCurrent);
			if (num > 0)
			{
				_health.Heal(num);
				SpawnHealPotionVisual();
				PlayWitchSound(SoundType.Drink);
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"[Witch] Healed {num}, current = {_health.healthCurrent}");
				}
			}
		}

		private void SpawnHealPotionVisual()
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)$"[Witch] SpawnHealPotionVisual, mp={SemiFunc.IsMultiplayer()}, pv={(Object)(object)_photonView != (Object)null}");
			}
			if (SemiFunc.IsMultiplayer() && (Object)(object)_photonView != (Object)null)
			{
				_photonView.RPC("SpawnHealPotionVisualRPC", (RpcTarget)0, Array.Empty<object>());
			}
			else
			{
				SpawnHealPotionVisualRPC();
			}
		}

		private void SpawnHealPotionVisualLocal()
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = (((Object)(object)healPotionPrefab != (Object)null) ? healPotionPrefab : potionPrefab);
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)$"[Witch] SpawnHealPotionVisualLocal, healPrefab={(Object)(object)healPotionPrefab != (Object)null}, potionPrefab={(Object)(object)potionPrefab != (Object)null}");
			}
			if (!((Object)(object)val == (Object)null))
			{
				Transform val2 = (((Object)(object)healOrigin != (Object)null) ? healOrigin : ((Component)this).transform);
				Vector3 localPosition = (Vector3)(((Object)(object)healOrigin != (Object)null) ? Vector3.zero : new Vector3(0f, 1.2f, 0.6f));
				GameObject val3 = Object.Instantiate<GameObject>(val, val2);
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)string.Format("[Witch] SpawnHealPotionVisualLocal: visual={0}, prefab={1}, parent={2}, isClient={3}", ((Object)(object)val3 != (Object)null) ? "OK" : "NULL", ((Object)val).name, ((Object)val2).name, !SemiFunc.IsMasterClientOrSingleplayer()));
				}
				val3.transform.localPosition = localPosition;
				val3.transform.localRotation = Quaternion.Euler(0f, 90f, 0f);
				Rigidbody componentInChildren = val3.GetComponentInChildren<Rigidbody>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.isKinematic = true;
				}
				WitchPotionProjectile componentInChildren2 = val3.GetComponentInChildren<WitchPotionProjectile>();
				if ((Object)(object)componentInChildren2 != (Object)null)
				{
					((Behaviour)componentInChildren2).enabled = false;
				}
				PlayHealPotionParticles(val3);
				Object.Destroy((Object)(object)val3, 1f);
			}
		}

		[PunRPC]
		public void SpawnHealPotionVisualRPC()
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogWarning((object)"[Witch] SpawnHealPotionVisualRPC received (client)");
			}
			SpawnHealPotionVisualLocal();
		}

		private void PlayHealPotionParticles(GameObject visual)
		{
			//IL_002f: 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_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_0047: 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)
			ParticleSystem[] componentsInChildren = visual.GetComponentsInChildren<ParticleSystem>(true);
			ParticleSystem[] array = componentsInChildren;
			foreach (ParticleSystem val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					((Component)val).transform.SetParent((Transform)null, true);
					val.Play();
					MainModule main = val.main;
					float duration = ((MainModule)(ref main)).duration;
					main = val.main;
					MinMaxCurve startLifetime = ((MainModule)(ref main)).startLifetime;
					float num = duration + ((MinMaxCurve)(ref startLifetime)).constantMax;
					Object.Destroy((Object)(object)((Component)val).gameObject, Mathf.Max(num, 1f));
				}
			}
		}

		public void TryDropHealthPack()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_005a: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)healthPackDrop == (Object)null) && !(Random.value > Plugin.HealthPackDropChance.Value))
			{
				Vector3 val = (((Object)(object)_enemy != (Object)null && (Object)(object)_enemy.CenterTransform != (Object)null) ? _enemy.CenterTransform.position : ((Component)this).transform.position);
				Quaternion val2 = Quaternion.Euler(0f, 90f, 0f);
				if (_healthPackNetworkRef != null)
				{
					NetworkPrefabs.SpawnNetworkPrefab(_healthPackNetworkRef, val, val2, (byte)0, (object[])null);
				}
				else
				{
					Object.Instantiate<GameObject>(healthPackDrop, val, val2);
				}
			}
		}

		public void PlayDeathSound()
		{
			PlayWitchSound(SoundType.Death);
		}
	}
	[HarmonyPatch(typeof(EnemyBombThrower), "UpdateState")]
	internal static class PatchBombThrowerNoThrow
	{
		private static bool Prefix(EnemyBombThrower __instance, State _state)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if (((int)_state == 8 || (int)_state == 9) && (Object)(object)((Component)__instance).GetComponent<WitchBehaviour>() != (Object)null)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(EnemyBombThrower), "OnDeath")]
	internal static class PatchBombThrowerNoDeathBomb
	{
		private static bool Prefix(EnemyBombThrower __instance)
		{
			if ((Object)(object)((Component)__instance).GetComponent<WitchBehaviour>() == (Object)null)
			{
				return true;
			}
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				WitchBehaviour component = ((Component)__instance).GetComponent<WitchBehaviour>();
				component.TryDropHealthPack();
				component.PlayDeathSound();
				__instance.enemy.EnemyParent.Despawn();
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(EnemyBombThrower), "OnHurt")]
	internal static class PatchBombThrowerNoHurtSound
	{
		private static bool Prefix(EnemyBombThrower __instance)
		{
			if ((Object)(object)((Component)__instance).GetComponent<WitchBehaviour>() == (Object)null)
			{
				return true;
			}
			return false;
		}
	}
	public class WitchPotionProjectile : MonoBehaviour, IPunInstantiateMagicCallback, IPunObservable
	{
		public enum PotionType
		{
			Damage,
			Poison
		}

		public PotionType potionType;

		public Enemy enemyHost;

		public int damage = 50;

		public int poisonDamagePerSecond = 4;

		public float poisonDuration = 20f;

		public float poisonStopThreshold = 4f;

		public float hitRadius = 1.2f;

		public float collisionRadius = 0.4f;

		public Sound breakSound;

		public Material poisonParticlesMaterial;

		private bool exploded;

		private bool _remotePhysicsStarted;

		private Vector3 _remotePosition;

		private Vector3 _remoteVelocity;

		private double _remoteTimestamp;

		private Rigidbody _rb;

		private static readonly Color DamageColor = new Color(0.6588f, 0.3961f, 0.4157f);

		private static readonly Color PoisonColor = new Color(0.529f, 0.639f, 0.388f);

		private Vector3 Position
		{
			get
			{
				//IL_0020: 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)
				if (!((Object)(object)_rb != (Object)null))
				{
					return ((Component)this).transform.position;
				}
				return _rb.position;
			}
		}

		private void Awake()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			_rb = ((Component)this).GetComponentInChildren<Rigidbody>();
			_remotePosition = Position;
		}

		public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_0028: 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)
			if (stream.IsWriting)
			{
				stream.SendNext((object)Position);
				stream.SendNext((object)(((Object)(object)_rb != (Object)null) ? _rb.velocity : Vector3.zero));
				stream.SendNext((object)exploded);
				return;
			}
			_remotePosition = (Vector3)stream.ReceiveNext();
			_remoteVelocity = (Vector3)stream.ReceiveNext();
			if ((bool)stream.ReceiveNext() && !exploded)
			{
				exploded = true;
			}
			_remoteTimestamp = PhotonNetwork.Time;
			_remotePhysicsStarted = true;
			if ((Object)(object)_rb != (Object)null)
			{
				_rb.isKinematic = true;
				_rb.position = _remotePosition;
			}
		}

		private void Update()
		{
			//IL_0044: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			if (!exploded && !SemiFunc.IsMasterClientOrSingleplayer() && _remotePhysicsStarted && !((Object)(object)_rb == (Object)null))
			{
				float num = Mathf.Clamp((float)(PhotonNetwork.Time - _remoteTimestamp), 0f, 0.1f);
				Vector3 val = _remotePosition + _remoteVelocity * num;
				_rb.position = Vector3.Lerp(_rb.position, val, 0.75f);
				_rb.velocity = _remoteVelocity;
			}
		}

		public void Launch(Vector3 velocity)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			Rigidbody componentInChildren = ((Component)this).GetComponentInChildren<Rigidbody>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.useGravity = true;
				componentInChildren.isKinematic = false;
				componentInChildren.velocity = velocity;
			}
			ApplyColor();
		}

		public void OnPhotonInstantiate(PhotonMessageInfo info)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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)
			object[] array = (((Object)(object)info.photonView != (Object)null) ? info.photonView.InstantiationData : null);
			if (array != null && array.Length != 0)
			{
				potionType = (PotionType)(int)array[0];
			}
			ApplyColor();
			if (array != null && array.Length > 1 && array[1] is Vector3 velocity)
			{
				Launch(velocity);
			}
		}

		private void ApplyColor()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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)
			Color val = ((potionType == PotionType.Damage) ? DamageColor : PoisonColor);
			Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>();
			Renderer[] array = componentsInChildren;
			foreach (Renderer val2 in array)
			{
				if (!((Object)(object)val2.sharedMaterial == (Object)null))
				{
					Material material = val2.material;
					if (material.HasProperty("_BaseColor"))
					{
						material.SetColor("_BaseColor", val);
					}
					if (material.HasProperty("_Color"))
					{
						material.SetColor("_Color", val);
					}
					if (material.HasProperty("_EmissionColor"))
					{
						material.EnableKeyword("_EMISSION");
						material.SetColor("_EmissionColor", val * 2f);
					}
				}
			}
		}

		private void FixedUpdate()
		{
			//IL_0011: 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_0018: 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)
			if (exploded || !SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			LayerMask val = SemiFunc.LayerMaskGetShouldHits();
			Collider[] array = Physics.OverlapSphere(Position, collisionRadius, LayerMask.op_Implicit(val));
			Collider[] array2 = array;
			foreach (Collider val2 in array2)
			{
				if (!((Component)val2).transform.IsChildOf(((Component)this).transform) && (!((Object)(object)enemyHost != (Object)null) || !((Object)(object)enemyHost.EnemyParent != (Object)null) || !((Component)val2).transform.IsChildOf(((Component)enemyHost.EnemyParent).transform)))
				{
					Explode();
					break;
				}
			}
		}

		private void Explode()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: 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)
			if (exploded)
			{
				return;
			}
			exploded = true;
			HashSet<PlayerAvatar> hashSet = new HashSet<PlayerAvatar>();
			Collider[] array = Physics.OverlapSphere(Position, hitRadius);
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				if ((Object)(object)enemyHost != (Object)null && (Object)(object)enemyHost.EnemyParent != (Object)null && ((Component)val).transform.IsChildOf(((Component)enemyHost.EnemyParent).transform))
				{
					continue;
				}
				PlayerAvatar componentInParent = ((Component)val).GetComponentInParent<PlayerAvatar>();
				if ((Object)(object)componentInParent == (Object)null || componentInParent.isDisabled || componentInParent.deadSet || (Object)(object)componentInParent.playerHealth == (Object)null || !hashSet.Add(componentInParent))
				{
					continue;
				}
				if (potionType == PotionType.Damage)
				{
					componentInParent.playerHealth.HurtOther(damage, Position, false, SemiFunc.EnemyGetIndex(enemyHost), false);
				}
				else
				{
					if (!((Object)(object)((Component)componentInParent).GetComponent<WitchPoisonDebuff>() == (Object)null))
					{
						continue;
					}
					WitchPoisonDebuff witchPoisonDebuff = ((Component)componentInParent).gameObject.AddComponent<WitchPoisonDebuff>();
					witchPoisonDebuff.Initialize(enemyHost, poisonDamagePerSecond, poisonDuration, poisonStopThreshold, poisonParticlesMaterial);
					if (SemiFunc.IsMultiplayer())
					{
						PhotonView componentInChildren = ((Component)this).GetComponentInChildren<PhotonView>();
						if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInParent.photonView != (Object)null)
						{
							componentInChildren.RPC("AddPoisonDebuffRPC", (RpcTarget)0, new object[4]
							{
								componentInParent.photonView.ViewID,
								poisonDamagePerSecond,
								poisonDuration,
								poisonStopThreshold
							});
						}
					}
				}
			}
			if (breakSound != null)
			{
				breakSound.Play(Position, 1f, 1f, 1f, 1f);
				if (SemiFunc.IsMultiplayer())
				{
					PhotonView componentInChildren2 = ((Component)this).GetComponentInChildren<PhotonView>();
					if ((Object)(object)componentInChildren2 != (Object)null)
					{
						componentInChildren2.RPC("PlayBreakSoundRPC", (RpcTarget)1, Array.Empty<object>());
					}
				}
			}
			DetachAndPlayExplosionParticles();
			if (SemiFunc.IsMultiplayer())
			{
				PhotonView componentInChildren3 = ((Component)this).GetComponentInChildren<PhotonView>();
				if ((Object)(object)componentInChildren3 != (Object)null)
				{
					componentInChildren3.RPC("PlayExplosionParticlesRPC", (RpcTarget)1, Array.Empty<object>());
				}
			}
			if (SemiFunc.IsMultiplayer())
			{
				PhotonNetwork.Destroy(((Component)((Component)this).gameObject.transform.root).gameObject);
			}
			else
			{
				Object.Destroy((Object)(object)((Component)((Component)this).gameObject.transform.root).gameObject);
			}
		}

		[PunRPC]
		public void PlayBreakSoundRPC()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Sound obj = breakSound;
			if (obj != null)
			{
				obj.Play(Position, 1f, 1f, 1f, 1f);
			}
		}

		[PunRPC]
		public void PlayExplosionParticlesRPC()
		{
			DetachAndPlayExplosionParticles();
		}

		[PunRPC]
		public void AddPoisonDebuffRPC(int playerViewID, int dps, float duration, float stopThreshold, PhotonMessageInfo info = default(PhotonMessageInfo))
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if (!SemiFunc.MasterOnlyRPC(info))
			{
				return;
			}
			foreach (PlayerAvatar item in SemiFunc.PlayerGetList())
			{
				if (!((Object)(object)item == (Object)null) && !((Object)(object)item.photonView == (Object)null) && item.photonView.ViewID == playerViewID)
				{
					if ((Object)(object)((Component)item).GetComponent<WitchPoisonDebuff>() == (Object)null)
					{
						WitchPoisonDebuff witchPoisonDebuff = ((Component)item).gameObject.AddComponent<WitchPoisonDebuff>();
						witchPoisonDebuff.Initialize(null, dps, duration, stopThreshold, poisonParticlesMaterial);
					}
					break;
				}
			}
		}

		private void DetachAndPlayExplosionParticles()
		{
			//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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			ParticleSystem[] componentsInChildren = ((Component)this).GetComponentsInChildren<ParticleSystem>(true);
			ParticleSystem[] array = componentsInChildren;
			foreach (ParticleSystem val in array)
			{
				((Component)val).transform.SetParent((Transform)null, true);
				MainModule main = val.main;
				if (!((MainModule)(ref main)).loop)
				{
					val.Play();
					main = val.main;
					float duration = ((MainModule)(ref main)).duration;
					main = val.main;
					MinMaxCurve startLifetime = ((MainModule)(ref main)).startLifetime;
					float num = duration + ((MinMaxCurve)(ref startLifetime)).constantMax;
					Object.Destroy((Object)(object)((Component)val).gameObject, Mathf.Max(num, 2f));
				}
				else
				{
					val.Play();
					Object.Destroy((Object)(object)((Component)val).gameObject, 2f);
				}
			}
		}
	}
	public class WitchPoisonDebuff : MonoBehaviour
	{
		private Enemy _enemyHost;

		private int _damagePerSecond;

		private float _duration;

		private float _stopThreshold;

		private float _timeUntilNextTick = 1f;

		private float _elapsed;

		private GameObject _particlesInstance;

		private Material _particlesMaterial;

		private static readonly Color PoisonColor = new Color(0.529f, 0.639f, 0.388f);

		public void Initialize(Enemy enemyHost, int damagePerSecond, float duration, float stopThreshold, Material particlesMaterial = null)
		{
			_enemyHost = enemyHost;
			_damagePerSecond = damagePerSecond;
			_duration = duration;
			_stopThreshold = stopThreshold;
			_particlesMaterial = particlesMaterial;
		}

		private void Update()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			PlayerAvatar component = ((Component)this).GetComponent<PlayerAvatar>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.playerHealth == (Object)null)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			_elapsed += Time.deltaTime;
			if (_elapsed >= _duration)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			if (component.isLocal)
			{
				PostProcessing.Instance.VignetteOverride(PoisonColor, 0.7f, 0.5f, 1.5f, 1.5f, 1.5f, ((Component)this).gameObject);
			}
			if ((Object)(object)_particlesInstance == (Object)null)
			{
				_particlesInstance = CreatePoisonParticles(component);
			}
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			if ((float)component.playerHealth.health <= _stopThreshold)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			_timeUntilNextTick -= Time.deltaTime;
			if (_timeUntilNextTick <= 0f)
			{
				_timeUntilNextTick += 1f;
				component.playerHealth.HurtOther(_damagePerSecond, ((Component)component).transform.position, false, SemiFunc.EnemyGetIndex(_enemyHost), false);
			}
		}

		private GameObject CreatePoisonParticles(PlayerAvatar player)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: 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_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_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Expected O, but got Unknown
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: 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_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("WitchPoisonParticles");
			val.transform.SetParent(((Component)player).transform, false);
			val.transform.localPosition = new Vector3(0f, 0.6f, 0f);
			ParticleSystem val2 = val.AddComponent<ParticleSystem>();
			MainModule main = val2.main;
			((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(PoisonColor.r, PoisonColor.g, PoisonColor.b, 0.7f));
			((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.25f);
			((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(1.2f);
			((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0.5f);
			((MainModule)(ref main)).maxParticles = 80;
			((MainModule)(ref main)).loop = true;
			((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(-0.05f);
			EmissionModule emission = val2.emission;
			((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(30f);
			ShapeModule shape = val2.shape;
			((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0;
			((ShapeModule)(ref shape)).radius = 0.7f;
			if ((Object)(object)_particlesMaterial != (Object)null)
			{
				((Renderer)((Component)val2).GetComponent<ParticleSystemRenderer>()).material = _particlesMaterial;
			}
			ColorOverLifetimeModule colorOverLifetime = val2.colorOverLifetime;
			((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true;
			Gradient val3 = new Gradient();
			val3.SetKeys((GradientColorKey[])(object)new GradientColorKey[2]
			{
				new GradientColorKey(PoisonColor, 0f),
				new GradientColorKey(PoisonColor, 1f)
			}, (GradientAlphaKey[])(object)new GradientAlphaKey[2]
			{
				new GradientAlphaKey(0.8f, 0f),
				new GradientAlphaKey(0f, 1f)
			});
			((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(val3);
			val2.Play();
			return val;
		}

		private void OnDestroy()
		{
			if ((Object)(object)_particlesInstance != (Object)null)
			{
				Object.Destroy((Object)(object)_particlesInstance);
			}
		}
	}
}