Decompiled source of MCWitchMod v1.2.1

Witch.dll

Decompiled a week 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.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("Luca")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Witch enemy behaviour for R.E.P.O.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+bbd8406d9fe0d847b544865f4770518b3a2a8d3b")]
[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_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0014: 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)
			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_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_0071: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: 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_011d: 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_0071: 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_0086: 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)
			_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;
			}
		}
	}
	public sealed class WitchBat : MonoBehaviour
	{
		[SerializeField]
		private float modelYawOffset;

		[SerializeField]
		private Sound soundAppear;

		private const float ShrinkDuration = 0.5f;

		private Vector3 _velocity;

		private float _speed = 3f;

		private float _lifeTime = 2.5f;

		private float _age;

		private float _turnTimer;

		private float _wobblePhase;

		private float _wobbleFrequency = 5f;

		private float _wobbleAmplitude = 0.5f;

		private float _rollAmplitude = 15f;

		private Vector3 _initialScale = Vector3.one;

		private void Awake()
		{
			//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)
			_initialScale = ((Component)this).transform.localScale;
		}

		private void Start()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			Sound obj = soundAppear;
			if (obj != null)
			{
				obj.Play(((Component)this).transform.position, 1f, 1f, 1f, 1f);
			}
			Animator componentInChildren = ((Component)this).GetComponentInChildren<Animator>();
			if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.runtimeAnimatorController != (Object)null)
			{
				componentInChildren.Update(Random.Range(0f, 1f));
			}
		}

		public void Initialize(Vector3 velocity, float lifeTime)
		{
			//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)
			_velocity = velocity;
			_speed = Mathf.Max(0.5f, ((Vector3)(ref velocity)).magnitude);
			_lifeTime = Mathf.Max(0.6f, lifeTime);
			_age = 0f;
			_turnTimer = 0f;
			_wobblePhase = Random.Range(0f, MathF.PI * 2f);
			_wobbleFrequency = Random.Range(4f, 7f);
			_wobbleAmplitude = Random.Range(0.2f, 0.55f);
			_rollAmplitude = Random.Range(12f, 28f);
		}

		private void Update()
		{
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: 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_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_009d: 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_00c5: 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_0184: 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_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: 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)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			_age += Time.deltaTime;
			if (_age >= _lifeTime)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			_turnTimer -= Time.deltaTime;
			if (_turnTimer <= 0f)
			{
				_turnTimer = Random.Range(0.15f, 0.45f);
				Vector3 val = Vector3.Slerp(((Vector3)(ref _velocity)).normalized, Random.onUnitSphere, Random.Range(0.35f, 0.7f));
				val.y = Mathf.Clamp(val.y, -0.35f, 0.75f);
				_velocity = ((Vector3)(ref val)).normalized * _speed;
			}
			Transform transform = ((Component)this).transform;
			transform.position += _velocity * Time.deltaTime;
			_wobblePhase += _wobbleFrequency * Time.deltaTime;
			Transform transform2 = ((Component)this).transform;
			transform2.position += Vector3.up * (Mathf.Sin(_wobblePhase) * _wobbleAmplitude * Time.deltaTime);
			if (((Vector3)(ref _velocity)).sqrMagnitude > 0.0001f)
			{
				Quaternion val2 = Quaternion.Euler(0f, 0f, Mathf.Sin(_wobblePhase * 1.2f) * _rollAmplitude);
				((Component)this).transform.rotation = Quaternion.LookRotation(_velocity) * Quaternion.Euler(0f, modelYawOffset, 0f) * val2;
			}
			float num = _lifeTime - _age;
			if (num < 0.5f)
			{
				((Component)this).transform.localScale = _initialScale * Mathf.Max(0f, num / 0.5f);
			}
		}
	}
	[BepInPlugin("com.luca.witch", "Witch", "1.2.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;

		internal static ConfigEntry<bool> ShowLandingCircle;

		private void Awake()
		{
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: 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=全毒)");
			ShowLandingCircle = ((BaseUnityPlugin)this).Config.Bind<bool>("Witch", "ShowLandingCircle", true, "是否显示药水落点的预警圈。默认开。这是每个玩家各自的本地显示设置——关掉只影响你自己的画面,不影响其他玩家,也不影响女巫的投掷僵直(战斗难度不变)。");
			_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 LandingRadius = 1.2f;

		private const float WarnDuration = 0.5f;

		private const float DespawnDelay = 1.17f;

		private float _aimingUntil;

		private PlayerAvatar _aimTarget;

		private float _windupUntil;

		private static FieldInfo _rotationTargetField;

		private static bool _rotationTargetFieldWarned;

		[SerializeField]
		private GameObject potionPrefab;

		[SerializeField]
		private Transform throwOrigin;

		[SerializeField]
		private GameObject healPotionPrefab;

		[SerializeField]
		private Transform healOrigin;

		[SerializeField]
		private GameObject healthPackDrop;

		[SerializeField]
		private GameObject batSwarmPrefab;

		[SerializeField]
		private int batSwarmCount = 5;

		[SerializeField]
		private float batLifeTime = 2.5f;

		[SerializeField]
		private float batSpeedMin = 1.2f;

		[SerializeField]
		private float batSpeedMax = 2.2f;

		[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 bool _despawning;

		private float _despawnTimer;

		private PrefabRef _potionNetworkRef;

		private PrefabRef _healthPackNetworkRef;

		private static PrefabRef _cachedPotionNetworkRef;

		private static PrefabRef _cachedHealthPackNetworkRef;

		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 int _lastSyncedHealthMax = -1;

		private int _lastSyncedHealthCurrent = -1;

		private static bool ShowLandingCircle => Plugin.ShowLandingCircle == null || Plugin.ShowLandingCircle.Value;

		internal bool IsAiming => Time.time < _aimingUntil;

		internal bool IsThrowWindup => Time.time < _windupUntil;

		private void Start()
		{
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: 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;
			}
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				_health.health = Plugin.MaxHealth.Value;
				_health.OnSpawn();
			}
			else if (SemiFunc.IsMultiplayer() && (Object)(object)_photonView != (Object)null)
			{
				_photonView.RPC("RequestHealthSyncRPC", (RpcTarget)2, Array.Empty<object>());
			}
			_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}");
				}
			}
			_potionNetworkRef = GetOrRegisterNetworkPrefab(potionPrefab, ref _cachedPotionNetworkRef);
			_healthPackNetworkRef = GetOrRegisterNetworkPrefab(healthPackDrop, ref _cachedHealthPackNetworkRef);
			ManualLogSource log3 = Plugin.Log;
			if (log3 != null)
			{
				log3.LogInfo((object)$"WitchBehaviour initialized. Health = {_health.health}");
			}
		}

		private static PrefabRef GetOrRegisterNetworkPrefab(GameObject prefab, ref PrefabRef cachedRef)
		{
			if ((Object)(object)prefab == (Object)null)
			{
				return null;
			}
			if (cachedRef != null)
			{
				return cachedRef;
			}
			string name = ((Object)prefab).name;
			if (NetworkPrefabs.HasNetworkPrefab(name))
			{
				cachedRef = NetworkPrefabs.GetNetworkPrefabRef(name);
				return cachedRef;
			}
			PrefabRef val = NetworkPrefabs.RegisterNetworkPrefab(prefab);
			if (val != null)
			{
				cachedRef = val;
			}
			return val;
		}

		private void OnDestroy()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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;
			}
			SyncHealthToClients();
			UpdateDespawn();
			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 && IsEngaged(val))
				{
					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 UpdateDespawn()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			if ((int)_enemy.CurrentState != 11)
			{
				if (_despawning)
				{
					_despawning = false;
					_despawnTimer = 0f;
				}
				return;
			}
			EnemyParent enemyParent = _enemy.EnemyParent;
			if ((Object)(object)enemyParent == (Object)null)
			{
				return;
			}
			if (!_despawning)
			{
				_despawning = true;
				_despawnTimer = 1.17f;
				return;
			}
			_despawnTimer -= Time.deltaTime;
			if (!(_despawnTimer > 0f))
			{
				_despawning = false;
				if (enemyParent.Spawned && _health.healthCurrent > 0)
				{
					PlayVanishBats();
					enemyParent.Despawn();
				}
			}
		}

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

		private void UpdateFootsteps()
		{
			//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_00f9: 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_003a: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: 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_0142: 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_0019: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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)
			if (ShowLandingCircle)
			{
				Color color = ((type == 0) ? LandingDamageColor : LandingPoisonColor);
				LandingCircle.Create(pos, 1.2f, color, 2.5f);
			}
		}

		private IEnumerator ThrowPotionRoutine(PlayerAvatar target)
		{
			BeginAiming(target, 2.5f);
			float waited = 0f;
			while (waited < 2.5f && !IsFacingTarget(target))
			{
				if (!IsThrowTargetValid(target))
				{
					EndAiming();
					yield break;
				}
				waited += Time.deltaTime;
				yield return null;
			}
			if (!IsFacingTarget(target))
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"[Witch] 面向超时({2.5f}s 内没转过来),放弃本次投掷");
				}
				EndAiming();
				_attackTimer = 0.5f;
				yield break;
			}
			if (!IsThrowTargetValid(target))
			{
				EndAiming();
				yield break;
			}
			WitchPotionProjectile.PotionType type = ((Random.value < Plugin.PoisonChance.Value) ? WitchPotionProjectile.PotionType.Poison : WitchPotionProjectile.PotionType.Damage);
			float warn = 0.5f;
			_aimingUntil = Time.time + warn + 0.15f;
			FreezeForThrow(warn + 0.15f);
			Vector3 startPos = ThrowOriginPosition();
			Vector3 velocity = CalculateThrowVelocity(startPos, ((Component)target).transform.position);
			Vector3 landing = CalculateLandingPoint(startPos, velocity);
			if (SemiFunc.IsMultiplayer() && (Object)(object)_photonView != (Object)null)
			{
				_photonView.RPC("ShowLandingCircleRPC", (RpcTarget)0, new object[2]
				{
					landing,
					(int)type
				});
			}
			else
			{
				ShowLandingCircleRPC(landing, (int)type);
			}
			yield return (object)new WaitForSeconds(warn);
			if (!IsThrowTargetValid(target))
			{
				EndAiming();
				yield break;
			}
			ThrowPotion(startPos, velocity, type);
			EndAiming();
		}

		private void FreezeForThrow(float duration)
		{
			_windupUntil = Time.time + duration;
			if ((Object)(object)_enemy != (Object)null && (Object)(object)_enemy.NavMeshAgent != (Object)null)
			{
				_enemy.NavMeshAgent.Stop(duration);
			}
		}

		private Vector3 ThrowOriginPosition()
		{
			//IL_0036: 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_001a: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			return ((Object)(object)throwOrigin != (Object)null) ? throwOrigin.position : (((Component)this).transform.position + Vector3.up * 1.5f);
		}

		private bool IsThrowTargetValid(PlayerAvatar target)
		{
			if ((Object)(object)_enemy == (Object)null || _enemy.IsStunned())
			{
				return false;
			}
			return IsEngaged(target);
		}

		private bool IsEngaged(PlayerAvatar target)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Invalid comparison between Unknown and I4
			//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_0077: 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_007b: 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_0080: Invalid comparison between Unknown and I4
			if ((Object)(object)target == (Object)null || target.deadSet || target.isDisabled)
			{
				return false;
			}
			if ((Object)(object)_enemy == (Object)null)
			{
				return false;
			}
			if ((int)_enemy.CurrentState == 11)
			{
				return false;
			}
			if ((Object)(object)_bombThrower == (Object)null)
			{
				return true;
			}
			State currentState = _bombThrower.currentState;
			State val = currentState;
			if (val - 4 > 5)
			{
				return false;
			}
			if ((Object)(object)_enemy.Vision == (Object)null || (Object)(object)_enemy.Vision.VisionTransform == (Object)null)
			{
				return true;
			}
			return !_bombThrower.VisionBlocked();
		}

		private void BeginAiming(PlayerAvatar target, float duration)
		{
			_aimTarget = target;
			_aimingUntil = Time.time + duration;
			ForceFaceTarget(_bombThrower);
		}

		private void EndAiming()
		{
			_aimTarget = null;
			_aimingUntil = 0f;
		}

		internal void ForceFaceTarget(EnemyBombThrower bt)
		{
			//IL_00b8: 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_00e0: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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_011e: 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)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)bt == (Object)null || (Object)(object)_aimTarget == (Object)null)
			{
				return;
			}
			if (_rotationTargetField == null)
			{
				_rotationTargetField = typeof(EnemyBombThrower).GetField("horizontalRotationTarget", BindingFlags.Instance | BindingFlags.NonPublic);
			}
			if (_rotationTargetField == null)
			{
				if (!_rotationTargetFieldWarned)
				{
					_rotationTargetFieldWarned = true;
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogWarning((object)"[Witch] 取不到 EnemyBombThrower.horizontalRotationTarget,无法接管瞄准朝向,会退回原版转向(可能出现『先扔后转身』)。");
					}
				}
				return;
			}
			Vector3 val = (((Object)(object)bt.enemy != (Object)null && (Object)(object)bt.enemy.Rigidbody != (Object)null) ? ((Component)bt.enemy.Rigidbody).transform.position : ((Component)bt).transform.position);
			Vector3 val2 = ((Component)_aimTarget).transform.position - val;
			val2.y = 0f;
			if (!(((Vector3)(ref val2)).sqrMagnitude < 0.0001f))
			{
				Quaternion val3 = Quaternion.LookRotation(val2);
				((Quaternion)(ref val3)).eulerAngles = new Vector3(0f, ((Quaternion)(ref val3)).eulerAngles.y, 0f);
				_rotationTargetField.SetValue(bt, val3);
				if (bt.horizontalRotationSpring != null)
				{
					bt.horizontalRotationSpring.speed = 8f;
					bt.horizontalRotationSpring.damping = 0.7f;
				}
			}
		}

		private bool IsFacingTarget(PlayerAvatar target)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_0053: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: 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)
			//IL_0141: 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_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_0005: 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_0056: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//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_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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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_0095: 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)
			//IL_00d3: 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_00b4: 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_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_0008: 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_004e: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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)
			//IL_0106: 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_00ae: 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_00b3: 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)
			//IL_0139: 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_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 = 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_0057: 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_007e: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)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);
		}

		public void PlayVanishBats()
		{
			//IL_003d: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_0063: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)batSwarmPrefab == (Object)null))
			{
				Vector3 val = (((Object)(object)_enemy != (Object)null && (Object)(object)_enemy.CenterTransform != (Object)null) ? _enemy.CenterTransform.position : (((Component)this).transform.position + Vector3.up * 1.2f));
				if (SemiFunc.IsMultiplayer() && (Object)(object)_photonView != (Object)null)
				{
					_photonView.RPC("SpawnBatSwarmRPC", (RpcTarget)0, new object[1] { val });
				}
				else
				{
					SpawnBatSwarmRPC(val);
				}
			}
		}

		[PunRPC]
		public void SpawnBatSwarmRPC(Vector3 position)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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_009a: 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)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)batSwarmPrefab == (Object)null)
			{
				return;
			}
			for (int i = 0; i < batSwarmCount; i++)
			{
				Vector3 val = Quaternion.Euler(0f, Random.Range(0f, 360f), 0f) * Vector3.forward;
				Vector3 velocity = val * Random.Range(batSpeedMin, batSpeedMax) + Vector3.up * Random.Range(0.3f, 0.9f);
				Vector3 val2 = position + Random.insideUnitSphere * 0.35f;
				GameObject val3 = Object.Instantiate<GameObject>(batSwarmPrefab, val2, Quaternion.identity);
				WitchBat witchBat = val3.GetComponent<WitchBat>() ?? val3.GetComponentInChildren<WitchBat>();
				if ((Object)(object)witchBat != (Object)null)
				{
					witchBat.Initialize(velocity, batLifeTime);
				}
			}
		}

		private void SyncHealthToClients()
		{
			if (!((Object)(object)_photonView == (Object)null) && SemiFunc.IsMultiplayer() && (_lastSyncedHealthMax != _health.health || _lastSyncedHealthCurrent != _health.healthCurrent))
			{
				_lastSyncedHealthMax = _health.health;
				_lastSyncedHealthCurrent = _health.healthCurrent;
				_photonView.RPC("SyncHealthRPC", (RpcTarget)1, new object[2] { _health.health, _health.healthCurrent });
			}
		}

		[PunRPC]
		public void SyncHealthRPC(int maxHealth, int currentHealth)
		{
			if (!((Object)(object)_health == (Object)null))
			{
				_health.health = maxHealth;
				_health.healthCurrent = currentHealth;
			}
		}

		[PunRPC]
		public void RequestHealthSyncRPC(PhotonMessageInfo info = default(PhotonMessageInfo))
		{
			_lastSyncedHealthMax = -1;
			_lastSyncedHealthCurrent = -1;
		}
	}
	[HarmonyPatch(typeof(EnemyBombThrower), "UpdateState")]
	internal static class PatchBombThrowerNoThrow
	{
		private static bool Prefix(EnemyBombThrower __instance, State _state)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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.PlayVanishBats();
				component.TryDropHealthPack();
				component.PlayDeathSound();
				__instance.enemy.EnemyParent.Despawn();
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(EnemyBombThrower), "RotationStateSet")]
	internal static class PatchWitchAimDuringWindup
	{
		private static bool Prefix(EnemyBombThrower __instance)
		{
			WitchBehaviour component = ((Component)__instance).GetComponent<WitchBehaviour>();
			if ((Object)(object)component == (Object)null || !component.IsAiming)
			{
				return true;
			}
			component.ForceFaceTarget(__instance);
			return false;
		}
	}
	[HarmonyPatch(typeof(EnemyBombThrower), "BackAwayLogic")]
	internal static class PatchWitchNoBackAwayDuringWindup
	{
		private static bool Prefix(EnemyBombThrower __instance)
		{
			WitchBehaviour component = ((Component)__instance).GetComponent<WitchBehaviour>();
			return (Object)(object)component == (Object)null || !component.IsThrowWindup;
		}
	}
	[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 WitchEnemyPoisonDebuff : MonoBehaviour
	{
		private Enemy _target;

		private int _damagePerSecond;

		private float _duration;

		private float _stopThreshold;

		private float _timeUntilNextTick = 1f;

		private float _elapsed;

		private GameObject _particlesInstance;

		private Material _particlesMaterial;

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

		public void Refresh()
		{
			_elapsed = 0f;
			_timeUntilNextTick = 1f;
		}

		private void Update()
		{
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_target == (Object)null || !_target.HasHealth || (Object)(object)_target.Health == (Object)null)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			if (_target.Health.dead || _target.Health.healthCurrent <= 0)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			if ((Object)(object)_target.EnemyParent != (Object)null && !_target.EnemyParent.Spawned)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			_elapsed += Time.deltaTime;
			if (_elapsed >= _duration)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			if ((Object)(object)_particlesInstance == (Object)null)
			{
				_particlesInstance = CreateParticles();
			}
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			if ((float)_target.Health.healthCurrent <= _stopThreshold)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			_timeUntilNextTick -= Time.deltaTime;
			if (_timeUntilNextTick <= 0f)
			{
				_timeUntilNextTick += 1f;
				_target.Health.Hurt(_damagePerSecond, ((Component)_target).transform.up);
			}
		}

		private GameObject CreateParticles()
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			float num = 1f;
			if ((Object)(object)_target.Rigidbody != (Object)null)
			{
				float y = ((Component)_target).transform.InverseTransformPoint(((Component)_target.Rigidbody).transform.position).y;
				if (y > 0.05f && y <= 6f)
				{
					num = y;
				}
			}
			return WitchPoisonParticles.Create(((Component)_target).transform, new Vector3(0f, num, 0f), 1f, _particlesMaterial);
		}

		private void OnDestroy()
		{
			if ((Object)(object)_particlesInstance != (Object)null)
			{
				Object.Destroy((Object)(object)_particlesInstance);
			}
		}
	}
	internal static class WitchPoisonParticles
	{
		internal static readonly Color PoisonColor = new Color(0.529f, 0.639f, 0.388f);

		internal static GameObject Create(Transform parent, Vector3 localPosition, float radius, Material material)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0020: 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_0034: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_0095: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: 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_0118: 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_012a: Expected O, but got Unknown
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: 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_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("WitchPoisonParticles");
			val.transform.SetParent(parent, false);
			val.transform.localPosition = localPosition;
			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 = radius;
			if ((Object)(object)material != (Object)null)
			{
				((Renderer)((Component)val2).GetComponent<ParticleSystemRenderer>()).material = material;
			}
			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;
		}
	}
	public class WitchPotionProjectile : MonoBehaviour, IPunInstantiateMagicCallback, IPunObservable
	{
		public enum PotionType
		{
			Damage,
			Poison
		}

		public PotionType potionType = PotionType.Damage;

		public Enemy enemyHost;

		public int damage = 50;

		public int enemyDamage = 25;

		public int poisonDamagePerSecond = 4;

		public float poisonDuration = 20f;

		public float poisonStopThreshold = 4f;

		public float hitRadius = 1.2f;

		public float collisionRadius = 0.4f;

		public float balloonPopRadius = 1.5f;

		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 => ((Object)(object)_rb != (Object)null) ? _rb.position : ((Component)this).transform.position;

		private void Awake()
		{
			//IL_000f: 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)
			_rb = ((Component)this).GetComponentInChildren<Rigidbody>();
			_remotePosition = Position;
		}

		public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
		{
			//IL_006a: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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_0079: 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);
			}
		}

		public void Launch(Vector3 velocity)
		{
			//IL_0025: 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_0001: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_0010: 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_0015: 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_0087: 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_00bb: 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_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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			if (exploded)
			{
				return;
			}
			exploded = true;
			HashSet<PlayerAvatar> hashSet = new HashSet<PlayerAvatar>();
			HashSet<Enemy> hashSet2 = new HashSet<Enemy>();
			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)
				{
					if (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);
						continue;
					}
					WitchPoisonDebuff component = ((Component)componentInParent).GetComponent<WitchPoisonDebuff>();
					if ((Object)(object)component != (Object)null)
					{
						component.Refresh();
					}
					else
					{
						component = ((Component)componentInParent).gameObject.AddComponent<WitchPoisonDebuff>();
						component.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
							});
						}
					}
					continue;
				}
				Enemy val2 = ResolveEnemy(val);
				if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2 == (Object)(object)enemyHost) && hashSet2.Add(val2) && val2.HasHealth && !((Object)(object)val2.Health == (Object)null) && !val2.Health.dead && !val2.Health.deadImpulse)
				{
					if (potionType == PotionType.Damage)
					{
						val2.Health.Hurt(enemyDamage, DirFromExplosionTo(val2));
					}
					else
					{
						ApplyEnemyPoison(val2);
					}
				}
			}
			PopNearbyBalloons();
			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);
			}
		}

		private static Enemy ResolveEnemy(Collider hit)
		{
			EnemyParent componentInParent = ((Component)hit).GetComponentInParent<EnemyParent>();
			if ((Object)(object)componentInParent != (Object)null && (Object)(object)componentInParent.Enemy != (Object)null)
			{
				return componentInParent.Enemy;
			}
			EnemyRigidbody componentInParent2 = ((Component)hit).GetComponentInParent<EnemyRigidbody>();
			if ((Object)(object)componentInParent2 != (Object)null && (Object)(object)componentInParent2.enemy != (Object)null)
			{
				return componentInParent2.enemy;
			}
			return ((Component)hit).GetComponentInParent<Enemy>();
		}

		private Vector3 DirFromExplosionTo(Enemy enemy)
		{
			//IL_0022: 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_0027: 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_002a: 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_0034: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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)
			Vector3 val = (((Object)(object)enemy.CenterTransform != (Object)null) ? enemy.CenterTransform.position : ((Component)enemy).transform.position);
			Vector3 val2 = val - Position;
			return (((Vector3)(ref val2)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref val2)).normalized : Vector3.up;
		}

		private void ApplyEnemyPoison(Enemy target)
		{
			WitchEnemyPoisonDebuff component = ((Component)target).GetComponent<WitchEnemyPoisonDebuff>();
			if ((Object)(object)component != (Object)null)
			{
				component.Refresh();
			}
			else
			{
				component = ((Component)target).gameObject.AddComponent<WitchEnemyPoisonDebuff>();
				component.Initialize(target, poisonDamagePerSecond, poisonDuration, poisonStopThreshold, poisonParticlesMaterial);
			}
			if (SemiFunc.IsMultiplayer())
			{
				PhotonView componentInChildren = ((Component)this).GetComponentInChildren<PhotonView>();
				PhotonView photonView = target.PhotonView;
				if ((Object)(object)componentInChildren != (Object)null && (Object)(object)photonView != (Object)null)
				{
					componentInChildren.RPC("AddEnemyPoisonDebuffRPC", (RpcTarget)0, new object[4] { photonView.ViewID, poisonDamagePerSecond, poisonDuration, poisonStopThreshold });
				}
			}
		}

		private void PopNearbyBalloons()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			Collider[] array = Physics.OverlapSphere(Position, balloonPopRadius);
			if (array.Length == 0)
			{
				return;
			}
			HashSet<BirthdayBoyBalloon> hashSet = new HashSet<BirthdayBoyBalloon>();
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				BirthdayBoyBalloon componentInParent = ((Component)val).GetComponentInParent<BirthdayBoyBalloon>();
				if (!((Object)(object)componentInParent == (Object)null) && !componentInParent.popped && hashSet.Add(componentInParent))
				{
					componentInParent.popped = true;
				}
			}
		}

		[PunRPC]
		public void PlayBreakSoundRPC()
		{
			//IL_000e: 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_0001: 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)
				{
					continue;
				}
				WitchPoisonDebuff component = ((Component)item).GetComponent<WitchPoisonDebuff>();
				if ((Object)(object)component == (Object)null)
				{
					component = ((Component)item).gameObject.AddComponent<WitchPoisonDebuff>();
					component.Initialize(null, dps, duration, stopThreshold, poisonParticlesMaterial);
				}
				else
				{
					component.Refresh();
				}
				break;
			}
		}

		[PunRPC]
		public void AddEnemyPoisonDebuffRPC(int enemyViewID, int dps, float duration, float stopThreshold, PhotonMessageInfo info = default(PhotonMessageInfo))
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (!SemiFunc.MasterOnlyRPC(info))
			{
				return;
			}
			PhotonView val = PhotonView.Find(enemyViewID);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Enemy component = ((Component)val).GetComponent<Enemy>();
			if (!((Object)(object)component == (Object)null) && component.HasHealth && !((Object)(object)component.Health == (Object)null) && !component.Health.dead && component.Health.healthCurrent > 0 && (!((Object)(object)component.EnemyParent != (Object)null) || component.EnemyParent.Spawned))
			{
				WitchEnemyPoisonDebuff component2 = ((Component)component).GetComponent<WitchEnemyPoisonDebuff>();
				if ((Object)(object)component2 == (Object)null)
				{
					component2 = ((Component)component).gameObject.AddComponent<WitchEnemyPoisonDebuff>();
					component2.Initialize(component, dps, duration, stopThreshold, poisonParticlesMaterial);
				}
				else
				{
					component2.Refresh();
				}
			}
		}

		private void DetachAndPlayExplosionParticles()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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;
		}

		public void Refresh()
		{
			_elapsed = 0f;
			_timeUntilNextTick = 1f;
		}

		private void Update()
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			return WitchPoisonParticles.Create(((Component)player).transform, new Vector3(0f, 0.6f, 0f), 0.7f, _particlesMaterial);
		}

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