Decompiled source of TrainersOfAurai v5.2.1

plugins/MadDelayedDamage.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("MadDelayedDamage")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MadDelayedDamage")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("c5450fe0-edcf-483f-b9ea-4b1ef9d36da7")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace MadDelayedDamage;

[BepInPlugin("iggy.mad.delayeddamage", "Mad Delayed Damage", "2.0.0")]
public class DelayedDamage : BaseUnityPlugin
{
	[HarmonyPatch(typeof(ResourcesPrefabManager), "Load")]
	public class ResourcesPrefabManager_Load
	{
		[HarmonyPostfix]
		public static void Postfix()
		{
			ResourcesPrefabManager instance = ResourcesPrefabManager.Instance;
			if (instance != null && instance.Loaded)
			{
				MakeDelayedDamageStatusEffect();
			}
		}
	}

	[HarmonyPatch(typeof(Character), "OnReceiveHit", new Type[]
	{
		typeof(Weapon),
		typeof(float),
		typeof(DamageList),
		typeof(Vector3),
		typeof(Vector3),
		typeof(float),
		typeof(float),
		typeof(Character),
		typeof(float)
	})]
	public class Character_ReceiveHit
	{
		[HarmonyPrefix]
		public static void Prefix(Character __instance, ref float _damage, Character _dealerChar, DamageList _damageList, float _knockBack)
		{
			DelaySomeDamage(__instance, _dealerChar, ref _damage, _damageList, _knockBack);
		}
	}

	public const string GUID = "iggy.mad.delayeddamage";

	public const string VERSION = "2.0.0";

	public const string NAME = "Mad Delayed Damage";

	public static DelayedDamage Instance;

	public StatusEffect DelayedDamageInstance;

	public static Func<Character, Character, DamageList, float, float> GetDamageToDelay = (Character character, Character dealer, DamageList damageList, float damage) => 0f;

	public static Action<Character, Character, float> OnDelayedDamageTaken = delegate
	{
	};

	internal void Awake()
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		new Harmony("iggy.mad.delayeddamage").PatchAll();
	}

	private static void MakeDelayedDamageStatusEffect()
	{
		Instance.DelayedDamageInstance = MadHelper.MakeStatusEffectPrefab("Delayed Damage", "Delayed Damage", "Taking delayed damage over time.", DelayedDamageEffect.LifeSpan, DelayedDamageEffect.RefreshRate, (StackBehaviors)5, "Haunted", isMalusEffect: true, null, null, "iggy.mad.delayeddamage");
		EffectSignature statusEffectSignature = Instance.DelayedDamageInstance.StatusEffectSignature;
		DelayedDamageEffect delayedDamageEffect = MadHelper.MakeFreshObject("Effects", setActive: true, dontDestroyOnLoad: true, ((Component)statusEffectSignature).transform).AddComponent<DelayedDamageEffect>();
		((Effect)delayedDamageEffect).UseOnce = false;
		statusEffectSignature.Effects = new List<Effect> { (Effect)(object)delayedDamageEffect };
	}

	public static void DelaySomeDamage(Character character, Character dealer, ref float damage, DamageList damageList, float knockBack)
	{
		float num = Mathf.Clamp(GetDamageToDelay(character, dealer, damageList, knockBack), 0f, damage);
		if (num > 0f)
		{
			damage -= num;
			DealDelayedDamage(character, dealer, num);
		}
	}

	public static void DealDelayedDamage(Character character, Character dealer, float delayedDamage)
	{
		StatusEffect val = character.StatusEffectMngr.AddStatusEffect("Delayed Damage");
		if ((Object)(object)dealer != (Object)null)
		{
			val.SetSourceCharacter(dealer);
		}
		((EffectSynchronizer)val).SetPotency(delayedDamage);
	}

	public static float GetRemainingDelayedDamage(Character character)
	{
		float? num;
		if ((Object)(object)character == (Object)null)
		{
			num = null;
		}
		else
		{
			StatusEffectManager statusEffectMngr = character.StatusEffectMngr;
			num = (((Object)(object)statusEffectMngr == (Object)null) ? null : (from status in statusEffectMngr.Statuses?.Where((StatusEffect status) => status.IdentifierName == "Delayed Damage")
				select ((EffectSynchronizer)status).EffectPotency)?.Sum());
		}
		float? num2 = num;
		return num2.GetValueOrDefault();
	}
}
public class DelayedDamageEffect : Effect
{
	public static int LifeSpan = 15;

	public static float RefreshRate = 1f;

	public override void ActivateLocally(Character _affectedCharacter, object[] _infos)
	{
		StatusEffect parentStatusEffect = base.m_parentStatusEffect;
		float num = (0f - (((Object)(object)parentStatusEffect != (Object)null) ? ((EffectSynchronizer)parentStatusEffect).EffectPotency : 1f)) / ((float)LifeSpan / RefreshRate);
		_ = base.m_parentStatusEffect;
		Action<Character, Character, float> onDelayedDamageTaken = DelayedDamage.OnDelayedDamageTaken;
		StatusEffect parentStatusEffect2 = base.m_parentStatusEffect;
		onDelayedDamageTaken(_affectedCharacter, (((Object)(object)parentStatusEffect2 != (Object)null) ? ((EffectSynchronizer)parentStatusEffect2).OwnerCharacter : null) ?? null, num);
		_affectedCharacter.Stats.AffectHealth(num);
	}
}
internal class MadHelper
{
	public static class At
	{
		public static BindingFlags flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		public static object Call(object obj, string method, params object[] args)
		{
			MethodInfo method2 = obj.GetType().GetMethod(method, flags);
			if (method2 != null)
			{
				return method2.Invoke(obj, args);
			}
			return null;
		}

		public static void SetValue<T>(T value, Type type, object obj, string field)
		{
			FieldInfo field2 = type.GetField(field, flags);
			if (field2 != null)
			{
				field2.SetValue(obj, value);
			}
		}

		public static object GetValue(Type type, object obj, string value)
		{
			FieldInfo field = type.GetField(value, flags);
			if (field != null)
			{
				return field.GetValue(obj);
			}
			return null;
		}

		public static void InheritBaseValues(object _derived, object _base)
		{
			FieldInfo[] fields = _base.GetType().GetFields(flags);
			foreach (FieldInfo fieldInfo in fields)
			{
				try
				{
					_derived.GetType().GetField(fieldInfo.Name).SetValue(_derived, fieldInfo.GetValue(_base));
				}
				catch
				{
				}
			}
		}
	}

	public class CustomTexture
	{
		public enum SpriteBorderTypes
		{
			None,
			Item,
			TrainerSkill
		}

		public enum IconName
		{
			m_itemIcon,
			SkillTreeIcon
		}

		private static Dictionary<string, byte[]> m_loadedTextures;

		public static string PLUGIN_ROOT_PATH => Directory.GetCurrentDirectory() + "\\BepInEx\\plugins\\";

		private static Dictionary<string, byte[]> LoadedTextures
		{
			get
			{
				if (m_loadedTextures == null)
				{
					m_loadedTextures = new Dictionary<string, byte[]>();
				}
				return m_loadedTextures;
			}
		}

		public static Texture2D LoadTexture(string filePath, int mipCount, bool linear, FilterMode filterMode, float? mipMapBias = null)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			filePath = PLUGIN_ROOT_PATH + filePath;
			if (!LoadedTextures.ContainsKey(filePath))
			{
				LoadedTextures[filePath] = File.ReadAllBytes(filePath);
			}
			Texture2D val = new Texture2D(4, 4, (TextureFormat)12, mipCount > 0, linear);
			((Texture)val).filterMode = filterMode;
			((Texture)val).mipMapBias = mipMapBias ?? ((Texture)val).mipMapBias;
			ImageConversion.LoadImage(val, LoadedTextures[filePath]);
			((Texture)val).filterMode = (FilterMode)1;
			return val;
		}

		public static Sprite MakeSprite(Texture2D texture, SpriteBorderTypes spriteBorderType)
		{
			//IL_0069: 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)
			float num;
			float num2;
			float num3;
			float num4;
			switch (spriteBorderType)
			{
			default:
				num = 0f;
				num2 = 0f;
				num3 = 0f;
				num4 = 0f;
				break;
			case SpriteBorderTypes.TrainerSkill:
				num = 1f;
				num2 = 1f;
				num3 = 1f;
				num4 = 2f;
				break;
			case SpriteBorderTypes.Item:
				num = 1f;
				num2 = 2f;
				num3 = 2f;
				num4 = 3f;
				break;
			}
			return Sprite.Create(texture, new Rect(num, num3, (float)((Texture)texture).width - num2, (float)((Texture)texture).height - num4), new Vector2(0f, 0f), 100f, 0u);
		}
	}

	public static StatusEffect MakeStatusEffectPrefab(string effectName, string familyName, string description, float lifespan, float refreshRate, StackBehaviors stackBehavior, string targetStatusName, bool isMalusEffect, string tagID = null, UID? uid = null, string modGUID = null, string iconFileName = null, string displayName = null)
	{
		//IL_001b: 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_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_0167: Expected O, but got Unknown
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Expected O, but got Unknown
		//IL_017b: Expected O, but got Unknown
		//IL_0201: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_021e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0223: Unknown result type (might be due to invalid IL or missing references)
		//IL_022a: Expected O, but got Unknown
		//IL_023f: Expected O, but got Unknown
		//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
		Dictionary<string, StatusEffect> obj = At.GetValue(typeof(ResourcesPrefabManager), null, "STATUSEFFECT_PREFABS") as Dictionary<string, StatusEffect>;
		StatusEffectFamily val = MakeStatusEffectFamiliy(familyName, stackBehavior, -1, (LengthTypes)0);
		GameObject val2 = InstantiateClone(((Component)obj[targetStatusName]).gameObject, effectName, setActive: false, dontDestroyOnLoad: true);
		StatusEffect obj2 = val2.GetComponent<StatusEffect>() ?? val2.AddComponent<StatusEffect>();
		StatusEffect val3 = obj2;
		obj[effectName] = obj2;
		StatusEffect val4 = val3;
		At.SetValue(effectName, typeof(StatusEffect), val4, "m_identifierName");
		At.SetValue<StatusEffectFamily>(val, typeof(StatusEffect), val4, "m_bindFamily");
		At.SetValue(displayName ?? effectName, typeof(StatusEffect), val4, "m_nameLocKey");
		At.SetValue(description, typeof(StatusEffect), val4, "m_descriptionLocKey");
		val4.RefreshRate = refreshRate;
		val4.IsMalusEffect = isMalusEffect;
		At.SetValue<EffectSignatureModes>((EffectSignatureModes)1, typeof(StatusEffect), val4, "m_effectSignatureMode");
		At.SetValue<FamilyModes>((FamilyModes)0, typeof(StatusEffect), val4, "m_familyMode");
		val4.RequiredStatus = null;
		val4.RemoveRequiredStatus = false;
		if (iconFileName != null)
		{
			val4.OverrideIcon = CustomTexture.MakeSprite(CustomTexture.LoadTexture(iconFileName, 0, linear: false, (FilterMode)0), CustomTexture.SpriteBorderTypes.None);
		}
		At.SetValue<TagSourceSelector>((tagID != null) ? new TagSourceSelector(TagSourceManager.Instance.GetTag(UID.op_Implicit(tagID))) : new TagSourceSelector(), typeof(StatusEffect), val4, "m_effectType");
		StatusData val5 = new StatusData(val4.StatusData);
		StatusData val6 = val5;
		val4.StatusData = val5;
		StatusData val7 = val6;
		val7.LifeSpan = lifespan;
		(At.GetValue(typeof(StatusEffect), val4, "m_statusStack") as List<StatusData>)[0] = val7;
		Object.Destroy((Object)(object)((Component)val2.GetComponentInChildren<EffectSignature>()).gameObject);
		EffectSignature val8 = MakeFreshObject("Signature", setActive: true, dontDestroyOnLoad: true).AddComponent<EffectSignature>();
		((Object)val8).name = "Signature";
		val8.SignatureUID = (UID)(((??)uid) ?? ((modGUID != null) ? MakeUID(effectName, modGUID, "Status Effect") : UID.Generate()));
		EffectSignature effectSignature = (val7.EffectSignature = val8);
		val.EffectSignature = effectSignature;
		StatusEffectFamilySelector val10 = new StatusEffectFamilySelector();
		((UidSelector<StatusEffectFamily>)val10).Set(val);
		At.SetValue<StatusEffectFamilySelector>(val10, typeof(StatusEffect), val4, "m_stackingFamily");
		return val4;
	}

	public static StatusEffectFamily MakeStatusEffectFamiliy(string familyName, StackBehaviors stackBehavior, int maxStackCount, LengthTypes lengthType, UID? uid = null, string modGUID = null)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Expected O, but got Unknown
		//IL_0030: 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_005e: 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_006c: 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_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		StatusEffectFamily val = new StatusEffectFamily();
		uid = (UID)(((??)uid) ?? ((modGUID != null) ? MakeUID(familyName, modGUID, "Status Effect Family") : UID.Generate()));
		At.SetValue<UID>(uid.Value, typeof(StatusEffectFamily), val, "m_uid");
		val.Name = familyName;
		val.StackBehavior = stackBehavior;
		val.MaxStackCount = maxStackCount;
		val.LengthType = lengthType;
		return val;
	}

	public static GameObject InstantiateClone(GameObject sourceGameObject, bool setActive, bool dontDestroyOnLoad)
	{
		return InstantiateClone(sourceGameObject, ((Object)sourceGameObject).name + "(Clone)", setActive, dontDestroyOnLoad);
	}

	public static GameObject InstantiateClone(GameObject sourceGameObject, string newGameObjectName, bool setActive, bool dontDestroyOnLoad)
	{
		GameObject val = Object.Instantiate<GameObject>(sourceGameObject);
		val.SetActive(setActive);
		((Object)val).name = newGameObjectName;
		if (dontDestroyOnLoad)
		{
			Object.DontDestroyOnLoad((Object)(object)val);
		}
		return val;
	}

	public static UID MakeUID(string name, string modGUID, string category)
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		return new UID((modGUID + "." + category + "." + name).Replace(" ", "").ToLower());
	}

	public static GameObject MakeFreshObject(string newGameObjectName, bool setActive, bool dontDestroyOnLoad, Transform parent = null)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		GameObject val = new GameObject(newGameObjectName);
		val.SetActive(setActive);
		if ((Object)(object)parent != (Object)null)
		{
			val.transform.SetParent(parent);
		}
		if (dontDestroyOnLoad)
		{
			RecursiveDontDestroyOnLoad(val.transform);
		}
		return val;
	}

	public static void RecursiveDontDestroyOnLoad(Transform transform)
	{
		Transform val = transform;
		while ((Object)(object)val.parent != (Object)null)
		{
			val = val.parent;
		}
		Object.DontDestroyOnLoad((Object)(object)((Component)val).gameObject);
	}
}

plugins/TrainersOfAurai.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using AscendedClass;
using AuraiTrainers;
using AuraiTrainers.Apothecary;
using AuraiTrainers.Shady;
using AuraiUtility;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CustomAttributes;
using HarmonyLib;
using Lorewalker;
using MadDelayedDamage;
using NodeCanvas.DialogueTrees;
using NodeCanvas.Framework;
using NodeCanvas.Tasks.Actions;
using Photon;
using Shinobi;
using SideLoader;
using SideLoader.Managers;
using SideLoader.Model;
using SideLoader.SLPacks.Categories;
using SideLoader.SaveData;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.UI;
using WhispererClass;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("TrainersOfAurai")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TrainersOfAurai")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("215c80fe-e43c-4f33-9d00-af448d901a86")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[BepInPlugin("com.iggy.trainersofaurai", "Trainers of Aurai", "6.0.0")]
public class Plugin : BaseUnityPlugin
{
	[HarmonyPatch(typeof(Character), "Awake")]
	public class CharacterAwakePatch
	{
		private static void Postfix(Character __instance)
		{
			if ((Object)(object)__instance != (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<PlayerVariableComponent>();
			}
		}
	}

	private const string GUID = "com.iggy.trainersofaurai";

	private const string NAME = "Trainers of Aurai";

	private const string VERSION = "6.0.0";

	public static Plugin Instance;

	internal static ManualLogSource _Log;

	public const string SL_VISUAL_TRANSFORM = "SLVISUALCONTAINER";

	public static ConfigEntry<bool> AddTestItems;

	public static ConfigEntry<bool> ShowDebugLog;

	internal void Awake()
	{
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		Debug.Log((object)"Trainers of Aurai awake");
		GameObject gameObject = ((Component)this).gameObject;
		_Log = ((BaseUnityPlugin)this).Logger;
		gameObject.AddComponent<DrinkManager>();
		gameObject.AddComponent<FlowManager>();
		gameObject.AddComponent<CraftManager>();
		gameObject.AddComponent<MadDamageManager>();
		gameObject.AddComponent<MadExtrasManager>();
		gameObject.AddComponent<MadQuestManager>();
		gameObject.AddComponent<MagesDamageManager>();
		gameObject.AddComponent<MagesExtrasManager>();
		SL.OnPacksLoaded += SL_OnPacksLoaded;
		new Harmony("com.iggy.trainersofaurai").PatchAll();
		setCustomAttributes();
	}

	private void SL_OnPacksLoaded()
	{
		DialogueManager.Init();
		TrainerSpawn.Init();
		ShinobiStageSettup.BaseSetup();
		LocalsManager.Init();
		HeavyManager.Init();
		DodgePlayerManager.Init();
	}

	internal void Start()
	{
		Debug.Log((object)"Trainers of Aurai - Loaded");
		CustomAttSub();
	}

	internal void CustomAttSub()
	{
		CustomAttributesBase instance = CustomAttributesBase.Instance;
		instance.OnCharacterAvoidEvent = (Action<Character, Character, float>)Delegate.Combine(instance.OnCharacterAvoidEvent, new Action<Character, Character, float>(TimeWalkerManager.AvoidRewind));
		CustomAttributesBase instance2 = CustomAttributesBase.Instance;
		instance2.OnCharacterLeechEvent = (Action<Character, Character, float>)Delegate.Combine(instance2.OnCharacterLeechEvent, new Action<Character, Character, float>(ShinobiSkills.LeechHeal));
	}

	internal void setCustomAttributes()
	{
		CustomAttributeHelper.PassiveLeechStore(ShinobiIDs.chakraLeech, ShinobiBalance.chakraLeechBonus);
		CustomAttributeHelper.StatusAvoidanceStore(TimeWalkerIDs.timeline3Survival, (float)LoreWalkerBalance.survTAvoidChance);
		CustomAttributeHelper.PassiveCritRateStore(SpellslingerIDs.luckyStrikeID, (float)SpellslingerBalance.luckyStrikeCritChance);
		CustomAttributeHelper.StatusCritRateStore(SpellslingerIDs.streakBuffID, (float)SpellslingerBalance.streakBonusChance);
		CustomAttributeHelper.StatusCritCancelerStore(SpellslingerIDs.gunReloaderID, 0f);
		CustomAttributeHelper.PassiveSelfCritStore(SpellslingerIDs.luckyStrikeID, (float)SpellslingerBalance.luckyStrikeAIc);
		CustomAttributeHelper.PassiveCritScalingStore(SpellslingerIDs.critAdjustID, (float)SpellslingerBalance.critAdjustmentBonus);
	}
}
namespace PastSelf
{
	public static class PastManager
	{
		private static Character[] players;

		private static int[] pastSkills;

		private static int silverID = 9000010;
	}
}
namespace Shinobi
{
	public static class ShinobiNinjutsuManager
	{
		[HarmonyPatch(typeof(StatusEffectManager), "AddStatusEffect", new Type[]
		{
			typeof(StatusEffect),
			typeof(Character),
			typeof(string[])
		})]
		public class StatusEffectManager_AddStatusEffect
		{
			[HarmonyPostfix]
			public static void Postfix(StatusEffectManager __instance, StatusEffect _statusEffect, Character _dealer, string[] _loadData)
			{
				if (__instance.m_character.IsLocalPlayer && ShinobiIDs.Mudras.ContainsValue(_statusEffect.IdentifierName))
				{
					CheckActiveMudras(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(LevelAttackSkill), "get_QuickSlotIcon")]
		public class LevelAttackSkill_QuickSlotIcon
		{
			public static bool Prefix(ref Sprite __result, LevelAttackSkill __instance)
			{
				if (((Item)__instance).ItemID == ShinobiIDs.ninjutsuID && !((Item)__instance).m_ownerCharacter.StatusEffectMngr.HasStatusEffect(ShinobiIDs.activeJutsu))
				{
					Sprite val = null;
					val = ((!((CharacterKnowledge)((Item)__instance).m_ownerCharacter.Inventory.SkillKnowledge).IsItemLearned(ShinobiIDs.ToolMaster)) ? ShinobiStageSettup.baseNinjutsuSprite : ShinobiStageSettup.altNinjutsuSprite);
					if ((Object)(object)val != (Object)null)
					{
						__result = val;
						return false;
					}
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(QuickSlotDisplay), "Update")]
		public class QuickSlotDisplay_Update
		{
			public static void Postfix(QuickSlotDisplay __instance)
			{
				if (!((UIElement)__instance).LocalCharacter.IsLocalPlayer)
				{
					return;
				}
				int itemID = __instance.m_refQuickSlot.ItemID;
				PlayerVariableComponent component = ((Component)((UIElement)__instance).LocalCharacter).GetComponent<PlayerVariableComponent>();
				if (!Object.op_Implicit((Object)(object)component))
				{
					return;
				}
				if (ShinobiIDs.Mudras.ContainsKey(itemID))
				{
					((Component)__instance.m_lblStackCount).gameObject.SetActive(true);
					int num = 0;
					if (itemID == ShinobiIDs.MudraTen)
					{
						num = component.MudraTenStacks;
					}
					else if (itemID == ShinobiIDs.MudraChi)
					{
						num = component.MudraChiStacks;
					}
					else if (itemID == ShinobiIDs.MudraJin)
					{
						num = component.MudraJinStacks;
					}
					__instance.m_lblStackCount.text = num.ToString();
				}
				else if (itemID == ShinobiIDs.ninjutsuID)
				{
					__instance.m_lblStackCount.text = ((UIElement)__instance).LocalCharacter.Inventory.ItemEquippedCount(ShinobiIDs.ninjaScroll).ToString();
				}
				else
				{
					__instance.m_lblStackCount.text = "";
				}
			}
		}

		[HarmonyPatch(typeof(QuiverDisplay), "Update")]
		public class QuiverDisplay_Update
		{
			[HarmonyPrefix]
			public static void Postfix(QuiverDisplay __instance)
			{
				CharacterInventory inventory = ((UIElement)__instance).LocalCharacter.Inventory;
				if (inventory.Equipment.IsEquipmentSlotEmpty((EquipmentSlotIDs)8))
				{
					return;
				}
				Image componentInChildren = ((Component)__instance).gameObject.GetComponentInChildren<Image>();
				if (inventory.HasEquipped(ShinobiIDs.ninjaScroll))
				{
					if ((Object)(object)componentInChildren.sprite != (Object)(object)ShinobiStageSettup.ninjaScrollSprite)
					{
						componentInChildren.sprite = ShinobiStageSettup.ninjaScrollSprite;
					}
				}
				else if (!inventory.HasEquipped(2501017) && (Object)(object)componentInChildren.sprite != (Object)(object)ShinobiStageSettup.vanillaArrowSprite)
				{
					componentInChildren.sprite = ShinobiStageSettup.vanillaArrowSprite;
				}
			}
		}

		[HarmonyPatch(typeof(Skill), "InCooldown")]
		private class Skill_InCooldown
		{
			private static bool Prefix(ref bool __result, Skill __instance)
			{
				if (((EffectSynchronizer)__instance).OwnerCharacter.IsLocalPlayer)
				{
					PlayerVariableComponent component = ((Component)((EffectSynchronizer)__instance).OwnerCharacter).GetComponent<PlayerVariableComponent>();
					if (Object.op_Implicit((Object)(object)component))
					{
						if (((Item)__instance).ItemID == ShinobiIDs.MudraTen)
						{
							if (component.MudraTenStacks >= 1)
							{
								__result = false;
							}
							else
							{
								__instance.m_remainingCooldownTime = component.ShinobiTenCooldown;
								__result = true;
							}
							return false;
						}
						if (((Item)__instance).ItemID == ShinobiIDs.MudraChi)
						{
							if (component.MudraChiStacks >= 1)
							{
								__result = false;
							}
							else
							{
								__instance.m_remainingCooldownTime = component.ShinobiChiCooldown;
								__result = true;
							}
							return false;
						}
						if (((Item)__instance).ItemID == ShinobiIDs.MudraJin)
						{
							if (component.MudraJinStacks >= 1)
							{
								__result = false;
							}
							else
							{
								__instance.m_remainingCooldownTime = component.ShinobiJinCooldown;
								__result = true;
							}
							return false;
						}
					}
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(AttackSkill), "GetStaminaCost")]
		public class AttackSkill_GetStaminaCost
		{
			public static void Postfix(ref float __result, AttackSkill __instance)
			{
				if (((Item)__instance).ItemID == ShinobiIDs.ninjutsuID)
				{
					__result /= 4f;
				}
			}
		}

		[HarmonyPatch(typeof(Skill), "OwnerHasAllRequiredItems")]
		public class Skill_OwnerHasAllRequiredItems
		{
			public static bool Prefix(ref bool __result, Skill __instance, bool _tryingToActivate)
			{
				if (((EffectSynchronizer)__instance).OwnerCharacter.IsLocalPlayer && ((Item)__instance).ItemID == ShinobiIDs.ninjutsuID)
				{
					if (((EffectSynchronizer)__instance).OwnerCharacter.Inventory.HasEquipped(ShinobiIDs.ninjaScroll))
					{
						__result = true;
						return false;
					}
					__result = false;
					return false;
				}
				return true;
			}
		}

		private static void CheckActiveMudras(StatusEffectManager effectManager)
		{
			bool flag = false;
			bool flag2 = false;
			bool flag3 = false;
			string text = ShinobiIDs.Mudras[ShinobiIDs.MudraTen];
			string text2 = ShinobiIDs.Mudras[ShinobiIDs.MudraChi];
			string text3 = ShinobiIDs.Mudras[ShinobiIDs.MudraJin];
			foreach (StatusEffect status in effectManager.Statuses)
			{
				if (status.IdentifierName == text)
				{
					flag = true;
				}
				else if (status.IdentifierName == text2)
				{
					flag2 = true;
				}
				else if (status.IdentifierName == text3)
				{
					flag3 = true;
				}
			}
			if (flag || flag2 || flag3)
			{
				SetActiveJutsu(effectManager, flag, flag2, flag3);
			}
		}

		private static void SetActiveJutsu(StatusEffectManager effectManager, bool Ten, bool Chi, bool Jin)
		{
			if (!effectManager.HasStatusEffect(ShinobiIDs.activeJutsu))
			{
				effectManager.AddStatusEffect(ShinobiIDs.activeJutsu);
			}
			StatusEffect statusEffectOfName = effectManager.GetStatusEffectOfName(ShinobiIDs.activeJutsu);
			LevelStatusEffect val = (LevelStatusEffect)(object)((statusEffectOfName is LevelStatusEffect) ? statusEffectOfName : null);
			if (Ten)
			{
				if (Chi)
				{
					if (Jin)
					{
						val.m_currentLevel = 7;
					}
					else
					{
						val.m_currentLevel = 4;
					}
				}
				else if (Jin)
				{
					val.m_currentLevel = 6;
				}
				else
				{
					val.m_currentLevel = 1;
				}
			}
			else if (Chi)
			{
				if (Jin)
				{
					val.m_currentLevel = 5;
				}
				else
				{
					val.m_currentLevel = 2;
				}
			}
			else if (Jin)
			{
				val.m_currentLevel = 3;
			}
			val.NotifiyParentManagerOfLevelChange();
			val.OnLevelHasChanged();
		}
	}
	internal static class ShinobiSkills
	{
		[HarmonyPatch(typeof(Skill), "StartEffectsCast")]
		public class Skill_StartEffectsCast
		{
			[HarmonyPrefix]
			public static void Prefix(Skill __instance, Character _targetChar)
			{
				Character ownerCharacter = ((EffectSynchronizer)__instance).OwnerCharacter;
				if (ownerCharacter == null || !ownerCharacter.IsLocalPlayer)
				{
					return;
				}
				PlayerVariableComponent component = ((Component)((EffectSynchronizer)__instance).OwnerCharacter).GetComponent<PlayerVariableComponent>();
				if (Object.op_Implicit((Object)(object)component))
				{
					if (((Item)__instance).ItemID == ShinobiIDs.ninjutsuID)
					{
						NinjutsuEffects(((EffectSynchronizer)__instance).OwnerCharacter, __instance);
					}
					if (((Item)__instance).ItemID == ShinobiIDs.MudraTen)
					{
						component.MudraTenStacks--;
					}
					else if (((Item)__instance).ItemID == ShinobiIDs.MudraChi)
					{
						component.MudraChiStacks--;
					}
					else if (((Item)__instance).ItemID == ShinobiIDs.MudraJin)
					{
						component.MudraJinStacks--;
					}
				}
			}
		}

		[HarmonyPatch(typeof(SL_CharacterAIMelee), "ApplyToCharacter")]
		public class SL_CharacterAIMelee_ApplyToCharacter
		{
			[HarmonyPrefix]
			public static bool Prefix(SL_CharacterAIMelee __instance, Character character)
			{
				//IL_0019: 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_0067: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_010c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0112: Invalid comparison between Unknown and I4
				//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
				//IL_0206: Unknown result type (might be due to invalid IL or missing references)
				//IL_027c: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
				//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0324: Unknown result type (might be due to invalid IL or missing references)
				//IL_039a: Unknown result type (might be due to invalid IL or missing references)
				//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0407: Unknown result type (might be due to invalid IL or missing references)
				//IL_0449: Unknown result type (might be due to invalid IL or missing references)
				//IL_044e: Unknown result type (might be due to invalid IL or missing references)
				//IL_045f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0464: Unknown result type (might be due to invalid IL or missing references)
				//IL_0489: Unknown result type (might be due to invalid IL or missing references)
				//IL_048e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0500: Unknown result type (might be due to invalid IL or missing references)
				//IL_0520: Unknown result type (might be due to invalid IL or missing references)
				//IL_0122: Unknown result type (might be due to invalid IL or missing references)
				//IL_0131: Unknown result type (might be due to invalid IL or missing references)
				//IL_0138: Expected O, but got Unknown
				//IL_0168: Unknown result type (might be due to invalid IL or missing references)
				//IL_016d: 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_0195: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
				if (!character.Name.Contains("Ranged"))
				{
					return true;
				}
				AIRoot val = new GameObject("BasicMelee_AIRoot").AddComponent<AIRoot>();
				((Component)val).gameObject.SetActive(false);
				((Component)val).transform.parent = ((Component)character).transform;
				AISWander val2 = new GameObject("1_Wander").AddComponent<AISWander>();
				((Component)val2).transform.parent = ((Component)val).transform;
				AISSuspicious val3 = new GameObject("2_Suspicious").AddComponent<AISSuspicious>();
				((Component)val3).transform.parent = ((Component)val).transform;
				AISSuspicious val4 = new GameObject("3_Alert").AddComponent<AISSuspicious>();
				((Component)val4).transform.parent = ((Component)val).transform;
				AISCombatRanged val5 = new GameObject("4_Combat").AddComponent<AISCombatRanged>();
				((Component)val5).transform.parent = ((Component)val).transform;
				((AIState)val2).ContagionRange = __instance.AIContagionRange;
				((AIState)val2).ForceNotCombat = ((SL_CharacterAI)__instance).ForceNonCombat;
				val2.SpeedModif = __instance.Wander_Speed;
				val2.WanderFar = ((SL_CharacterAI)__instance).CanWanderFar;
				val2.AutoFollowPlayer = __instance.Wander_FollowPlayer;
				if (__instance.Wander_PatrolWaypoints != null && (int)__instance.Wander_Type == 1)
				{
					GameObject val6 = new GameObject($"Waypoints_{character.UID}");
					val2.WaypointsParent = val6.transform;
					for (int i = 0; i < __instance.Wander_PatrolWaypoints.Length; i++)
					{
						GameObject val7 = new GameObject("Waypoint " + i + 1);
						Waypoint val8 = val7.AddComponent<Waypoint>();
						val7.transform.parent = val6.transform;
						val7.transform.position = __instance.Wander_PatrolWaypoints[i].WorldPosition;
						val8.RandomRadius = __instance.Wander_PatrolWaypoints[i].RandomRadius;
						val8.WaitTime = __instance.Wander_PatrolWaypoints[i].WaitTime;
					}
				}
				AICEnemyDetection val9 = new GameObject("Detection").AddComponent<AICEnemyDetection>();
				((Component)val9).transform.parent = ((Component)val2).transform;
				AIESwitchState val10 = new GameObject("DetectEffects").AddComponent<AIESwitchState>();
				val10.ToState = (AIState)(object)val3;
				((Component)val10).transform.parent = ((Component)val9).transform;
				val9.DetectEffectsTrans = ((Component)val10).transform;
				((AISWander)val3).SpeedModif = __instance.Suspicious_Speed;
				val3.SuspiciousDuration = __instance.Suspicious_Duration;
				((AISWander)val3).Range = __instance.Suspicious_Range;
				((AISWander)val3).WanderFar = ((SL_CharacterAI)__instance).CanWanderFar;
				((AISWander)val3).TurnModif = __instance.Suspicious_TurnModif;
				AIESwitchState val11 = new GameObject("EndSuspiciousEffects").AddComponent<AIESwitchState>();
				val11.ToState = (AIState)(object)val2;
				((Component)val11).gameObject.AddComponent<AIESheathe>().Sheathed = true;
				((Component)val11).transform.parent = ((Component)val3).transform;
				val3.EndSuspiciousEffectsTrans = ((Component)val11).transform;
				AICEnemyDetection val12 = new GameObject("Detection").AddComponent<AICEnemyDetection>();
				((Component)val12).transform.parent = ((Component)val3).transform;
				AIESwitchState val13 = new GameObject("DetectEffects").AddComponent<AIESwitchState>();
				val13.ToState = (AIState)(object)val5;
				((Component)val13).transform.parent = ((Component)val12).transform;
				val12.DetectEffectsTrans = ((Component)val13).transform;
				AIESwitchState val14 = new GameObject("SuspiciousEffects").AddComponent<AIESwitchState>();
				val14.ToState = (AIState)(object)val4;
				((Component)val14).transform.parent = ((Component)val12).transform;
				val12.SuspiciousEffectsTrans = ((Component)val14).transform;
				((AISWander)val4).SpeedModif = __instance.Suspicious_Speed;
				val4.SuspiciousDuration = __instance.Suspicious_Duration;
				((AISWander)val4).Range = __instance.Suspicious_Range;
				((AISWander)val4).WanderFar = ((SL_CharacterAI)__instance).CanWanderFar;
				((AISWander)val4).TurnModif = __instance.Suspicious_TurnModif;
				AIESwitchState val15 = new GameObject("EndSuspiciousEffects").AddComponent<AIESwitchState>();
				val15.ToState = (AIState)(object)val3;
				((Component)val15).gameObject.AddComponent<AIESheathe>().Sheathed = true;
				((Component)val15).transform.parent = ((Component)val4).transform;
				val4.EndSuspiciousEffectsTrans = ((Component)val15).transform;
				AICEnemyDetection val16 = new GameObject("Detection").AddComponent<AICEnemyDetection>();
				((Component)val16).transform.parent = ((Component)val4).transform;
				AIESwitchState val17 = new GameObject("DetectEffects").AddComponent<AIESwitchState>();
				val17.ToState = (AIState)(object)val5;
				((Component)val17).transform.parent = ((Component)val16).transform;
				val16.DetectEffectsTrans = ((Component)val17).transform;
				val5.ChargeTime = new Vector2(1f, 1.5f);
				val5.Range = new Vector2(2f, 20f);
				val5.AimPrediction = 100f;
				val5.AlwaysAim = true;
				val5.AimRandom = new Vector2(0f, 0.5f);
				val5.SpeedModifs = new float[3] { 0.3f, 0.6f, 1f };
				((AISCombat)val5).ChanceToAttack = 100f;
				val5.ShootChargeWeapon = true;
				val5.StaticCombatStyle = false;
				((AISCombat)val5).KnowsUnblockable = __instance.Combat_KnowsUnblockable;
				((AISCombat)val5).DodgeCooldown = __instance.Combat_DodgeCooldown;
				((AISCombat)val5).CanBlock = ((SL_CharacterAI)__instance).CanBlock;
				((AISCombat)val5).CanDodge = ((SL_CharacterAI)__instance).CanDodge;
				((Component)new GameObject("Detection").AddComponent<AICEnemyDetection>()).transform.parent = ((Component)val5).transform;
				AIESwitchState obj = new GameObject("EndCombatEffects").AddComponent<AIESwitchState>();
				obj.ToState = (AIState)(object)val2;
				((Component)obj).transform.parent = ((Component)val5).transform;
				((Component)character).gameObject.AddComponent<NavMeshAgent>();
				((Component)character).gameObject.AddComponent<AISquadMember>();
				((Component)character).gameObject.AddComponent<EditorCharacterAILoadAI>();
				NavMeshObstacle component = ((Component)character).GetComponent<NavMeshObstacle>();
				if ((Object)(object)component != (Object)null)
				{
					Object.Destroy((Object)(object)component);
				}
				CharacterAI obj2 = ((Component)character).gameObject.AddComponent<CharacterAI>();
				((CharacterControl)obj2).m_character = character;
				obj2.AIStatesPrefab = val;
				obj2.GetAIStates();
				return false;
			}
		}

		public static void LeechHeal(Character player, Character enemy, float leechAmount)
		{
			if (player.StatusEffectMngr.HasStatusEffect(ShinobiIDs.gentleFistEffect) && ((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(ShinobiIDs.FistPlus))
			{
				player.CharacterUI.ShowInfoNotification("HP +" + leechAmount);
				player.Stats.AffectHealth(leechAmount);
			}
		}

		private static void NinjutsuEffects(Character player, Skill jutsu)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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)
			//IL_003e: 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_004a: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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)
			int statusLevel = player.StatusEffectMngr.GetStatusLevel(ShinobiIDs.activeJutsu);
			SpellCastModifier castModifier = (SpellCastModifier)2;
			SpellCastModifier castModifier2 = (SpellCastModifier)0;
			SpellCastModifier castModifier3 = (SpellCastModifier)1;
			if (player.StatusEffectMngr.HasStatusEffect(ShinobiIDs.activeJutsu))
			{
				switch (statusLevel)
				{
				case 1:
					((Item)jutsu).CastModifier = castModifier;
					break;
				case 2:
					((Item)jutsu).CastModifier = castModifier;
					break;
				case 4:
					((Item)jutsu).CastModifier = castModifier2;
					break;
				case 3:
					((Item)jutsu).CastModifier = castModifier2;
					((MonoBehaviour)Plugin.Instance).StartCoroutine(SummonBunshinMelee(player));
					break;
				case 5:
					((Item)jutsu).CastModifier = castModifier2;
					break;
				case 6:
					((Item)jutsu).CastModifier = castModifier2;
					((MonoBehaviour)Plugin.Instance).StartCoroutine(SummonBunshinRanged(player));
					break;
				case 7:
				{
					((Item)jutsu).CastModifier = castModifier2;
					TargetingSystem targetingSystem = player.TargetingSystem;
					if (targetingSystem != null && targetingSystem.Locked)
					{
						Character lockedCharacter = player.TargetingSystem.LockedCharacter;
						if (Object.op_Implicit((Object)(object)lockedCharacter) && lockedCharacter.IsAI)
						{
							((MonoBehaviour)Plugin.Instance).StartCoroutine(GenjutsuTimer(player, lockedCharacter));
						}
					}
					break;
				}
				default:
					((Item)jutsu).CastModifier = castModifier2;
					break;
				}
			}
			else
			{
				((Item)jutsu).CastModifier = castModifier3;
			}
		}

		public static IEnumerator SummonBunshinMelee(Character player)
		{
			Vector3 spawneePos = ((Component)player).transform.position - ((Component)player).transform.forward + ((Component)player).transform.right;
			Quaternion rotation = ((Component)player).transform.rotation;
			Vector3 spawneeRot = ((Quaternion)(ref rotation)).eulerAngles;
			string spawneeID = SummonIDs.BunshinSpawn;
			yield return (object)new WaitForSeconds(0.5f);
			Character SummonedClone = CharacterHelpers.SpawnCharacter(spawneeID, spawneePos, spawneeRot);
			Character _target = null;
			TargetingSystem targetingSystem = player.TargetingSystem;
			if (targetingSystem != null && targetingSystem.Locked)
			{
				_target = player.TargetingSystem.LockedCharacter;
			}
			yield return (object)new WaitForSeconds(0.2f);
			if ((Object)(object)player.CurrentWeapon != (Object)null && (int)player.CurrentWeapon.Type != 200)
			{
				SummonedClone.TryGenerateAndEquipItemByItemID(((Item)player.CurrentWeapon).ItemID);
			}
			yield return (object)new WaitForSeconds(1f);
			if (Object.op_Implicit((Object)(object)_target) && _target.IsAI && _target.Alive && Object.op_Implicit((Object)(object)_target.LockingPoint))
			{
				SummonedClone.TargetingSystem.SwitchTarget(_target.LockingPoint);
			}
			yield return (object)new WaitForSeconds(ShinobiBalance.BunshinMeleeDuration);
			SummonedClone.ReceiveDamage(100f, Vector3.zero, true);
		}

		public static IEnumerator SummonBunshinRanged(Character player)
		{
			Vector3 spawneePos1 = ((Component)player).transform.position - ((Component)player).transform.forward + ((Component)player).transform.right;
			Vector3 spawneePos2 = ((Component)player).transform.position - ((Component)player).transform.forward - ((Component)player).transform.right;
			Quaternion rotation = ((Component)player).transform.rotation;
			Vector3 spawneeRot = ((Quaternion)(ref rotation)).eulerAngles;
			string spawneeID = SummonIDs.ArcherSpawn;
			yield return (object)new WaitForSeconds(0.5f);
			Character SummonedClone1 = CharacterHelpers.SpawnCharacter(spawneeID, spawneePos1, spawneeRot);
			Character SummonedClone2 = CharacterHelpers.SpawnCharacter(spawneeID, spawneePos2, spawneeRot);
			Character _target = null;
			TargetingSystem targetingSystem = player.TargetingSystem;
			if (targetingSystem != null && targetingSystem.Locked)
			{
				_target = player.TargetingSystem.LockedCharacter;
			}
			yield return (object)new WaitForSeconds(0.2f);
			SummonedClone1.TryGenerateAndEquipItemByItemID(5200001);
			SummonedClone2.TryGenerateAndEquipItemByItemID(5200001);
			yield return (object)new WaitForSeconds(1f);
			if (Object.op_Implicit((Object)(object)_target) && _target.IsAI && _target.Alive && Object.op_Implicit((Object)(object)_target.LockingPoint))
			{
				SummonedClone1.TargetingSystem.SwitchTarget(_target.LockingPoint);
				SummonedClone2.TargetingSystem.SwitchTarget(_target.LockingPoint);
			}
			yield return (object)new WaitForSeconds(ShinobiBalance.BunshinRangedDuration);
			if (SummonedClone1 != null)
			{
				SummonedClone1.ReceiveDamage(100f, Vector3.zero, true);
			}
			if (SummonedClone2 != null)
			{
				SummonedClone2.ReceiveDamage(100f, Vector3.zero, true);
			}
		}

		private static IEnumerator GenjutsuTimer(Character player, Character _target)
		{
			player.StatusEffectMngr.AddStatusEffect(ShinobiIDs.genjutsuEffect);
			player.CharacterUI.ShowInfoNotification("Genjutsu");
			player.TargetingSystem.AcquireRandomTarget();
			Factions oldFaction = _target.Faction;
			_target.Knock(false);
			yield return (object)new WaitForSeconds(0.5f);
			_target.ChangeFaction(player.Faction, true);
			_target.TargetingSystem.AcquireRandomTarget();
			yield return (object)new WaitForSeconds(ShinobiBalance.genjutsuDuration);
			_target.Knock(false);
			_target.ChangeFaction(oldFaction, true);
			_target.TargetingSystem.AcquireRandomTarget();
		}
	}
	public static class ShinobiStageSettup
	{
		private static string jutsuIcon = "NinjutsuIcon";

		public static Sprite ninjaScrollSprite;

		public static Sprite vanillaArrowSprite;

		public static Sprite baseNinjutsuSprite;

		public static Sprite altNinjutsuSprite;

		public static Dictionary<int, SpellCastType> NinjaAnim = new Dictionary<int, SpellCastType>
		{
			{
				0,
				(SpellCastType)24
			},
			{
				1,
				(SpellCastType)500
			},
			{
				2,
				(SpellCastType)506
			},
			{
				3,
				(SpellCastType)72
			},
			{
				4,
				(SpellCastType)25
			},
			{
				5,
				(SpellCastType)61
			},
			{
				6,
				(SpellCastType)15
			},
			{
				7,
				(SpellCastType)51
			}
		};

		public static void BaseSetup()
		{
			ChangeStages();
			ChangeQuivers();
		}

		private static void UpdateNinjutsuDescription(Item item, ref string description)
		{
			if (item.ItemID != ShinobiIDs.ninjutsuID)
			{
				return;
			}
			if (!((EffectSynchronizer)item).OwnerCharacter.StatusEffectMngr.HasStatusEffect(ShinobiIDs.activeJutsu))
			{
				CustomItems.SetDescription(item, "Shuriken go brrrrr");
				return;
			}
			switch (((EffectSynchronizer)item).OwnerCharacter.StatusEffectMngr.GetStatusLevel(ShinobiIDs.activeJutsu))
			{
			case 1:
				CustomItems.SetDescription(item, "Chidori");
				break;
			case 2:
				CustomItems.SetDescription(item, "Frostbolt");
				break;
			case 4:
				CustomItems.SetDescription(item, "GentleFist");
				break;
			case 3:
				CustomItems.SetDescription(item, "Bunshin");
				break;
			case 5:
				CustomItems.SetDescription(item, "Fireball");
				break;
			case 6:
				CustomItems.SetDescription(item, "Archers");
				break;
			case 7:
				CustomItems.SetDescription(item, "");
				break;
			}
		}

		public static void ChangeStages()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			Item itemPrefab = ResourcesPrefabManager.Instance.GetItemPrefab(ShinobiIDs.ninjutsuID);
			LevelAttackSkill val = (LevelAttackSkill)(object)((itemPrefab is LevelAttackSkill) ? itemPrefab : null);
			Array.Resize(ref val.m_skillStages, 7);
			foreach (int key in NinjaAnim.Keys)
			{
				if (key > 0)
				{
					SkillStage val2 = new SkillStage();
					val.m_skillStages[key - 1] = val2;
					val.m_skillStages[key - 1].StageIcon = CharacterHelpers.LoadSprite(jutsuIcon + key + ".PNG");
					val.m_skillStages[key - 1].StageAnim = NinjaAnim[key];
				}
			}
			baseNinjutsuSprite = CharacterHelpers.LoadSprite("NinjutsuIconDefault.PNG");
			altNinjutsuSprite = CharacterHelpers.LoadSprite("NinjutsuIconAlt.PNG");
		}

		private static void ChangeQuivers()
		{
			ninjaScrollSprite = CharacterHelpers.LoadSprite("quiverDisplayNinjaScroll.png");
			vanillaArrowSprite = CharacterHelpers.LoadSprite("quiverDisplayVanilla.png");
		}
	}
	public enum JutsuStages
	{
		Shuriken,
		Chidori,
		Frostbolt,
		Bunshin,
		GentleFist,
		Fireball,
		Archers,
		Genjutsu
	}
	public static class ShinobiDesc
	{
		public static string baseNinjutsuDesc = "Required: Shinobi Scroll\r\n\r\nChannel chakra from a Shinobi scroll to unleash a Ninjutsu.\r\n\r\nThe ninjutsu cast can be altered by performing Mudra hand signs.";

		public static Dictionary<int, string> JutsuDesc = new Dictionary<int, string>
		{
			{ 0, "Throw a shuriken, lightly damaging an enemy hit" },
			{ 1, "Hit an enemy, dealing electric damage and forcing a stagger\r\n" },
			{ 2, "Frost damage ranged bolt that deals big impact damage and applies slowdown." },
			{ 3, "Gain attack speed and movement speed, but reduce basic atk dmg and impact. Lasts for 30s or until being directly hit." },
			{ 4, "Summon a single 1hp clone to rush forward recklessly. Lasts 10s.\r\n" },
			{ 5, "Fire bolt that explodes with AoE dmg and applies burning\r\n" },
			{ 6, "Summon two 1HP  archers that attack enemies for 10s.\r\n" },
			{ 7, "Force an enemy to fight for you for 10s. Only works on enemies with less than three times your health." }
		};
	}
	public static class ShinobiIDs
	{
		public static int ninjutsuID = -2141;

		public static int MudraTen = -2142;

		public static int MudraChi = -2143;

		public static int MudraJin = -2144;

		public static int chakraLeech = -2145;

		public static int MudraPlus = -2146;

		public static int ToolMaster = -2147;

		public static int FistPlus = -2148;

		public static int ninjaInk = -2149;

		public static int ninjaScroll = -2150;

		public static string activeJutsu = "ActiveJutsu";

		public static string gentleFistEffect = "GentleFistEffect";

		public static string genjutsuEffect = "GenjutsuEffect";

		public static string bunshinEffect = "BunshinEffect";

		public static Dictionary<int, string> Mudras = new Dictionary<int, string>
		{
			{ -2142, "MudraTenEffect" },
			{ -2143, "MudraChiEffect" },
			{ -2144, "MudraJinEffect" }
		};

		public static string inkRecipe = "iggy.ninja.NinInkRecipe";

		public static string scrollRecipe = "iggy.ninja.NinScrollRecipe";
	}
	public static class ShinobiBalance
	{
		public static float chakraLeechBonus = 10f;

		public static int mudraBaseStacks = 1;

		public static int mudraPlusStacks = 2;

		public static int mudraCooldowns = 10;

		public static float genjutsuDuration = 10f;

		public static float BunshinMeleeDuration = 10f;

		public static float BunshinRangedDuration = 10f;
	}
}
namespace WhispererClass
{
	public enum WSkills
	{
		NONE = 0,
		Pathway = -2001,
		BreakDelay = -2002,
		BreakSpeed = -2003,
		SupressPain = -2004,
		Purify = -2007,
		applyMadness = -2010,
		upgraderQ = -2020
	}
	public enum WUpgrades
	{
		painPlus = -2005,
		painEther = -2006,
		purShield = -2008,
		purCleanse = -2009,
		drainMadness = -2011,
		expellMadness = -2012,
		extremism = -2013,
		absorbStamina = -2014,
		shareMadness = -2017,
		desperation = -2018,
		secretEffect1 = -2015,
		secretEffect2 = -2016
	}
	public enum WItems
	{
		WhisperSkull = -2049,
		SkullPassive = -2050
	}
	public enum WEffects
	{
		EnemyHealing,
		Mortality
	}
	internal static class MadIDs
	{
		public static int Pathway = -2001;

		public static int BreakDelay = -2002;

		public static int BreakSpeed = -2003;

		public static int SupressPain = -2004;

		public static int Purify = -2007;

		public static int applyMadness = -2010;

		public static int upgraderQ = -2020;

		public static string Insanity = "Insanity";
	}
	public class MadQuestManager : MonoBehaviour
	{
		[HarmonyPatch(typeof(CharacterKnowledge), "AddItem")]
		public class CharacterKnowledge_AddItem
		{
			[HarmonyPostfix]
			public static void Postfix(CharacterKnowledge __instance, Item _item, ref Character ___m_character)
			{
				Character val = ___m_character;
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				Character worldHostCharacter = CharacterManager.Instance.GetWorldHostCharacter();
				if (!val.IsLocalPlayer)
				{
					return;
				}
				Item itemFromItemID = ((CharacterKnowledge)worldHostCharacter.Inventory.QuestKnowledge).GetItemFromItemID(-2061);
				Quest val2 = (Quest)(object)((itemFromItemID is Quest) ? itemFromItemID : null);
				if (!((Object)(object)val2 == (Object)null) && QuestEventManager.Instance.GetEventCurrentStack(QE_WhispererStart.EventUID) < 9)
				{
					CharacterSkillKnowledge skillKnowledge = val.Inventory.SkillKnowledge;
					if (_item.ItemID == -2020)
					{
						Instance.questTriger = 2;
						Instance.UpdateQuestProgress(val2);
					}
					else if (((CharacterKnowledge)skillKnowledge).IsItemLearned(-2020) && Instance.checkAllUpgrades(val))
					{
						Instance.questTriger = 3;
						Instance.UpdateQuestProgress(val2);
					}
				}
			}
		}

		[HarmonyPatch(typeof(CharacterInventory), "GetMostRelevantContainer", new Type[] { typeof(Item) })]
		public class CharacterInventory_GetMostRelevantContainer
		{
			[HarmonyPrefix]
			public static void Postfix(CharacterInventory __instance, Item _item, ref Character ___m_character)
			{
				Character val = ___m_character;
				if (!((Object)(object)val == (Object)null) && val.IsLocalPlayer && _item.ItemID == -2049 && QuestEventManager.Instance.GetEventCurrentStack(QE_WhispererStart.EventUID) < 1)
				{
					Instance.GetOrGiveQuestToHost();
				}
			}
		}

		[HarmonyPatch(typeof(InteractionTriggerBase), "TryActivateBasicAction", new Type[]
		{
			typeof(Character),
			typeof(int)
		})]
		public class InteractionTriggerBase_TryActivateBasicAction
		{
			[HarmonyPrefix]
			public static void Prefix(InteractionTriggerBase __instance, Character _character, int _toggleState)
			{
				//IL_0052: 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)
				if (!_character.IsWorldHost || SceneManagerHelper.ActiveSceneName != "Chersonese_Dungeon3" || !Object.op_Implicit((Object)/*isinst with value type is only supported in some contexts*/))
				{
					return;
				}
				EventActivator currentTriggerManager = __instance.CurrentTriggerManager;
				InteractionActivator val = (InteractionActivator)(object)((currentTriggerManager is InteractionActivator) ? currentTriggerManager : null);
				if (val.BasicInteraction != null && val.BasicInteraction is InteractionTrainerDialogue && Vector3.Distance(_character.CenterPosition, Instance.madtrainer1Spawn) < 2f && !PhotonNetwork.isNonMasterClientInRoom)
				{
					Item itemFromItemID = ((CharacterKnowledge)_character.Inventory.QuestKnowledge).GetItemFromItemID(-2061);
					Quest quest = (Quest)(object)((itemFromItemID is Quest) ? itemFromItemID : null);
					if (QuestEventManager.Instance.GetEventCurrentStack(QE_WhispererStart.EventUID) < 3)
					{
						Instance.questTriger = 1;
						Instance.UpdateQuestProgress(quest);
					}
				}
			}
		}

		[HarmonyPatch(typeof(QuestLogEntry), "CreateEntryFromNetworkData")]
		private static class ExceptionFix
		{
			[HarmonyFinalizer]
			private static Exception Finalizer()
			{
				return null;
			}
		}

		public static MadQuestManager Instance;

		private static int baseDelayID = -2001;

		private static int breakDelayID = -2002;

		private static int breakSpeedID = -2003;

		private static int ignorePainID = -2004;

		private static int ignorePlusID = -2005;

		private static int etherealSkinID = -2006;

		private static int halfDamageID = -2007;

		private static int purShieldID = -2008;

		private static int purCleanseID = -2009;

		private static int applyMadnessID = -2010;

		private static int drainMadnessID = -2011;

		private static int expellMadnessID = -2012;

		private static int extremismhp = -2013;

		private static int masochism = -2014;

		private static int desperation = -2018;

		private static int shareMadness = -2017;

		private static int secretEffect1ID = -2015;

		private static int secretEffect2ID = -2016;

		private static int upgraderID = -2020;

		private int questTriger;

		private const int QuestID = -2061;

		private const string QuestName = "Mad Calling";

		public const string QUEST_EVENT_FAMILY_NAME = "A_Iggy_MadWhisperer";

		private const string LogSignature_A = "whisperer.objective.a";

		private const string LogSignature_B = "whisperer.objective.b";

		private const string LogSignature_C = "whisperer.objective.c";

		private const string LogSignature_D1 = "whisperer.objective.d1";

		private const string LogSignature_D2 = "whisperer.objective.d2";

		private const string LogSignature_D3 = "whisperer.objective.d3";

		private const string LogSignature_D4 = "whisperer.objective.d4";

		private const string LogSignature_D5 = "whisperer.objective.d5";

		private const string LogSignature_E = "whisperer.objective.e";

		private Vector3 madtrainer1Spawn = new Vector3(-6.7f, 0.03f, -74.6f);

		private static QuestEventSignature QE_WhispererStart;

		public static string QE_Scenario_UID => "iggythemad.scenarios.whisperer";

		public SL_Quest QuestTemplate { get; private set; }

		public Dictionary<string, string> QuestLogSignatures => new Dictionary<string, string>
		{
			{ "whisperer.objective.a", "Decypher the whispering skull riddle: “Bring the skull home, so we may supply. Ghosts will Pass, yet whispers will rise.”" },
			{ "whisperer.objective.b", "At Ghosts Pass: The skull senses it's masters nearby." },
			{ "whisperer.objective.c", "Surrender to madness: Learn all the skills from Iggy The Mad." },
			{ "whisperer.objective.d1", "Riddle: “The masters already Rose from their prisons of Sand. The whispers usher their coming.”" },
			{ "whisperer.objective.d2", "Riddle: “Stand face to Face againts the Ancients. Embrace the cold. Surrender to its grasp.”" },
			{ "whisperer.objective.d3", "Riddle: “The Jade masters will not stand your Quarrels long, mortals. They are coming.”" },
			{ "whisperer.objective.d4", "Riddle: “The masters once brought the world to Ruins. Their legacy is ever Giant.”" },
			{ "whisperer.objective.d5", "Riddle: “Vigil of the scourge, whose purity taken by the Lair of depravity. Thy whispers shall set free.”" },
			{ "whisperer.objective.e", "Your duties are over, mortal... for now..." }
		};

		internal void Awake()
		{
			Instance = this;
			SL.OnPacksLoaded += OnPacksLoaded;
			QE_WhispererStart = CustomQuests.CreateQuestEvent("iggythemad.whisperer.start", false, true, true, "A_Iggy_MadWhisperer", "CustomEvent", "A custom event created with SideLoader");
			SL.OnGameplayResumedAfterLoading += SL_OnGameplayResumedAfterLoading;
		}

		public void OnPacksLoaded()
		{
			PrepareSLQuest();
		}

		private void SL_OnGameplayResumedAfterLoading()
		{
			if (!PhotonNetwork.isNonMasterClientInRoom)
			{
				Character worldHostCharacter = CharacterManager.Instance.GetWorldHostCharacter();
				if (((CharacterKnowledge)worldHostCharacter.Inventory.QuestKnowledge).IsItemLearned(-2061))
				{
					Item itemFromItemID = ((CharacterKnowledge)worldHostCharacter.Inventory.QuestKnowledge).GetItemFromItemID(-2061);
					Quest quest = (Quest)(object)((itemFromItemID is Quest) ? itemFromItemID : null);
					UpdateQuestProgress(quest);
				}
			}
		}

		public void PrepareSLQuest()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			SL_Quest val = new SL_Quest();
			((SL_Item)val).Target_ItemID = 7011620;
			((SL_Item)val).New_ItemID = -2061;
			((SL_Item)val).Name = "Mad Calling";
			val.IsSideQuest = false;
			((SL_Item)val).ItemExtensions = (SL_ItemExtension[])(object)new SL_ItemExtension[1] { (SL_ItemExtension)new SL_QuestProgress() };
			QuestTemplate = val;
			List<SL_QuestLogEntrySignature> list = new List<SL_QuestLogEntrySignature>();
			foreach (KeyValuePair<string, string> questLogSignature in QuestLogSignatures)
			{
				list.Add(new SL_QuestLogEntrySignature
				{
					UID = questLogSignature.Key,
					Text = questLogSignature.Value,
					Type = (QuestLogEntrySignatureType)0
				});
			}
			SL_ItemExtension obj = ((SL_Item)QuestTemplate).ItemExtensions[0];
			((SL_QuestProgress)((obj is SL_QuestProgress) ? obj : null)).LogSignatures = list.ToArray();
			((ContentTemplate)QuestTemplate).ApplyTemplate();
			QuestTemplate.OnQuestLoaded += UpdateQuestProgress;
		}

		public Quest GetOrGiveQuestToHost()
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			QuestEventManager.Instance.AddEvent(QE_WhispererStart, 1);
			Character worldHostCharacter = CharacterManager.Instance.GetWorldHostCharacter();
			if (((CharacterKnowledge)worldHostCharacter.Inventory.QuestKnowledge).IsItemLearned(-2061))
			{
				Item itemFromItemID = ((CharacterKnowledge)worldHostCharacter.Inventory.QuestKnowledge).GetItemFromItemID(-2061);
				return (Quest)(object)((itemFromItemID is Quest) ? itemFromItemID : null);
			}
			Item obj = ItemManager.Instance.GenerateItemNetwork(-2061);
			Quest val = (Quest)(object)((obj is Quest) ? obj : null);
			((Component)val).transform.SetParent(((Component)worldHostCharacter.Inventory.QuestKnowledge).transform);
			((CharacterKnowledge)worldHostCharacter.Inventory.QuestKnowledge).AddItem((Item)(object)val);
			((Component)val).GetComponent<QuestProgress>().m_progressState = (ProgressState)1;
			UpdateQuestProgress(val);
			return val;
		}

		private bool checkAllUpgrades(Character player)
		{
			bool num = ((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(ignorePlusID) || ((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(etherealSkinID);
			bool flag = ((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(desperation) || ((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(masochism);
			bool flag2 = ((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(purCleanseID) || ((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(purShieldID);
			bool flag3 = ((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(drainMadnessID) || ((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(extremismhp);
			bool flag4 = ((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(expellMadnessID) || ((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(shareMadness);
			if (num && flag && flag2 && flag3 && flag4)
			{
				return true;
			}
			return false;
		}

		public void UpdateQuestProgress(Quest quest)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			if (!PhotonNetwork.isNonMasterClientInRoom)
			{
				CharacterManager.Instance.GetWorldHostCharacter();
				int eventCurrentStack = QuestEventManager.Instance.GetEventCurrentStack(QE_WhispererStart.EventUID);
				QuestProgress questProgress = quest.m_questProgress;
				if (eventCurrentStack < 1)
				{
					QuestEventManager.Instance.AddEvent(QE_WhispererStart, 1);
					questProgress.UpdateLogEntry(questProgress.GetLogSignature(UID.op_Implicit("whisperer.objective.a")), displayTime: false);
					ShowUIMessage("“Bring the skull home, so we may supply. Ghosts will Pass, yet whispers will rise.”");
				}
				if (SceneManagerHelper.ActiveSceneName == "Chersonese_Dungeon3" && eventCurrentStack < 2)
				{
					QuestEventManager.Instance.AddEvent(QE_WhispererStart, 1);
					questProgress.UpdateLogEntry(questProgress.GetLogSignature(UID.op_Implicit("whisperer.objective.b")), displayTime: false);
					ShowUIMessage("“The Mad Ones are here. Open your mind to the masters. Surrender to their will.”");
				}
				else if (questTriger == 1 && eventCurrentStack < 3)
				{
					questTriger = 0;
					QuestEventManager.Instance.AddEvent(QE_WhispererStart, 1);
					questProgress.UpdateLogEntry(questProgress.GetLogSignature(UID.op_Implicit("whisperer.objective.c")), displayTime: false);
					ShowUIMessage("“Surrender to madness... Let Iggy The Mad teach you everything about the whispers...”");
				}
				else if (questTriger == 2 && eventCurrentStack < 4)
				{
					questTriger = 0;
					QuestEventManager.Instance.AddEvent(QE_WhispererStart, 5);
					questProgress.UpdateLogEntry(questProgress.GetLogSignature(UID.op_Implicit("whisperer.objective.d1")), displayTime: false);
					questProgress.UpdateLogEntry(questProgress.GetLogSignature(UID.op_Implicit("whisperer.objective.d2")), displayTime: false);
					questProgress.UpdateLogEntry(questProgress.GetLogSignature(UID.op_Implicit("whisperer.objective.d3")), displayTime: false);
					questProgress.UpdateLogEntry(questProgress.GetLogSignature(UID.op_Implicit("whisperer.objective.d4")), displayTime: false);
					questProgress.UpdateLogEntry(questProgress.GetLogSignature(UID.op_Implicit("whisperer.objective.d5")), displayTime: false);
					ShowUIMessage("“Your mind is overwhelmed with whispering riddles...”");
				}
				else if (questTriger == 3 && eventCurrentStack < 9)
				{
					questTriger = 0;
					QuestEventManager.Instance.AddEvent(QE_WhispererStart, 1);
					questProgress.UpdateLogEntry(questProgress.GetLogSignature(UID.op_Implicit("whisperer.objective.e")), displayTime: true);
					questProgress.DisableQuest((ProgressState)3);
					ShowUIMessage("“Your duties are over, mortal... for now...”");
				}
				questProgress = quest.m_questProgress;
				ReloadLogs(eventCurrentStack, questProgress);
			}
		}

		public void ReloadLogs(int stack, QuestProgress progress)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			foreach (KeyValuePair<string, string> questLogSignature in QuestLogSignatures)
			{
				if (num < stack && questLogSignature.Key != null)
				{
					Debug.Log((object)("log: " + questLogSignature.Key));
					progress.UpdateLogEntry(progress.GetLogSignature(UID.op_Implicit(questLogSignature.Key)), displayTime: false);
					num++;
				}
			}
		}

		public void ShowUIMessage(string message)
		{
			if (!((Object)(object)CharacterManager.Instance == (Object)null) && !string.IsNullOrEmpty(message))
			{
				Character firstLocalCharacter = CharacterManager.Instance.GetFirstLocalCharacter();
				if (Object.op_Implicit((Object)(object)firstLocalCharacter))
				{
					firstLocalCharacter.CharacterUI.NotificationPanel.ShowNotification(message, 4f);
				}
			}
		}
	}
	internal static class QuestExtensions
	{
		internal static void UpdateLogEntry(this QuestProgress progress, QuestLogEntrySignature signature, bool displayTime)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			progress.UpdateLogEntry(signature.UID, displayTime, signature);
		}
	}
	public class MadDamageManager : MonoBehaviour
	{
		[HarmonyPatch(typeof(StatusEffectManager), "AddStatusEffect", new Type[]
		{
			typeof(StatusEffect),
			typeof(Character),
			typeof(string[])
		})]
		public class StatusEffectManager_AddStatusEffect
		{
			[HarmonyPrefix]
			public static void Prefix(StatusEffectManager __instance, StatusEffect _statusEffect, Character _dealer, string[] _loadData)
			{
				if (!PhotonNetwork.isNonMasterClientInRoom && _statusEffect.IdentifierName == "IgnorePain" && ((CharacterKnowledge)__instance.m_character.Inventory.SkillKnowledge).IsItemLearned(etherealSkinID))
				{
					__instance.m_character.StatusEffectMngr.AddStatusEffect("PainBuff");
				}
			}
		}

		[HarmonyPatch(typeof(CharacterStats), "ReceiveDamage")]
		public class Character_ReceiveDamage
		{
			[HarmonyPrefix]
			public static void Prefix(CharacterStats __instance, ref float _damage, ref Character ___m_character)
			{
				if (!___m_character.IsLocalPlayer)
				{
					return;
				}
				int num = ((!((Object)(object)___m_character == (Object)(object)Instance.players[0])) ? 1 : 0);
				if (___m_character.StatusEffectMngr.HasStatusEffect("PurifyShield"))
				{
					if (_damage < Instance.purifyShieldPot[num])
					{
						Instance.purifyShieldPot[num] -= _damage;
						_damage = 0f;
					}
					else
					{
						_damage -= Instance.purifyShieldPot[num];
						___m_character.StatusEffectMngr.RemoveStatusWithIdentifierName("PurifyShield");
						_damage /= 2f;
					}
				}
				if (((CharacterKnowledge)__instance.m_character.Inventory.SkillKnowledge).IsItemLearned(-2018))
				{
					int statusLevel = __instance.m_character.StatusEffectMngr.GetStatusLevel(Insanity);
					int num2 = 2;
					if (((CharacterKnowledge)__instance.m_character.Inventory.SkillKnowledge).IsItemLearned(-2002))
					{
						num2 = 3;
					}
					if (statusLevel < num2 && Random.Range(0, 100) < (int)_damage)
					{
						__instance.m_character.StatusEffectMngr.AddStatusEffect(Insanity);
					}
				}
			}
		}

		[HarmonyPatch(typeof(Item), "Use", new Type[] { typeof(Character) })]
		public class Item_Usage
		{
			[HarmonyPrefix]
			public static void Prefix(Item __instance, Character _character)
			{
				_character.StatusEffectMngr.GetStatusEffectOfName("Insanity");
				if (__instance.ItemID == halfDamageID)
				{
					((MonoBehaviour)Instance).StartCoroutine(Instance.Purify(_character));
				}
				else if (__instance.ItemID == ignorePainID)
				{
					Instance.ReduceInsanity(_character);
					if (((CharacterKnowledge)_character.Inventory.SkillKnowledge).IsItemLearned(ignorePlusID) && ((CharacterKnowledge)_character.Inventory.SkillKnowledge).IsItemLearned(breakSpeedID))
					{
						_character.StatusEffectMngr.AddStatusEffect("PainSpeed");
					}
					if (((CharacterKnowledge)_character.Inventory.SkillKnowledge).IsItemLearned(-2017))
					{
						((MonoBehaviour)Instance).StartCoroutine(Instance.ShareMadness(_character));
					}
				}
				else if (__instance.ItemID == drainMadnessID)
				{
					Instance.ReduceInsanity(_character);
					((MonoBehaviour)Instance).StartCoroutine(Instance.DrainMadness(_character));
				}
				else if (__instance.ItemID == expellMadnessID)
				{
					Instance.ReduceInsanity(_character);
					Object.FindObjectsOfType<Character>();
					((MonoBehaviour)Instance).StartCoroutine(Instance.ExpellMadness(_character));
				}
			}
		}

		[HarmonyPatch(typeof(Character), "VitalityHit")]
		public class Character_VitalityHit
		{
			[HarmonyPrefix]
			public static void Prefix(Character __instance, Character _dealerChar, float _damage, Vector3 _hitVector)
			{
				if (!((Object)(object)_dealerChar == (Object)null) && __instance.IsAI && _dealerChar.IsLocalPlayer && ((CharacterKnowledge)_dealerChar.Inventory.SkillKnowledge).IsItemLearned(applyMadnessID) && !Instance.madnessCD)
				{
					Instance.madnessCD = true;
					((MonoBehaviour)Instance).StartCoroutine("ResetMadCD");
					_dealerChar.StatusEffectMngr.AddStatusEffect("Madness");
				}
			}
		}

		[HarmonyPatch(typeof(CharacterStats), "RestoreBurntHealth")]
		public class Character_RestoreBurntHealth
		{
			[HarmonyPrefix]
			public static void Prefix(CharacterStats __instance, ref float _value, bool _ratioFromMax, ref Character ___m_character)
			{
				if (___m_character.IsLocalPlayer && ((CharacterKnowledge)___m_character.Inventory.SkillKnowledge).IsItemLearned(secretEffect1ID))
				{
					_value += _value;
				}
			}
		}

		public static MadDamageManager Instance;

		public float delayedTick;

		public int tickCounter;

		public float regenPurTimer = 20f;

		private static int baseDelayID = -2001;

		private static int breakDelayID = -2002;

		private static int breakSpeedID = -2003;

		private static int ignorePainID = -2004;

		private static int ignorePlusID = -2005;

		private static int etherealSkinID = -2006;

		private static int halfDamageID = -2007;

		private static int purShieldID = -2008;

		private static int purCleanseID = -2009;

		private static int applyMadnessID = -2010;

		private static int drainMadnessID = -2011;

		private static int expellMadnessID = -2012;

		private static int purHealID = -2013;

		private static int absorbStaminaID = -2014;

		private static int secretEffect1ID = -2015;

		private static int secretEffect2ID = -2016;

		private static int upgraderID = -2020;

		private static int whispHelm = -2033;

		private static string expellBoltID = "ExpellBolt";

		private static string MadnessID = "Madness";

		private static string ExtremismEffect = "ExtremismEffect";

		private static string Insanity = "Insanity";

		private static string delayedDamage = "Delayed Damage";

		private static string ExpellFX = "ExpellFX";

		public float delayPerStack = 0.1f;

		public float tickStaminaMult = 2f;

		public float baseDrainHeal = 0.5f;

		public float drainPowDiv = 0.5f;

		public float expellPowDiv = 2f;

		public float expellRange = 12f;

		public float ignoreStaggerMult = 0.8f;

		public float purifyStrenght = 0.4f;

		public float purShieldMult = 10f;

		public float purifyStrenghtPlus = 0.6f;

		public float expellBoltRate = 0.7f;

		public float shareImpact = 5f;

		public float shareRange = 8f;

		public float purifyHeal = 3f;

		public int localPlayers;

		public int[] regenInsanity;

		public bool[] Regenerating;

		public float[] purifyShieldPot;

		public int[] maxInsanity;

		public float[] baseMaxHP;

		public int[] madnessLv;

		public bool[] madReset;

		public Character[] players;

		public bool[] normalizeTrigger;

		public bool madnessCD;

		public Coroutine[] drainCo;

		internal void Awake()
		{
			Instance = this;
			players = (Character[])(object)new Character[2];
			regenInsanity = new int[2];
			Regenerating = new bool[2];
			maxInsanity = new int[2];
			purifyShieldPot = new float[2];
			baseMaxHP = new float[2];
			madnessLv = new int[2];
			madReset = new bool[2];
			normalizeTrigger = new bool[2];
			drainCo = (Coroutine[])(object)new Coroutine[2];
			players[0] = null;
			players[1] = null;
			regenInsanity[0] = 0;
			regenInsanity[1] = 0;
			Regenerating[0] = false;
			Regenerating[1] = false;
			maxInsanity[0] = 0;
			maxInsanity[1] = 0;
			purifyShieldPot[0] = 0f;
			purifyShieldPot[1] = 0f;
			DelayedDamage.GetDamageToDelay = (Func<Character, Character, DamageList, float, float>)Delegate.Combine(DelayedDamage.GetDamageToDelay, new Func<Character, Character, DamageList, float, float>(GetDelayedDamage));
			DelayedDamage.OnDelayedDamageTaken = (Action<Character, Character, float>)Delegate.Combine(DelayedDamage.OnDelayedDamageTaken, new Action<Character, Character, float>(StaminaRegenOnDelay));
			SL.OnGameplayResumedAfterLoading += Fixer;
		}

		private void Fixer()
		{
			players[0] = CharacterManager.Instance.GetFirstLocalCharacter();
			if (!SplitScreenManager.Instance.IsSplitActive)
			{
				return;
			}
			Character[] array = Object.FindObjectsOfType<Character>();
			foreach (Character val in array)
			{
				if ((!val.IsAI & ((Object)(object)val != (Object)(object)players[0])) && val.IsLocalPlayer)
				{
					players[1] = val;
				}
			}
		}

		private void Update()
		{
			if ((Object)(object)players[0] == (Object)null)
			{
				return;
			}
			if (SplitScreenManager.Instance.IsSplitActive)
			{
				localPlayers = 2;
				if ((Object)(object)players[1] == (Object)null)
				{
					Fixer();
				}
			}
			else
			{
				localPlayers = 1;
			}
			for (int i = 0; i < localPlayers; i++)
			{
				if (!((Object)(object)players[i] != (Object)null))
				{
					continue;
				}
				if (players[i].Inventory.HasEquipped(whispHelm) && !players[i].StatusEffectMngr.HasStatusEffect("skullDrain") && players[i].InCombat)
				{
					players[i].StatusEffectMngr.AddStatusEffect("skullDrain");
				}
				else if ((!players[i].Inventory.HasEquipped(whispHelm) || !players[i].InCombat) && players[i].StatusEffectMngr.HasStatusEffect("skullDrain"))
				{
					players[i].StatusEffectMngr.RemoveStatusWithIdentifierName("skullDrain");
				}
				if (!((CharacterKnowledge)players[i].Inventory.SkillKnowledge).IsItemLearned(baseDelayID))
				{
					continue;
				}
				if (((CharacterKnowledge)players[i].Inventory.SkillKnowledge).IsItemLearned(breakDelayID))
				{
					maxInsanity[i] = 3;
				}
				else if (((CharacterKnowledge)players[i].Inventory.SkillKnowledge).IsItemLearned(breakSpeedID))
				{
					maxInsanity[i] = 2;
				}
				else
				{
					maxInsanity[i] = 1;
				}
				if (regenInsanity[i] < maxInsanity[i] && !Regenerating[i])
				{
					((MonoBehaviour)this).StartCoroutine(RegenInsanityStack(i));
				}
				if (regenInsanity[i] > players[i].StatusEffectMngr.GetStatusLevel("Insanity") && regenInsanity[i] > 0)
				{
					players[i].StatusEffectMngr.AddStatusEffect("Insanity");
				}
				else if (regenInsanity[i] < players[i].StatusEffectMngr.GetStatusLevel("Insanity") && players[i].StatusEffectMngr.HasStatusEffect("Insanity"))
				{
					regenInsanity[i]++;
				}
				if (players[i].StatusEffectMngr.GetStatusLevel("InsanitySpeed") != players[i].StatusEffectMngr.GetStatusLevel("Insanity") && ((CharacterKnowledge)players[i].Inventory.SkillKnowledge).IsItemLearned(breakSpeedID))
				{
					if (players[i].StatusEffectMngr.GetStatusLevel("InsanitySpeed") > players[i].StatusEffectMngr.GetStatusLevel("Insanity"))
					{
						StatusEffect statusEffectOfName = players[i].StatusEffectMngr.GetStatusEffectOfName("InsanitySpeed");
						players[i].StatusEffectMngr.ReduceStatusLevel(statusEffectOfName, 1);
					}
					else if (players[i].StatusEffectMngr.GetStatusLevel("InsanitySpeed") < players[i].StatusEffectMngr.GetStatusLevel("Insanity"))
					{
						players[i].StatusEffectMngr.AddStatusEffect("InsanitySpeed");
					}
				}
				if (players[i].StatusEffectMngr.GetStatusLevel("Insanity") > maxInsanity[i])
				{
					regenInsanity[i]--;
					players[i].StatusEffectMngr.ReduceStatusLevel(players[i].StatusEffectMngr.GetStatusEffectOfName("Insanity"), 1);
				}
			}
		}

		public IEnumerator RegenInsanityStack(int i)
		{
			while (regenInsanity[i] < maxInsanity[i])
			{
				Regenerating[i] = true;
				yield return (object)new WaitForSeconds(regenPurTimer);
				regenInsanity[i]++;
			}
			Regenerating[i] = false;
		}

		private float GetDelayedDamage(Character character, Character dealer, DamageList damageList, float knockBack)
		{
			float totalDamage = damageList.TotalDamage;
			float num = 0f;
			if (knockBack > 0f && (Object)(object)dealer != (Object)null && ((CharacterKnowledge)character.Inventory.SkillKnowledge).IsItemLearned(baseDelayID) && !character.StatusEffectMngr.HasStatusEffect("PurifyShield"))
			{
				if (((CharacterKnowledge)character.Inventory.SkillKnowledge).IsItemLearned(breakDelayID))
				{
					num = ((!character.StatusEffectMngr.HasStatusEffect("IgnorePain")) ? (num + totalDamage * (delayPerStack * 3f)) : ((!((CharacterKnowledge)character.Inventory.SkillKnowledge).IsItemLearned(ignorePlusID)) ? (num + totalDamage * (delayPerStack * 3f + 0.3f)) : (num + totalDamage * 0.9f)));
				}
				else if (((CharacterKnowledge)character.Inventory.SkillKnowledge).IsItemLearned(breakSpeedID))
				{
					num = ((!character.StatusEffectMngr.HasStatusEffect("IgnorePain")) ? (num + totalDamage * ((float)character.StatusEffectMngr.GetStatusLevel("Insanity") * delayPerStack)) : (num + totalDamage * ((float)character.StatusEffectMngr.GetStatusLevel("Insanity") * delayPerStack + 0.3f)));
				}
				else if (character.StatusEffectMngr.HasStatusEffect("Insanity"))
				{
					num += totalDamage * delayPerStack;
				}
			}
			return num;
		}

		public void StaminaRegenOnDelay(Character receiver, Character dealer, float damage)
		{
			if (((CharacterKnowledge)receiver.Inventory.SkillKnowledge).IsItemLearned(absorbStaminaID))
			{
				receiver.Stats.AffectStamina(Mathf.Abs(damage * tickStaminaMult));
			}
		}

		public IEnumerator ShareMadness(Character _character)
		{
			List<Character> inRange = new List<Character>();
			new List<Character>();
			yield return (object)new WaitForSeconds(0.4f);
			CharacterManager.Instance.FindCharactersInRange(((Component)_character).transform.position, Instance.shareRange, ref inRange);
			foreach (Character item in inRange)
			{
				if (item.IsAI && !item.IsAlly(_character))
				{
					int statusLevel = _character.StatusEffectMngr.GetStatusLevel(MadnessID);
					item.OnReceiveHit(_character.CurrentWeapon, 1f, new DamageList(), Vector3.forward, Vector3.forward, 0f, 0f, _character, 6f * (float)statusLevel);
				}
			}
		}

		public IEnumerator Purify(Character _character)
		{
			yield return (object)new WaitForSeconds(0.6f);
			float num = 0f;
			float num2 = 0f;
			float num3 = purifyStrenght;
			if (((CharacterKnowledge)_character.Inventory.SkillKnowledge).IsItemLearned(-2009))
			{
				num3 = Instance.purifyStrenghtPlus;
			}
			Instance.ReduceInsanity(_character);
			foreach (StatusEffect status in _character.StatusEffectMngr.Statuses)
			{
				if (status.IdentifierName == delayedDamage)
				{
					num += ((EffectSynchronizer)status).EffectPotency;
					((EffectSynchronizer)status).SetPotency(((EffectSynchronizer)status).EffectPotency * (1f - num3));
					num2 += ((EffectSynchronizer)status).EffectPotency;
				}
			}
			if (((CharacterKnowledge)_character.Inventory.SkillKnowledge).IsItemLearned(purShieldID))
			{
				int num4 = ((!((Object)(object)_character == (Object)(object)Instance.players[0])) ? 1 : 0);
				Instance.purifyShieldPot[num4] = (num - num2) * Instance.purShieldMult;
				_character.StatusEffectMngr.RemoveStatusWithIdentifierName("PurifyShield");
				_character.StatusEffectMngr.AddStatusEffect("PurifyShield");
			}
			else if (((CharacterKnowledge)_character.Inventory.SkillKnowledge).IsItemLearned(purCleanseID))
			{
				_ = _character.StatusEffectMngr.Statuses.Count;
				foreach (string item in new List<string> { "Poisoned +", "Poisoned", "Possessed", "Curse", "Plague", "Hallowed Marsh Poison Lvl2", "Hallowed Marsh Poison Lvl1", "SulphurPoison", "Food Poisoned +", "Food Poisoned" })
				{
					if (_character.StatusEffectMngr.HasStatusEffect(item))
					{
						_character.StatusEffectMngr.RemoveStatusWithIdentifierName(item);
						break;
					}
				}
			}
			if (((CharacterKnowledge)_character.Inventory.SkillKnowledge).IsItemLearned(-2013))
			{
				int statusLevel = _character.StatusEffectMngr.GetStatusLevel(MadnessID);
				_character.Stats.AffectHealth((float)statusLevel * purifyHeal);
			}
		}

		public void ReduceInsanity(Character _character)
		{
			_character.StatusEffectMngr.ReduceStatusLevel(Insanity, 1);
			if ((Object)(object)_character == (Object)(object)Instance.players[0])
			{
				Instance.regenInsanity[0]--;
			}
			else
			{
				Instance.regenInsanity[1]--;
			}
		}

		public IEnumerator DrainMadness(Character playerChar)
		{
			yield return (object)new WaitForSeconds(0.5f);
			_ = baseDrainHeal;
			yield return (object)new WaitForSeconds(0.5f);
			StartDrainHOT(playerChar);
		}

		private void StartDrainHOT(Character playerChar)
		{
			int num = 0;
			num = ((!((Object)(object)playerChar == (Object)(object)players[0])) ? 1 : 0);
			if (drainCo[num] != null)
			{
				((MonoBehaviour)Instance).StopCoroutine(drainCo[num]);
			}
			drainCo[num] = ((MonoBehaviour)Instance).StartCoroutine(DrainHOT(playerChar));
		}

		private IEnumerator DrainHOT(Character playerChar)
		{
			float HPtoHeal = baseDrainHeal;
			playerChar.StatusEffectMngr.AddStatusEffect("DrainHOT");
			while (playerChar.StatusEffectMngr.HasStatusEffect("Madness") && playerChar.Stats.CurrentHealth > 1f)
			{
				yield return (object)new WaitForSeconds(1f);
				if (playerChar.Stats.CurrentHealth > 1f)
				{
					playerChar.Stats.AffectHealth(HPtoHeal);
				}
				playerChar.StatusEffectMngr.ReduceStatusLevel("Madness", 1);
				if (HPtoHeal < baseDrainHeal * 10f)
				{
					HPtoHeal += baseDrainHeal;
				}
			}
			playerChar.StatusEffectMngr.CleanseStatusEffect("DrainHOT");
		}

		public IEnumerator ExpellMadness(Character playerChar)
		{
			playerChar.Animator.speed = 1.5f;
			yield return (object)new WaitForSeconds(1f);
			playerChar.Animator.speed = 1f;
			playerChar.StatusEffectMngr.AddStatusEffect(ExpellFX);
			while (playerChar.StatusEffectMngr.GetStatusLevel(MadnessID) > 0 && playerChar.Stats.CurrentHealth > 1f)
			{
				playerChar.StatusEffectMngr.AddStatusEffect(expellBoltID);
				playerChar.StatusEffectMngr.ReduceStatusLevel(MadnessID, 1);
				yield return (object)new WaitForSeconds(expellBoltRate);
			}
		}

		private IEnumerator ResetMadCD()
		{
			yield return (object)new WaitForSeconds(0.1f);
			madnessCD = false;
		}
	}
	public class MadExtrasManager : MonoBehaviour
	{
		[HarmonyPatch(typeof(CharacterInventory), "DropItem", new Type[]
		{
			typeof(Item),
			typeof(Transform),
			typeof(bool)
		})]
		public class CharacterInventory_DropItem
		{
			[HarmonyPrefix]
			public static bool Prefix(CharacterInventory __instance, Item _item, Transform _newParent, bool _playAnim, ref Character ___m_character)
			{
				if (_item.ItemID == -2049 && ((EffectSynchronizer)_item).OwnerCharacter.IsLocalPlayer && ((CharacterKnowledge)((EffectSynchronizer)_item).OwnerCharacter.Inventory.SkillKnowledge).IsItemLearned(whispPassive))
				{
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(ShopMenu), "OnConfirmTransaction")]
		public class ItemDisplay_OnConfirmSell
		{
			[HarmonyPrefix]
			public static void Prefix(ShopMenu __instance)
			{
				if (!((CharacterKnowledge)((UIElement)__instance).LocalCharacter.Inventory.SkillKnowledge).IsItemLearned(whispPassive))
				{
					return;
				}
				foreach (ItemQuantity item in __instance.m_merchant.SellCart.ItemsInCart)
				{
					if (item.Item.ItemID == whispSkull)
					{
						Debug.Log((object)"IS SELLING SKULL-------------");
						Item itemFromItemID = ((CharacterKnowledge)((UIElement)__instance).LocalCharacter.Inventory.SkillKnowledge).GetItemFromItemID(whispPassive);
						ItemManager.Instance.DestroyItem(itemFromItemID.UID);
						((CharacterKnowledge)((UIElement)__instance).LocalCharacter.Inventory.SkillKnowledge).RemoveItem(whispPassive);
						((UIElement)__instance).LocalCharacter.CharacterUI.ShowInfoNotification("The burden of the Whispering Skull has been passed...");
					}
				}
			}
		}

		[HarmonyPatch(typeof(CharacterInventory), "EquipItem", new Type[]
		{
			typeof(Equipment),
			typeof(bool)
		})]
		public class CharacterInventory_EquipItem
		{
			[HarmonyPrefix]
			public static void Postfix(CharacterInventory __instance, Equipment _itemToEquip, bool _playAnim, ref Character ___m_character)
			{
				Character val = ___m_character;
				if (!((Object)(object)val == (Object)null) && val.IsLocalPlayer)
				{
					checkSkulls(val);
				}
			}
		}

		[HarmonyPatch(typeof(CharacterInventory), "UnequipItem", new Type[]
		{
			typeof(Equipment),
			typeof(bool)
		})]
		public class CharacterInventory_UnequipItem
		{
			[HarmonyPrefix]
			public static void Postfix(CharacterInventory __instance, Equipment _itemToUnequip, bool _playAnim, ref Character ___m_character)
			{
				Character val = ___m_character;
				if (!((Object)(object)val == (Object)null) && val.IsLocalPlayer)
				{
					checkSkulls(val);
				}
			}
		}

		[HarmonyPatch(typeof(CharacterUI), "ShowMenu", new Type[] { typeof(MenuScreens) })]
		public class CharacterUI_ShowMenu
		{
			[HarmonyPrefix]
			public static void Prefix(CharacterUI __instance, MenuScreens _menu)
			{
				Character targetCharacter = __instance.TargetCharacter;
				if (!((Object)(object)targetCharacter == (Object)null) && targetCharacter.IsLocalPlayer)
				{
					checkSkulls(targetCharacter);
				}
			}
		}

		[HarmonyPatch(typeof(CharacterKnowledge), "AddItem")]
		public class CharacterKnowledge_AddItem
		{
			[HarmonyPrefix]
			public static void Postfix(CharacterKnowledge __instance, Item _item)
			{
				if (_item.ItemID == -2050)
				{
					Character character = __instance.m_character;
					if (SceneManagerHelper.ActiveSceneName == "ChersoneseDungeonsSmall")
					{
						((MonoBehaviour)Instance).StartCoroutine(Instance.Unfade(character));
					}
				}
			}
		}

		public static MadExtrasManager Instance;

		private static int baseDelayID = -2001;

		private static int breakDelayID = -2002;

		private static int breakSpeedID = -2003;

		private static int ignorePainID = -2004;

		private static int ignorePlusID = -2005;

		private static int etherealSkinID = -2006;

		private static int halfDamageID = -2007;

		private static int purShieldID = -2008;

		private static int purCleanseID = -2009;

		private static int applyMadnessID = -2010;

		private static int drainMadnessID = -2011;

		private static int expellMadnessID = -2012;

		private static int extremismhp = -2013;

		private static int masochism = -2014;

		private static int desperation = -2018;

		private static int shareMadness = -2017;

		private static int secretEffect1ID = -2015;

		private static int secretEffect2ID = -2016;

		private static int upgraderID = -2020;

		private static int skullDropChance = 20;

		private bool blockNotifs;

		private static int whispSkull = -2049;

		private static int whispPassive = -2050;

		private string skullStart = "The skull whispers to you constantly. It slowly takes over your mind...“I will guide your path...”";

		private string skullTalking = "The whispers fill your mind with lust and pain. “The voices here... They call your name... The Mad ones...”";

		private string skullDrop = "The whispers are eternal...";

		private string skullSilent = "The skull seems silent. For now. “...”";

		private string skullTeasing = "The skull invades your mind: “The Mad Ones are here. Open your mind to the masters. Surrender to their will.”";

		private string skullMadTalk = "The whispers fill your mind with thoughts of madness “A Mad one is here... find him. Madness take over.”";

		private string skullPureTalk = "The whispers make you feel enraged. In need of cleansing the world: “A Mad One... He's watching you.”";

		private string skullInsTalk = "The insanity fills your body, overpowering your thoughts: “Purge these fools. Claim your prize. Bow before the Mad One.”";

		private string skullPainTalk = "The whispers overwhelm your body. The Pain is unbearable: “Embrace the Mad One in the cold. Enjoy the pain of mortality”";

		private string skullSecret1Talk = "The skull fills your mind with doubt and confusion: “A Mad One? Here? I can hear its whispers. But where is it...”";

		private string skullNearbyTalk = "The whispers become louder as you feel a presence nearby: “There's a Mad One nearby. One of these places. Find him.”";

		private string skullFuture = "The whispers seem to be planning something. You are filled with lust of power. “Rest for now, whisperer. I will make use of you soon.”";

		private string skullHarmTalk = "The whispers cloud your mind. Chills shiver your body: “Slaughter... Murder... Betrayal... and a Mad One. Here.”";

		private List<Character> madGhosts;

		private int ghostTrigger;

		private SL_Character mysteryMan;

		private Vector3 hollowSmallPos = new Vector3(1810f, 0f, 30f);

		private Vector3 cherzSmallPos = new Vector3(1199f, 0f, -1f);

		private Vector3 chersNearby = new Vector3(1294f, 25f, 1207f);

		private Vector3 emercarNearby = new Vector3(1422f, -18f, 1715f);

		private Vector3 abrassarNearby = new Vector3(-732f, 100f, -715f);

		private Vector3 hallowNearbyJade = new Vector3(1675f, -61f, 575f);

		private Vector3 hallowNearbyGiant = new Vector3(890f, -50f, 1468f);

		private Vector3 antiqueNearby = new Vector3(964.6f, 48f, 460f);

		private Vector3 antiqueSmallPos = new Vector3(2100.2f, 0.1f, 13.5f);

		private bool stopNotify;

		private float notifyRange = 150f;

		private float smallNotifyRange = 50f;

		private float nearbyTimer;

		private Vector3 lastPos = new Vector3(8.3f, -3.8f, 4.4f);

		internal void Awake()
		{
			madGhosts = new List<Character>();
			Instance = this;
			SL.OnGameplayResumedAfterLoading += TrainerSpawn;
			DescriptionHelper.OnDescriptionModified = (DescriptionHelper.DescriptionModifier)Delegate.Combine(DescriptionHelper.OnDescriptionModified, new DescriptionHelper.DescriptionModifier(SkullDescriptionModifier));
		}

		private static void checkSkulls(Character player)
		{
			if (!((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(-2050))
			{
				return;
			}
			bool flag = player.Inventory.OwnsOrHasEquipped(whispSkull);
			List<Item> ownedItems = player.Inventory.GetOwnedItems(whispSkull);
			int num = ownedItems.Count;
			if (num > 1 || flag)
			{
				foreach (Item item in ownedItems)
				{
					if (num > 1)
					{
						item.RemoveQuantity(1);
						num--;
					}
				}
				return;
			}
			if (num == 0 && !flag)
			{
				((MonoBehaviour)Instance).StartCoroutine(Instance.BlockNotifs());
				player.Inventory.ReceiveItemReward(whispSkull, 1, false);
			}
		}

		private IEnumerator BlockNotifs()
		{
			blockNotifs = true;
			yield return (object)new WaitForSeconds(1f);
			blockNotifs = false;
		}

		private IEnumerator Unfade(Character player)
		{
			yield return (object)new WaitForSeconds(0.5f);
			BlackFade.Instance.StartFade(true);
			yield return (object)new WaitForSeconds(2.5f);
			List<Character> list = new List<Character>();
			CharacterManager.Instance.FindCharactersInRange(player.CenterPosition, 6f, ref list);
			foreach (Character item in list)
			{
				if (item.IsAI)
				{
					((Component)item).gameObject.SetActive(false);
				}
			}
			player.AutoKnock(true, Vector3.back, player);
			yield return (object)new WaitForSeconds(0.5f);
			BlackFade.Instance.StartFade(false);
		}

		private void SkullDescriptionModifier(Item item, ref string description)
		{
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_046b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0476: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0522: Unknown result type (might be due to invalid IL or missing references)
			//IL_052d: Unknown result type (might be due to invalid IL or missing references)
			if (item.ItemID != whispSkull)
			{
				return;
			}
			Character ownerCharacter = ((EffectSynchronizer)item).OwnerCharacter;
			if (ownerCharacter.Inventory.ItemCount(whispSkull) > 1)
			{
				Debug.Log((object)"much skulls, wow");
				return;
			}
			bool flag = ((CharacterKnowledge)ownerCharacter.Inventory.SkillKnowledge).IsItemLearned(upgraderID);
			bool flag2 = ((CharacterKnowledge)ownerCharacter.Inventory.SkillKnowledge).IsItemLearned(ignorePlusID) || ((CharacterKnowledge)ownerCharacter.Inventory.SkillKnowledge).IsItemLearned(etherealSkinID);
			bool flag3 = ((CharacterKnowledge)ownerCharacter.Inventory.SkillKnowledge).IsItemLearned(desperation) || ((CharacterKnowledge)ownerCharacter.Inventory.SkillKnowledge).IsItemLearned(masochism);
			bool flag4 = ((CharacterKnowledge)ownerCharacter.Inventory.SkillKnowledge).IsItemLearned(purCleanseID) || ((CharacterKnowledge)ownerCharacter.Inventory.SkillKnowledge).IsItemLearned(purShieldID);
			bool flag5 = ((CharacterKnowledge)ownerCharacter.Inventory.SkillKnowledge).IsItemLearned(drainMadnessID) || ((CharacterKnowledge)ownerCharacter.Inventory.SkillKnowledge).IsItemLearned(extremismhp);
			bool flag6 = ((CharacterKnowledge)ownerCharacter.Inventory.SkillKnowledge).IsItemLearned(expellMadnessID) || ((CharacterKnowledge)ownerCharacter.Inventory.SkillKnowledge).IsItemLearned(shareMadness);
			if (SceneManagerHelper.ActiveSceneName == "ChersoneseNewTerrain")
			{
				if (Vector3.Distance(chersNearby, ((Component)ownerCharacter).transform.position) < notifyRange && !((CharacterKnowledge)ownerCharacter.Inventory.SkillKnowledge).IsItemLearned(upgraderID))
				{
					UpdateDesc(ownerCharacter, item, skullNearbyTalk);
				}
				else
				{
					UpdateDesc(ownerCharacter, item, skullSilent);
				}
			}
			else if (SceneManagerHelper.ActiveSceneName == "Emercar")
			{
				float num = Vector3.Distance(emercarNearby, ((Component)ownerCharacter).transform.position);
				if (flag && num < notifyRange && !flag2)
				{
					UpdateDesc(ownerCharacter, item, skullNearbyTalk);
				}
				else
				{
					UpdateDesc(ownerCharacter, item, skullSilent);
				}
			}
			else if (SceneManagerHelper.ActiveSceneName == "HallowedMarshNewTerrain")
			{
				if (flag)
				{
					float num2 = Vector3.Distance(hallowNearbyJade, ((Component)ownerCharacter).transform.position);
					if (Vector3.Distance(hallowNearbyGiant, ((Component)ownerCharacter).transform.position) < notifyRange && !flag3)
					{
						UpdateDesc(ownerCharacter, item, skullNearbyTalk);
					}
					else if (num2 < notifyRange && !flag5)
					{
						UpdateDesc(ownerCharacter, item, skullNearbyTalk);
					}
				}
				else
				{
					UpdateDesc(ownerCharacter, item, skullSilent);
				}
			}
			else if (SceneManagerHelper.ActiveSceneName == "Abrassar")
			{
				float num3 = Vector3.Distance(abrassarNearby, ((Component)ownerCharacter).transform.position);
				if (flag && num3 < notifyRange && !flag4)
				{
					UpdateDesc(ownerCharacter, item, skullNearbyTalk);
				}
				else
				{
					UpdateDesc(ownerCharacter, item, skullSilent);
				}
			}
			else if (SceneManagerHelper.ActiveSceneName == "AntiqueField")
			{
				float num4 = Vector3.Distance(antiqueNearby, ((Component)ownerCharacter).transform.position);
				if (flag && num4 < notifyRange && !flag6)
				{
					UpdateDesc(ownerCharacter, item, skullNearbyTalk);
				}
				else
				{
					UpdateDesc(ownerCharacter, item, skullSilent);
				}
			}
			else if (SceneManagerHelper.ActiveSceneName == "Chersonese_Dungeon3")
			{
				if (flag)
				{
					UpdateDesc(ownerCharacter, item, skullSilent);
				}
				else
				{
					UpdateDesc(ownerCharacter, item, skullTeasing);
				}
			}
			else if (SceneManagerHelper.ActiveSceneName == "Emercar_Dungeon4")
			{
				if (flag && !flag2)
				{
					UpdateDesc(ownerCharacter, item, skullPainTalk);
				}
				else
				{
					UpdateDesc(ownerCharacter, item, skullSilent);
				}
			}
			else if (SceneManagerHelper.ActiveSceneName == "Abrassar_Dungeon6")
			{
				if (flag && !flag4)
				{
					UpdateDesc(ownerCharacter, item, skullPureTalk);
				}
				else
				{
					UpdateDesc(ownerCharacter, item, skullSilent);
				}
			}
			else if (SceneManagerHelper.ActiveSceneName == "Hallowed_Dungeon1")
			{
				if (flag && !flag5)
				{
					UpdateDesc(ownerCharacter, item, skullMadTalk);
				}
				else
				{
					UpdateDesc(ownerCharacter, item, skullSilent);
				}
			}
			else if (SceneManagerHelper.ActiveSceneName == "HallowedDungeonsSmall")
			{
				float num5 = Vector3.Distance(hollowSmallPos, ((Component)ownerCharacter).transform.position);
				if (flag && num5 < 50f && !flag3)
				{
					UpdateDesc(ownerCharacter, item, skullInsTalk);
				}
				else
				{
					UpdateDesc(ownerCharacter, item, skullSilent);
				}
			}
			else if (SceneManagerHelper.ActiveSceneName == "AntiqueFieldDungeonsSmall")
			{
				float num6 = Vector3.Distance(antiqueSmallPos, ((Component)ownerCharacter).transform.position);
				if (flag && num6 < 50f && !flag6)
				{
					UpdateDesc(ownerCharacter, item, skullHarmTalk);
				}
				else
				{
					UpdateDesc(ownerCharacter, item, skullSilent);
				}
			}
			else if (SceneManagerHelper.ActiveSceneName == "ChersoneseDungeonsSmall")
			{
				float num7 = Vector3.Distance(cherzSmallPos, ((Component)ownerCharacter).transform.position);
				if (flag && num7 < 50f)
				{
					UpdateDesc(ownerCharacter, item, skullSecret1Talk);
				}
				else
				{
					UpdateDesc(ownerCharacter, item, skullSilent);
				}
			}
			else
			{
				UpdateDesc(ownerCharacter, item, skullSilent);
			}
			if (flag2 && flag3 && flag4 && flag5 && flag6)
			{
				CustomItems.SetDescription(item, skullFuture);
			}
		}

		private void UpdateDesc(Character player, Item item, string desc)
		{
			if (player.Inventory.OwnsOrHasEquipped(whispSkull))
			{
				CustomItems.SetDescription(item, desc);
			}
		}

		private void TrainerSpawn()
		{
			if (CharacterManager.Instance.GetWorldHostCharacter().IsLocalPlayer)
			{
				((MonoBehaviour)this).StartCoroutine(delayedTrainerSpawn());
			}
		}

		private IEnumerator delayedTrainerSpawn()
		{
			yield return (object)new WaitForSeconds(1f);
			bool flag = false;
			foreach (PlayerSystem item in Global.Lobby.PlayersInLobby)
			{
				bool flag2 = item.ControlledCharacter.Inventory.OwnsOrHasEquipped(whispSkull);
				bool flag3 = ((CharacterKnowledge)item.ControlledCharacter.Inventory.SkillKnowledge).IsItemLearned(upgraderID);
				string activeSceneName = SceneManagerHelper.ActiveSceneName;
				if (!item.IsLocalPlayer || flag)
				{
					continue;
				}
				if (activeSceneName == "ChersoneseDungeonsSmall" && !((CharacterKnowledge)item.ControlledCharacter.Inventory.SkillKnowledge).IsItemLearned(whispPassive))
				{
					Vector3 trainerPos = new Vector3(6.7f, -3f, 29.8f);
					Vector3 trainerRot = new Vector3(0f, 150.5f, 0f);
					string whisperMystery = TrainerIDs.whisperMystery;
					SpawnTrainer(whisperMystery, trainerPos, trainerRot);
					flag = true;
				}
				if (activeSceneName == "Chersonese_Dungeon3" && flag2)
				{
					Vector3 trainerPos = new Vector3(-6.7f, 0.1f, -74.6f);
					Vector3 trainerRot = new Vector3(0f, 90f, 0f);
					string whisperMystery = TrainerIDs.whisperMain;
					SpawnTrainer(whisperMystery, trainerPos, trainerRot);
					flag = true;
					SkullNotifyFX(item.ControlledCharacter);
				}
				else if (activeSceneName == "Emercar_Dungeon4" && flag3)
				{
					Vector3 trainerPos = new Vector3(34.8f, -25f, 185.2f);
					Vector3 trainerRot = new Vector3(0f, 164.6f, 0f);
					string whisperMystery = TrainerIDs.whisperUpgrade1;
					SpawnTrainer(whisperMystery, trainerPos, trainerRot);
					flag = true;
					SkullNotifyFX(item.ControlledCharacter);
				}
				else if (activeSceneName == "Abrassar_Dungeon6" && flag3)
				{
					Vector3 trainerPos = new Vector3(-85.5f, 3.2f, 24.3f);
					Vector3 trainerRot = new Vector3(0f, 42.4f, 0f);
					string whisperMystery = TrainerIDs.whisperUpgrade2;
					SpawnTrainer(whisperMystery, trainerPos, trainerRot);
					flag = true;
					SkullNotifyFX(item.ControlledCharacter);
				}
				else if (activeSceneName == "Hallowed_Dungeon1" && flag3)
				{
					Vector3 trainerPos = new Vector3(34.8f, 26.8f, 473.3f);
					Vector3 trainerRot = new Vector3(0f, 315.1f, 0f);
					string whisperMystery = TrainerIDs.whisperUpgrade3;
					SpawnTrainer(whisperMystery, trainerPos, trainerRot);
					flag = true;
					SkullNotifyFX(item.ControlledCharacter);
				}
				else if (activeSceneName == "HallowedDungeonsSmall" && flag3)
				{
					Vector3 trainerPos = new Vector3(1791.9f, -4.8f, 44.4f);
					Vector3 trainerRot = new Vector3(0f, 92.5f, 0f);
					string whisperMystery = TrainerIDs.whisperUpgrade4;
					SpawnTrainer(whisperMystery, trainerPos, trainerRot);
					flag = true;
					if (Vector3.Distance(hollowSmallPos, ((Component)item).transform.position) < smallNotifyRange)
					{
						SkullNotifyFX(item.ControlledCharacter);
					}
				}
				else if (activeSceneName == "AntiqueFieldDungeonsSmall" && flag3)
				{
					Vector3 trainerPos = new Vector3(2144.9f, -25.1f, 8.2f);
					Vector3 trainerRot = new Vector3(0f, 359.7f, 0f);
					string whisperMystery = TrainerIDs.whisperUpgrade5;
					SpawnTrainer(whisperMystery, trainerPos, trainerRot);
					flag = true;
					if (Vector3.Distance(antiqueSmallPos, ((Component)item).transform.position) < smallNotifyRange)
					{
						SkullNotifyFX(item.ControlledCharacter);
					}
					SkullNotifyFX(item.ControlledCharacter);
				}
				else if (activeSceneName == "ChersoneseDungeonsSmall" && flag3)
				{
					Vector3 trainerPos = new Vector3(1223.5f, 0f, -2.8f);
					Vector3 trainerRot = new Vector3(0f, 307f, 0f);
					string whisperMystery = TrainerIDs.whisperSecret1;
					SpawnTrainer(whisperMystery, trainerPos, trainerRot);
					flag = true;
					if (Vector3.Distance(cherzSmallPos, ((Component)item).transform.position) < smallNotifyRange)
					{
						SkullNotifyFX(item.ControlledCharacter);
					}
				}
			}
		}

		private void SpawnTrainer(string trainerID, Vector3 trainerPos, Vector3 trainerRot)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			SL_Character val = SL.GetSLPack(SLPackIDs.madSLPack).CharacterTemplates[trainerID];
			val.Spawn(trainerPos, trainerRot, UID.op_Implicit(UID.Generate()), (string)null);
			if (trainerID == TrainerIDs.whisperMystery)
			{
				mysteryMan = val;
			}
		}

		private void SkullNotifyFX(Character player)
		{
			player.StatusEffectMngr.AddStatusEffect("SkullNotif");
			player.CharacterUI.ShowInfoNotification("The Skull is trying to talk to you");
			player.CharacterUI.NotificationPanel.ShowNotification("The Skull is trying to talk to you", 4f);
		}

		private void LateUpdate()
		{
			nearbyTimer += Time.deltaTime;
			if (!(nearbyTimer >= 5f))
			{
				return;
			}
			nearbyTimer = 0f;
			foreach (PlayerSystem item in Global.Lobby.PlayersInLobby)
			{
				if (!item.IsLocalPlayer)
				{
					break;
				}
				if (item.ControlledCharacter.Inventory.OwnsOrHasEquipped(whispSkull))
				{
					NearbyNotification(item.ControlledCharacter);
				}
			}
		}

		private void NearbyNotification(Character player)
		{
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			bool flag = ((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(ignorePlusID) || ((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(etherealSkinID);
			bool flag2 = ((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(desperation) || ((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(masochism);
			bool flag3 = ((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(purCleanseID) || ((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(purShieldID);
			bool flag4 = ((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(drainMadnessID) || ((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(extremismhp);
			bool flag5 = ((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(expellMadnessID) || ((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(shareMadness);
			if (!((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(upgraderID))
			{
				if (SceneManagerHelper.ActiveSceneName == "ChersoneseNewTerrain" && !stopNotify && Vector3.Distance(chersNearby, ((Component)player).transform.position) < notifyRange)
				{
					SkullNotifyFX(player);
					stopNotify = true;
				}
			}
			else
			{
				if (!((CharacterKnowledge)player.Inventory.SkillKnowledge).IsItemLearned(upgraderID))
				{
					return;
				}
				if (SceneManagerHelper.ActiveSceneName == "Emercar" && !stopNotify)
				{
					if (!flag && Vector3.Distance(emercarNearby, ((Component)player).transform.position) < notifyRange)
					{
						SkullNotifyFX(player);
						stopNotify = true;
					}
				}
				else if (SceneManagerHelper.ActiveSceneName == "Abrassar" && !stopNotify)
				{
					if (!flag3 && Vector3.Distance(abrassarNearby, ((Component)player).transform.position) < notifyRange)
					{
						SkullNotifyFX(player);
						stopNotify = true;
					}
				}
				else if (SceneManagerHelper.ActiveSceneName == "HallowedMarshNewTerrain" && !stopNotify)
				{
					float num = Vector3.Distance(hallowNearbyJade, ((Component)player).transform.position);
					float num2 = Vector3.Distance(hallowNearbyGiant, ((Component)player).transform.position);
					if (!flag4 && num < notifyRange)
					{
						SkullNotifyFX(player);
						stopNotify = true;
					}
					if (!flag2 && num2 < notifyRange)
					{
						SkullNotifyFX(player);
						stopNotify = true;
					}
				}
				else if (SceneManagerHelper.ActiveSceneName == "AntiqueField" && !stopNotify && !flag5 && Vector3.Distance(antiqueNearby, ((Component)player).transform.position) < notifyRange)
				{
					SkullNotifyFX(player);
					stopNotify = true;
				}
			}
		}
	}
}
namespace Lorewalker
{
	internal static class PlagueManager
	{
		[HarmonyPatch(typeof(PunctualDamage), "ActivateLocally")]
		public class PunctualDamage_ActivateLocally
		{
			[HarmonyPrefix]
			public static void Prefix(PunctualDamage __instance, Character _targetCharacter, object[] _infos)
			{
				if (!Object.op_Implicit((Object)(object)((Effect)__instance).SourceCharacter) || !((Effect)__instance).SourceID.Contains(TimeWalkerIDs.TimePlagueFamily))
				{
					return;
				}
				Debug.Log((object)("IdentifierName: " + ((Effect)__instance).m_parentStatusEffect.IdentifierName));
				Debug.Log((object)("Time: " + ((Effect)__instance).m_parentStatusEffect.RemainingLifespan));
				bool num = ((Effect)__instance).SourceCharacter.StatusEffectMngr.HasStatusEffect(TimeWalkerIDs.activeTimelineEffect) && ((Effect)__instance).SourceCharacter.StatusEffectMngr.GetStatusLevel(TimeWalkerIDs.activeTimelineEffect) == 1;
				int timelineMult = 1;
				if (num)
				{
					timelineMult = LoreWalkerBalance.timelinePlagueMult;
					for (int i = 0; i < __instance.DamagesAI.Length; i++)
					{
						if (__instance.DamagesAI[i] == null || !(__instance.DamagesAI[i].Damage > 0f))
						{
							continue;
						}
						if (((Effect)__instance).m_parentStatusEffect.IdentifierName == TimeWalkerIDs.TimePlagueCburnout)
						{
							if (((Effect)__instance).OwnerCharacter.StatusEffectMngr.HasStatusEffect(TimeWalkerIDs.plagueBurnoutTracker))
							{
								Debug.Log((object)("Level: " + ((Effect)__instance).OwnerCharacter.StatusEffectMngr.GetStatusLevel(TimeWalkerIDs.plagueBurnoutTracker)));
								__instance.DamagesAI[i].Damage = ((Effect)__instance).OwnerCharacter.StatusEffectMngr.GetStatusLevel(TimeWalkerIDs.plagueBurnoutTracker);
							}
							else
							{
								__instance.DamagesAI[i].Damage = 1f;
							}
						}
						else
						{
							__instance.DamagesAI[i].Damage = 1f;
						}
					}
				}
				else
				{
					for (int j = 0; j < __instance.DamagesAI.Length; j++)
					{
						if (__instance.DamagesAI[j] == null || !(__instance.DamagesAI[j].Damage > 0f))
						{
							continue;
						}
						if (((Effect)__instance).m_parentStatusEffect.IdentifierName == TimeWalkerIDs.TimePlagueCburnout)
						{
							if (((Effect)__instance).OwnerCharacter.StatusEffectMngr.HasStatusEffect(TimeWalkerIDs.plagueBurnoutTracker))
							{
								Debug.Log((object)("Level: " + ((Effect)__instance).OwnerCharacter.StatusEffectMngr.GetStatusLevel(TimeWalkerIDs.plagueBurnoutTracker)));
								__instance.DamagesAI[j].Damage = (float)((Effect)__instance).OwnerCharacter.StatusEffectMngr.GetStatusLevel(TimeWalkerIDs.plagueBurnoutTracker) / 2f;
							}
							else
							{
								__instance.DamagesAI[j].Damage = 0.5f;
							}
						}
						else
						{
							__instance.DamagesAI[j].Damage = 0.5f;
						}
					}
				}
				PlagueEffects(__instance, timelineMult);
			}
		}

		[HarmonyPatch(typeof(PunctualDamageAoE), "ActivateLocally")]
		public class PunctualDamageAoE_ActivateLocally
		{
			[HarmonyPrefix]
			public static void Prefix(PunctualDamageAoE __instance, Character _targetCharacter, object[] _infos)
			{
				if (Object.op_Implicit((Object)(object)((Effect)__instance).SourceCharacter) && ((Effect)__instance).SourceCharacter.IsLocalPlayer && Object.op_Implicit((Object)(object)((Effect)__instance).m_parentStatusEffect) && ((Effect)__instance).m_parentStatusEffect.IdentifierName.Contains(TimeWalkerIDs.pandemicEffect))
				{
					((MonoBehaviour)Plugin.Instance).StartCoroutine(PandemicPlagues(((Effect)__instance).SourceCharacter));
				}
			}
		}

		[HarmonyPatch(typeof(Character), "OnReceiveHit")]
		public class Character_OnReceiveHit
		{
			[HarmonyPrefix]
			public static void Prefix(Character __instance, Weapon _weapon, float _damage, DamageList _damageList, Vector3 _hitDir, Vector3 _hitPoint, float _angle, float _angleDir, Character _dealerChar, float _knockBack)
			{
				if (Object.op_Implicit((Object)(object)_dealerChar) && _dealerChar.IsLocalPlayer && !((Object)(object)_weapon == (Object)null) && _damageList != null)
				{
					RefreshBurnPlague(__instance, _dealerChar, _damage);
				}
			}
		}

		private static int level = 1;

		public static void PlagueEffects(PunctualDamage _plagueDmg, int timelineMult)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			if (((Effect)_plagueDmg).m_parentStatusEffect.IdentifierName == TimeWalkerIDs.TimePlagueAcooldown)
			{
				float plagueCDrestore = LoreWalkerBalance.plagueCDrestore;
				{
					foreach (Skill learnedItem in ((CharacterKnowledge)((Effect)_plagueDmg).SourceCharacter.Inventory.SkillKnowledge).m_learnedItems)
					{
						Skill val = learnedItem;
						if (!val.IsPassive && val.InCooldown())
						{
							_ = val.m_remainingCooldownTime;
							val.m_remainingCooldownTime -= plagueCDrestore * (float)timelineMult;
							if (val.m_remainingCooldownTime <= 0f)
							{
								val.m_remainingCooldownTime = 0f;
							}
						}
					}
					return;
				}
			}
			if (((Effect)_plagueDmg).m_parentStatusEffect.IdentifierName == TimeWalkerIDs.TimePlagueBweakness)
			{
				for (int i = 0; i < timelineMult;