Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of MCWitchMod v1.2.1
Witch.dll
Decompiled a week agousing 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); } } } }