Decompiled source of MonsterModifiers v1.3.3

MonsterModifiers.dll

Decompiled 2 hours 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 System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using Jotunn;
using Jotunn.Entities;
using Jotunn.Extensions;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using MonsterModifiers.Custom_Components;
using MonsterModifiers.Modifiers;
using MonsterModifiers.StatusEffects;
using MonsterModifiers.Visuals;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("MonsterModifiers")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("KorCaptain")]
[assembly: AssemblyProduct("MonsterModifiers")]
[assembly: AssemblyCopyright("Copyright ©  2022")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("E0E2F92E-557C-4A05-9D89-AA92A0BD75C4")]
[assembly: AssemblyFileVersion("1.3.3")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.3.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace MonsterModifiers
{
	[BepInPlugin("KorCaptain.MonsterModifiers", "MonsterModifiers", "1.3.3")]
	public class MonsterModifiersPlugin : BaseUnityPlugin
	{
		public enum Toggle
		{
			On = 1,
			Off = 0
		}

		internal const string ModName = "MonsterModifiers";

		internal const string ModVersion = "1.3.3";

		internal const string Author = "KorCaptain";

		private const string ModGUID = "KorCaptain.MonsterModifiers";

		private static string ConfigFileName = "KorCaptain.MonsterModifiers.cfg";

		private static string ConfigFileFullPath;

		internal static string ConnectionError;

		private readonly Harmony _harmony = new Harmony("KorCaptain.MonsterModifiers");

		public static readonly ManualLogSource MonsterModifiersLogger;

		public Texture2D tex = null;

		public static ConfigEntry<int> Configurations_Monster_Modifiers;

		public static ConfigEntry<int> Configurations_Boss_Modifiers;

		public static ConfigEntry<int> Cfg_PierceImmunity_DamageReduction;

		public static ConfigEntry<int> Cfg_SlashImmunity_DamageReduction;

		public static ConfigEntry<int> Cfg_BluntImmunity_DamageReduction;

		public static ConfigEntry<int> Cfg_ElementalImmunity_DamageReduction;

		public static ConfigEntry<int> Cfg_Knockback_StaggerForce;

		public static ConfigEntry<int> Cfg_Knockback_PushForce;

		public static ConfigEntry<float> Cfg_FastAttackSpeed_AnimatorMultiplier;

		public static ConfigEntry<float> Cfg_FastAttackSpeed_IntervalReduction;

		public static ConfigEntry<float> Cfg_SplitSpawn_Scale;

		public static ConfigEntry<float> Cfg_SplitSpawn_HP;

		public static ConfigEntry<Toggle> Cfg_SplitSpawn_RandomizeWeapon;

		public static ConfigEntry<float> Cfg_ShieldBreaker_DurabilityThreshold;

		public static ConfigEntry<float> Cfg_ShieldBreaker_DurabilityReduction;

		public static ConfigEntry<float> Cfg_IgnoreArmor_ArmorReduction;

		public static ConfigEntry<float> Cfg_FoodDrain_DurationReduction;

		public static ConfigEntry<float> Cfg_ElementalInfusion_DamageRatio;

		public static ConfigEntry<float> Cfg_Forceful_PushMultiplier;

		public static ConfigEntry<float> Cfg_Vampiric_HealRatio;

		public static ConfigEntry<int> Cfg_PersonalShield_Duration;

		public static ConfigEntry<float> Cfg_PersonalShield_Magnitude;

		public static ConfigEntry<float> Cfg_FastMovement_SpeedMultiplier;

		public static ConfigEntry<float> Cfg_DistantDetection_RangeMultiplier;

		public static ConfigEntry<float> Cfg_SoulEater_Radius;

		public static ConfigEntry<int> Cfg_SoulEater_MaxStacks;

		public static ConfigEntry<float> Cfg_SoulEater_GrowthMultiplier;

		public static ConfigEntry<float> Cfg_SoulEater_DmgStack1;

		public static ConfigEntry<float> Cfg_SoulEater_DmgStack2;

		public static ConfigEntry<float> Cfg_SoulEater_DmgStack3;

		public static ConfigEntry<int> Cfg_ResistanceNotification_MaxCount;

		public static ConfigEntry<int> Cfg_Boss_OffenseMultiplier;

		public static ConfigEntry<int> Cfg_Boss_HealMultiplier;

		public static ConfigEntry<int> Cfg_Offense_Probability;

		public static ConfigEntry<int> Cfg_Defense_Probability;

		public static ConfigEntry<int> Cfg_Utility_Probability;

		public static ConfigEntry<int> Cfg_SplitSpawn_Probability;

		public static ConfigEntry<Toggle> Cfg_EliteMonster_Enabled;

		public static ConfigEntry<int> Cfg_EliteMonster_Probability;

		public static ConfigEntry<int> Cfg_Elite_Size;

		public static ConfigEntry<int> Cfg_Elite_HP;

		public static ConfigEntry<int> Cfg_Elite_ATK;

		public static ConfigEntry<int> Cfg_Elite_DFS;

		public void Awake()
		{
			bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet;
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = false;
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			_harmony.PatchAll(executingAssembly);
			SetupWatcher();
			if (saveOnConfigSet)
			{
				((BaseUnityPlugin)this).Config.SaveOnConfigSet = saveOnConfigSet;
				((BaseUnityPlugin)this).Config.Save();
			}
			YamlUtils.ParseDefaultYamls();
			TranslationUtils.AddLocalizations();
			ModifierAssetUtils.Setup();
			ModifierAssetUtils.LoadAllIcons();
			int length = Enum.GetValues(typeof(MonsterModifierTypes)).Length;
			int num = length - ModifierUtils.BossExcludedModifiers.Count;
			ConfigFile config = ((BaseUnityPlugin)this).Config;
			AcceptableValueBase val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, num);
			Configurations_Boss_Modifiers = ConfigFileExtensions.BindConfig<int>(config, "General", "boss_Modifiers", 5, "Minimum modifiers for bosses (0 = disabled). Max is auto-calculated excluding death-spawn modifiers. N = always assign at least N modifiers.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			SetConfigOrder((ConfigEntryBase)(object)Configurations_Boss_Modifiers, 7);
			Cfg_EliteMonster_Enabled = ConfigFileExtensions.BindConfig<Toggle>(((BaseUnityPlugin)this).Config, "General", "Elite_Monster", Toggle.On, "Enable Elite Monster spawning. When Off, its 10% probability is automatically redistributed (+5% Offense, +5% Defense).", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			SetConfigOrder((ConfigEntryBase)(object)Cfg_EliteMonster_Enabled, 6);
			ConfigFile config2 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, length);
			Configurations_Monster_Modifiers = ConfigFileExtensions.BindConfig<int>(config2, "General", "Monster_Modifiers", 5, "Maximum modifiers for regular monsters. 0 = disabled.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			SetConfigOrder((ConfigEntryBase)(object)Configurations_Monster_Modifiers, 5);
			ConfigFile config3 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100);
			Cfg_EliteMonster_Probability = ConfigFileExtensions.BindConfig<int>(config3, "General", "Elite_Monster_Probability", 10, "Relative roll probability for Elite Monster (boss-excluded, biome-spawn only).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			SetConfigOrder((ConfigEntryBase)(object)Cfg_EliteMonster_Probability, 4);
			ConfigFile config4 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100);
			Cfg_SplitSpawn_Probability = ConfigFileExtensions.BindConfig<int>(config4, "General", "SplitSpawn_Probability", 10, "Relative roll probability for SplitSpawn modifier (boss-excluded). Set 0 to disable SplitSpawn from rolling.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			SetConfigOrder((ConfigEntryBase)(object)Cfg_SplitSpawn_Probability, 3);
			ConfigFile config5 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100);
			Cfg_Offense_Probability = ConfigFileExtensions.BindConfig<int>(config5, "General", "Offense_Probability", 35, "Relative roll probability for Offense modifiers (values are treated as ratio).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			SetConfigOrder((ConfigEntryBase)(object)Cfg_Offense_Probability, 2);
			ConfigFile config6 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100);
			Cfg_Defense_Probability = ConfigFileExtensions.BindConfig<int>(config6, "General", "Defense_Probability", 35, "Relative roll probability for Defense modifiers (values are treated as ratio).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			SetConfigOrder((ConfigEntryBase)(object)Cfg_Defense_Probability, 1);
			ConfigFile config7 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100);
			Cfg_Utility_Probability = ConfigFileExtensions.BindConfig<int>(config7, "General", "Utility_Probability", 10, "Relative roll probability for Utility modifiers.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			SetConfigOrder((ConfigEntryBase)(object)Cfg_Utility_Probability, 0);
			ConfigFile config8 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100);
			Cfg_PierceImmunity_DamageReduction = ConfigFileExtensions.BindConfig<int>(config8, "Modifier_Defense", "PierceImmunity Damage Reduction %", 70, "Percentage of pierce damage reduced when PierceImmunity modifier is active. 100 = full immunity.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config9 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100);
			Cfg_SlashImmunity_DamageReduction = ConfigFileExtensions.BindConfig<int>(config9, "Modifier_Defense", "SlashImmunity Damage Reduction %", 70, "Percentage of slash damage reduced when SlashImmunity modifier is active. 100 = full immunity.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config10 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100);
			Cfg_BluntImmunity_DamageReduction = ConfigFileExtensions.BindConfig<int>(config10, "Modifier_Defense", "BluntImmunity Damage Reduction %", 70, "Percentage of blunt damage reduced when BluntImmunity modifier is active. 100 = full immunity.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config11 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100);
			Cfg_ElementalImmunity_DamageReduction = ConfigFileExtensions.BindConfig<int>(config11, "Modifier_Defense", "ElementalImmunity Damage Reduction %", 70, "Percentage of elemental damage (fire/frost/lightning/poison/spirit) reduced when ElementalImmunity modifier is active. 100 = full immunity.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config12 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2000);
			Cfg_Knockback_StaggerForce = ConfigFileExtensions.BindConfig<int>(config12, "Modifier_Offense", "Knockback Stagger Force", 500, "Stagger force applied by the Knockback modifier.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config13 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 200);
			Cfg_Knockback_PushForce = ConfigFileExtensions.BindConfig<int>(config13, "Modifier_Offense", "Knockback Push Force", 45, "Push force applied by the Knockback modifier.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config14 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f);
			Cfg_FastAttackSpeed_AnimatorMultiplier = ConfigFileExtensions.BindConfig<float>(config14, "Modifier_Offense", "FastAttackSpeed Animator Speed Multiplier", 0.3f, "Animator speed bonus for FastAttackSpeed modifier (0.3 = +30% faster animation). Default: 0.3", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config15 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.95f);
			Cfg_FastAttackSpeed_IntervalReduction = ConfigFileExtensions.BindConfig<float>(config15, "Modifier_Offense", "FastAttackSpeed Attack Interval Reduction", 0.3f, "Attack cooldown reduction fraction for FastAttackSpeed modifier (0.3 = -30% cooldown). Default: 0.3", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config16 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f);
			Cfg_SplitSpawn_Scale = ConfigFileExtensions.BindConfig<float>(config16, "Modifier_Offense", "SplitSpawn Scale", 0.85f, "Size of SplitSpawn children relative to parent size (0.7 = 70%).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config17 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f);
			Cfg_SplitSpawn_HP = ConfigFileExtensions.BindConfig<float>(config17, "Modifier_Offense", "SplitSpawn Health", 0.7f, "HP of SplitSpawn children as a fraction of parent max HP (0.7 = 70%).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			Cfg_SplitSpawn_RandomizeWeapon = ConfigFileExtensions.BindConfig<Toggle>(((BaseUnityPlugin)this).Config, "Modifier_Offense", "SplitSpawn Randomize Weapon", Toggle.On, "When On, bow-wielding creatures may spawn melee-variant children instead of archer copies.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config18 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 0.5f);
			Cfg_ShieldBreaker_DurabilityThreshold = ConfigFileExtensions.BindConfig<float>(config18, "Modifier_Offense", "ShieldBreaker Durability Threshold", 0.1f, "Shield durability fraction below which reduction is skipped (0.1 = skip if below 10%).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config19 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f);
			Cfg_ShieldBreaker_DurabilityReduction = ConfigFileExtensions.BindConfig<float>(config19, "Modifier_Offense", "ShieldBreaker Durability Reduction", 0.5f, "Multiplier applied to shield durability on block (0.5 = halved).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config20 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f);
			Cfg_IgnoreArmor_ArmorReduction = ConfigFileExtensions.BindConfig<float>(config20, "Modifier_Offense", "IgnoreArmor Armor Reduction", 0.5f, "Multiplier applied to player armor value (0.5 = armor halved).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config21 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f);
			Cfg_FoodDrain_DurationReduction = ConfigFileExtensions.BindConfig<float>(config21, "Modifier_Offense", "FoodDrain Duration Reduction", 0.5f, "Multiplier applied to food duration on hit (0.5 = halved).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config22 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f);
			Cfg_ElementalInfusion_DamageRatio = ConfigFileExtensions.BindConfig<float>(config22, "Modifier_Offense", "ElementalInfusion Damage Ratio", 0.5f, "Ratio of total hit damage added as elemental bonus (0.5 = +50% as element).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config23 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f);
			Cfg_Forceful_PushMultiplier = ConfigFileExtensions.BindConfig<float>(config23, "Modifier_Offense", "Forceful Push Multiplier", 5f, "Multiplier applied to hit push force (5.0 = 5x knockback).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config24 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f);
			Cfg_Vampiric_HealRatio = ConfigFileExtensions.BindConfig<float>(config24, "Modifier_Offense", "Vampiric Heal Ratio", 0.5f, "Ratio of total hit damage healed by the attacker (0.5 = heal 50% of damage).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config25 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 60);
			Cfg_PersonalShield_Duration = ConfigFileExtensions.BindConfig<int>(config25, "Modifier_Defense", "PersonalShield Duration", 10, "Duration (seconds) of the GoblinShaman shield status effect.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config26 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 10f);
			Cfg_PersonalShield_Magnitude = ConfigFileExtensions.BindConfig<float>(config26, "Modifier_Defense", "PersonalShield Magnitude", 2f, "Magnitude of the GoblinShaman shield status effect.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config27 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f);
			Cfg_FastMovement_SpeedMultiplier = ConfigFileExtensions.BindConfig<float>(config27, "Modifier_Utility", "FastMovement Speed Multiplier", 1.5f, "Speed multiplier applied to m_speed/m_runSpeed/m_walkSpeed (1.5 = +50%).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config28 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f);
			Cfg_DistantDetection_RangeMultiplier = ConfigFileExtensions.BindConfig<float>(config28, "Modifier_Utility", "DistantDetection Range Multiplier", 2f, "Multiplier applied to hear and view range (2.0 = double range).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config29 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f);
			Cfg_SoulEater_Radius = ConfigFileExtensions.BindConfig<float>(config29, "Modifier_Utility", "SoulEater Absorb Radius", 5f, "Radius (units) in which SoulEater detects dying enemies.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config30 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10);
			Cfg_SoulEater_MaxStacks = ConfigFileExtensions.BindConfig<int>(config30, "Modifier_Utility", "SoulEater Max Stacks", 3, "Maximum number of soul stacks the SoulEater can accumulate.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config31 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 2f);
			Cfg_SoulEater_GrowthMultiplier = ConfigFileExtensions.BindConfig<float>(config31, "Modifier_Utility", "SoulEater Growth Multiplier", 1.1f, "Size and health growth multiplier per stack (1.1 = +10% per soul).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config32 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 3f);
			Cfg_SoulEater_DmgStack1 = ConfigFileExtensions.BindConfig<float>(config32, "Modifier_Utility", "SoulEater Damage Stack 1", 1.1f, "Damage multiplier at 1 soul stack.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config33 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 3f);
			Cfg_SoulEater_DmgStack2 = ConfigFileExtensions.BindConfig<float>(config33, "Modifier_Utility", "SoulEater Damage Stack 2", 1.2f, "Damage multiplier at 2 soul stacks.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config34 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 3f);
			Cfg_SoulEater_DmgStack3 = ConfigFileExtensions.BindConfig<float>(config34, "Modifier_Utility", "SoulEater Damage Stack 3", 1.3f, "Damage multiplier at 3 soul stacks.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config35 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10);
			Cfg_ResistanceNotification_MaxCount = ConfigFileExtensions.BindConfig<int>(config35, "Modifier_Utility", "ResistanceNotification Max Count", 2, "Max times to show a resistance notification per damage type per enemy.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config36 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100);
			Cfg_Boss_OffenseMultiplier = ConfigFileExtensions.BindConfig<int>(config36, "Boss", "Boss_Offense_Multiplier", 20, "Scales offensive modifier effects when the modifier is on a boss (100 = full effect, 10 = 10% of normal).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config37 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100);
			Cfg_Boss_HealMultiplier = ConfigFileExtensions.BindConfig<int>(config37, "Boss", "Boss_Heal_Multiplier", 10, "Scales healing modifier effects when the modifier is on a boss (100 = full effect, 10 = 10% of normal).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config38 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 200);
			Cfg_Elite_Size = ConfigFileExtensions.BindConfig<int>(config38, "Modifier_Elite", "Elite_Monster_Size", 100, "Size increase % for Elite monsters (100 = +100% scale, i.e. 2x base size).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config39 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(100, 500);
			Cfg_Elite_HP = ConfigFileExtensions.BindConfig<int>(config39, "Modifier_Elite", "Elite_Monster_HP", 150, "Health multiplier % for Elite monsters (150 = 1.5x base HP).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config40 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 200);
			Cfg_Elite_ATK = ConfigFileExtensions.BindConfig<int>(config40, "Modifier_Elite", "Elite_Monster_ATK", 30, "Attack power increase % for Elite monsters (30 = +30% damage output).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config41 = ((BaseUnityPlugin)this).Config;
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 90);
			Cfg_Elite_DFS = ConfigFileExtensions.BindConfig<int>(config41, "Modifier_Elite", "Elite_Monster_DFS", 30, "Physical and elemental damage reduction % for Elite monsters (30 = -30% incoming damage).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ShaderLogFilter.Install();
			CompatibilityUtils.RunCompatibiltyChecks();
			StatusEffectUtils.CreateCustomStatusEffects();
			PrefabManager.OnVanillaPrefabsAvailable += PrefabUtils.CreateCustomPrefabs;
		}

		private static void SetConfigOrder(ConfigEntryBase entry, int order)
		{
			ConfigDescription description = entry.Description;
			if (((description != null) ? description.Tags : null) == null)
			{
				return;
			}
			object[] tags = entry.Description.Tags;
			foreach (object obj in tags)
			{
				if (obj == null)
				{
					continue;
				}
				PropertyInfo property = obj.GetType().GetProperty("Order");
				if (!(property == null))
				{
					try
					{
						property.SetValue(obj, (property.PropertyType == typeof(int?)) ? ((object)order) : ((object)order));
						break;
					}
					catch
					{
						break;
					}
				}
			}
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}

		private void SetupWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
			fileSystemWatcher.Changed += ReadConfigValues;
			fileSystemWatcher.Created += ReadConfigValues;
			fileSystemWatcher.Renamed += ReadConfigValues;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private void ReadConfigValues(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(ConfigFileFullPath))
			{
				return;
			}
			try
			{
				MonsterModifiersLogger.LogDebug((object)"ReadConfigValues called");
				((BaseUnityPlugin)this).Config.Reload();
			}
			catch
			{
				MonsterModifiersLogger.LogError((object)("There was an issue loading your " + ConfigFileName));
				MonsterModifiersLogger.LogError((object)"Please check your config entries for spelling and format!");
			}
		}

		static MonsterModifiersPlugin()
		{
			string configPath = Paths.ConfigPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
			ConnectionError = "";
			MonsterModifiersLogger = Logger.CreateLogSource("MonsterModifiers");
			Configurations_Monster_Modifiers = null;
			Configurations_Boss_Modifiers = null;
			Cfg_PierceImmunity_DamageReduction = null;
			Cfg_SlashImmunity_DamageReduction = null;
			Cfg_BluntImmunity_DamageReduction = null;
			Cfg_ElementalImmunity_DamageReduction = null;
			Cfg_Knockback_StaggerForce = null;
			Cfg_Knockback_PushForce = null;
			Cfg_FastAttackSpeed_AnimatorMultiplier = null;
			Cfg_FastAttackSpeed_IntervalReduction = null;
			Cfg_SplitSpawn_Scale = null;
			Cfg_SplitSpawn_HP = null;
			Cfg_SplitSpawn_RandomizeWeapon = null;
			Cfg_ShieldBreaker_DurabilityThreshold = null;
			Cfg_ShieldBreaker_DurabilityReduction = null;
			Cfg_IgnoreArmor_ArmorReduction = null;
			Cfg_FoodDrain_DurationReduction = null;
			Cfg_ElementalInfusion_DamageRatio = null;
			Cfg_Forceful_PushMultiplier = null;
			Cfg_Vampiric_HealRatio = null;
			Cfg_PersonalShield_Duration = null;
			Cfg_PersonalShield_Magnitude = null;
			Cfg_FastMovement_SpeedMultiplier = null;
			Cfg_DistantDetection_RangeMultiplier = null;
			Cfg_SoulEater_Radius = null;
			Cfg_SoulEater_MaxStacks = null;
			Cfg_SoulEater_GrowthMultiplier = null;
			Cfg_SoulEater_DmgStack1 = null;
			Cfg_SoulEater_DmgStack2 = null;
			Cfg_SoulEater_DmgStack3 = null;
			Cfg_ResistanceNotification_MaxCount = null;
			Cfg_Boss_OffenseMultiplier = null;
			Cfg_Boss_HealMultiplier = null;
			Cfg_Offense_Probability = null;
			Cfg_Defense_Probability = null;
			Cfg_Utility_Probability = null;
			Cfg_SplitSpawn_Probability = null;
			Cfg_EliteMonster_Enabled = null;
			Cfg_EliteMonster_Probability = null;
			Cfg_Elite_Size = null;
			Cfg_Elite_HP = null;
			Cfg_Elite_ATK = null;
			Cfg_Elite_DFS = null;
		}
	}
	public static class KeyboardExtensions
	{
		public static bool IsKeyDown(this KeyboardShortcut shortcut)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return (int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey);
		}

		public static bool IsKeyHeld(this KeyboardShortcut shortcut)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return (int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKey(((KeyboardShortcut)(ref shortcut)).MainKey) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey);
		}
	}
	public class CompatibilityUtils
	{
		public static bool isStarLevelsExpandedInstalled;

		public static void RunCompatibiltyChecks()
		{
			if (Chainloader.PluginInfos.ContainsKey("CreatureLevelControl"))
			{
				MonsterModifiersPlugin.MonsterModifiersLogger.LogWarning((object)"CreatureLevelandLootControl plugin is installed. Please ensure special effects and infusions are disabled in CLLC configuration.");
			}
			if (Chainloader.PluginInfos.ContainsKey("MidnightsFX.StarLevelSystem"))
			{
				MonsterModifiersPlugin.MonsterModifiersLogger.LogWarning((object)"StarLevelSystem plugin is installed. Please ensure max modifiers config is set.");
				isStarLevelsExpandedInstalled = true;
			}
		}
	}
	public class DamageUtils
	{
		public static float TryCurrentWeapon(Humanoid humanoid)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			ItemData currentWeapon = humanoid.GetCurrentWeapon();
			if (currentWeapon == null)
			{
				return 10f;
			}
			DamageTypes damage = currentWeapon.GetDamage();
			if (((DamageTypes)(ref damage)).HaveDamage())
			{
				return 10f;
			}
			float totalDamage = ((DamageTypes)(ref damage)).GetTotalDamage();
			if (totalDamage == 0f)
			{
				return 10f;
			}
			DamageTypes damage2 = humanoid.GetCurrentWeapon().GetDamage();
			return ((DamageTypes)(ref damage2)).GetTotalDamage();
		}

		public static float TryWeaponList(GameObject[] weaponArray)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			float num = 10f;
			List<GameObject> list = weaponArray.ToList();
			if (list.Count > 0)
			{
				foreach (GameObject item in list)
				{
					ItemData itemData = item.GetComponent<ItemDrop>().m_itemData;
					if (itemData != null)
					{
						DamageTypes damage = itemData.GetDamage();
						float totalDamage = ((DamageTypes)(ref damage)).GetTotalDamage();
						if (totalDamage > num)
						{
							num = totalDamage;
						}
					}
				}
			}
			if (num > 0f)
			{
			}
			return num;
		}

		public static float CalculateDamage(Character character, float percentTotal)
		{
			Humanoid val = (Humanoid)(object)((character is Humanoid) ? character : null);
			if ((Object)(object)val == (Object)null)
			{
				return 10f;
			}
			if (character.IsPlayer())
			{
				return 10f;
			}
			float num = 10f;
			float num2 = TryCurrentWeapon(val);
			if (num2 > 0f && num2 > num)
			{
				num = num2;
			}
			float num3 = TryWeaponList(val.m_defaultItems);
			if (num3 > 0f && num3 > num)
			{
				num = num3;
			}
			float num4 = TryWeaponList(val.m_randomWeapon);
			if (num4 > 0f && num4 > num)
			{
				num = num4;
			}
			return num * percentTotal;
		}
	}
	public class ModifierAssetUtils
	{
		public static AssetBundle ashlandsAssetBundle;

		public static AssetBundle statusEffectBundle;

		public static AssetBundle modiferIconsBundle;

		public static Sprite swordIcon;

		public static Sprite shieldIcon;

		public static Sprite plusSquareIcon;

		public static Sprite circleIcon;

		public static Sprite soulIcon;

		public static Sprite skullIcon;

		public static Sprite appleIcon;

		public static Sprite shieldBrokenIcon;

		public static Sprite shieldSpearIcon;

		public static Sprite shieldMaceIcon;

		public static Sprite shieldSwordIcon;

		public static Sprite potionIcon;

		public static Sprite bloodIcon;

		public static Sprite bloodIconRed;

		public static Sprite heartIcon;

		public static Sprite earIcon;

		public static void Setup()
		{
			statusEffectBundle = AssetUtils.LoadAssetBundleFromResources("statusicon", Assembly.GetExecutingAssembly());
			modiferIconsBundle = AssetUtils.LoadAssetBundleFromResources("modifiericons", Assembly.GetExecutingAssembly());
		}

		public static void LoadAllIcons()
		{
			swordIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/Sword.png");
			shieldIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/Shield.png");
			plusSquareIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/PlusBox.png");
			circleIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/Circle.png");
			soulIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/SoulEater.png");
			skullIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/Skull.png");
			appleIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/Apple.png");
			shieldBrokenIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/ShieldBroken.png");
			shieldSpearIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/ShieldSpear.png");
			shieldMaceIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/ShieldMace.png");
			shieldSwordIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/ShieldSword.png");
			potionIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/Potion.png");
			heartIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/heartIcon.png");
			bloodIcon = statusEffectBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/bloodIcon.png");
			bloodIconRed = statusEffectBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/bloodIconRed.png");
			earIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/Ear.png");
		}
	}
	public enum MonsterModifierTypes
	{
		StaminaSiphon,
		EitrSiphon,
		ShieldBreaker,
		FoodDrain,
		IgnoreArmor,
		PoisonDeath,
		FrostDeath,
		FireDeath,
		HealDeath,
		StaggerDeath,
		TarDeath,
		PersonalShield,
		ShieldDome,
		SoulEater,
		RemoveStatusEffect,
		StaggerImmune,
		FireInfused,
		PoisonInfused,
		FrostInfused,
		LightningInfused,
		ElementalImmunity,
		PierceImmunity,
		BluntImmunity,
		SlashImmunity,
		FastMovement,
		FastAttackSpeed,
		DistantDetection,
		BloodLoss,
		Absorption,
		Vampiric,
		Forceful,
		Wet,
		Quiet,
		Knockback,
		ArmorCharge,
		FireTrail,
		ResistanceNotification,
		SplitSpawn,
		EliteMonster
	}
	public enum ModifierCategory
	{
		Offense,
		Defense,
		Utility,
		SplitSpawn,
		Elite
	}
	public class ModifierData
	{
		public int weight { get; set; }

		public List<float> color { get; set; } = null;

	}
	public class ModifierUtils
	{
		public static Dictionary<MonsterModifierTypes, ModifierData> modifiers = null;

		public static readonly Dictionary<MonsterModifierTypes, ModifierCategory> ModifierCategories = new Dictionary<MonsterModifierTypes, ModifierCategory>
		{
			{
				MonsterModifierTypes.StaminaSiphon,
				ModifierCategory.Offense
			},
			{
				MonsterModifierTypes.EitrSiphon,
				ModifierCategory.Offense
			},
			{
				MonsterModifierTypes.ShieldBreaker,
				ModifierCategory.Offense
			},
			{
				MonsterModifierTypes.FoodDrain,
				ModifierCategory.Offense
			},
			{
				MonsterModifierTypes.IgnoreArmor,
				ModifierCategory.Offense
			},
			{
				MonsterModifierTypes.PoisonDeath,
				ModifierCategory.Offense
			},
			{
				MonsterModifierTypes.FrostDeath,
				ModifierCategory.Offense
			},
			{
				MonsterModifierTypes.FireDeath,
				ModifierCategory.Offense
			},
			{
				MonsterModifierTypes.StaggerDeath,
				ModifierCategory.Offense
			},
			{
				MonsterModifierTypes.TarDeath,
				ModifierCategory.Offense
			},
			{
				MonsterModifierTypes.FireInfused,
				ModifierCategory.Offense
			},
			{
				MonsterModifierTypes.PoisonInfused,
				ModifierCategory.Offense
			},
			{
				MonsterModifierTypes.FrostInfused,
				ModifierCategory.Offense
			},
			{
				MonsterModifierTypes.LightningInfused,
				ModifierCategory.Offense
			},
			{
				MonsterModifierTypes.FastAttackSpeed,
				ModifierCategory.Offense
			},
			{
				MonsterModifierTypes.BloodLoss,
				ModifierCategory.Offense
			},
			{
				MonsterModifierTypes.Vampiric,
				ModifierCategory.Offense
			},
			{
				MonsterModifierTypes.Forceful,
				ModifierCategory.Offense
			},
			{
				MonsterModifierTypes.Wet,
				ModifierCategory.Offense
			},
			{
				MonsterModifierTypes.Knockback,
				ModifierCategory.Offense
			},
			{
				MonsterModifierTypes.RemoveStatusEffect,
				ModifierCategory.Offense
			},
			{
				MonsterModifierTypes.PersonalShield,
				ModifierCategory.Defense
			},
			{
				MonsterModifierTypes.ShieldDome,
				ModifierCategory.Defense
			},
			{
				MonsterModifierTypes.ElementalImmunity,
				ModifierCategory.Defense
			},
			{
				MonsterModifierTypes.PierceImmunity,
				ModifierCategory.Defense
			},
			{
				MonsterModifierTypes.BluntImmunity,
				ModifierCategory.Defense
			},
			{
				MonsterModifierTypes.SlashImmunity,
				ModifierCategory.Defense
			},
			{
				MonsterModifierTypes.StaggerImmune,
				ModifierCategory.Defense
			},
			{
				MonsterModifierTypes.Absorption,
				ModifierCategory.Defense
			},
			{
				MonsterModifierTypes.FastMovement,
				ModifierCategory.Utility
			},
			{
				MonsterModifierTypes.DistantDetection,
				ModifierCategory.Utility
			},
			{
				MonsterModifierTypes.SoulEater,
				ModifierCategory.Utility
			},
			{
				MonsterModifierTypes.HealDeath,
				ModifierCategory.Utility
			},
			{
				MonsterModifierTypes.Quiet,
				ModifierCategory.Utility
			},
			{
				MonsterModifierTypes.ResistanceNotification,
				ModifierCategory.Utility
			},
			{
				MonsterModifierTypes.ArmorCharge,
				ModifierCategory.Utility
			},
			{
				MonsterModifierTypes.FireTrail,
				ModifierCategory.Utility
			},
			{
				MonsterModifierTypes.SplitSpawn,
				ModifierCategory.SplitSpawn
			},
			{
				MonsterModifierTypes.EliteMonster,
				ModifierCategory.Elite
			}
		};

		public static readonly HashSet<MonsterModifierTypes> BossExcludedModifiers = new HashSet<MonsterModifierTypes>
		{
			MonsterModifierTypes.PoisonDeath,
			MonsterModifierTypes.FireDeath,
			MonsterModifierTypes.FrostDeath,
			MonsterModifierTypes.StaggerDeath,
			MonsterModifierTypes.HealDeath,
			MonsterModifierTypes.TarDeath,
			MonsterModifierTypes.SplitSpawn,
			MonsterModifierTypes.EliteMonster,
			MonsterModifierTypes.Vampiric,
			MonsterModifierTypes.Absorption,
			MonsterModifierTypes.SoulEater
		};

		public static Color GetModifierColor(MonsterModifierTypes modifier)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			List<float> color = modifiers[modifier].color;
			Color result = default(Color);
			((Color)(ref result))..ctor(color[0], color[1], color[2], color[3]);
			return result;
		}

		public static Sprite GetModifierIcon(MonsterModifierTypes modifier)
		{
			if (modifier == MonsterModifierTypes.FireInfused || modifier == MonsterModifierTypes.FrostInfused || modifier == MonsterModifierTypes.PoisonInfused || modifier == MonsterModifierTypes.LightningInfused || modifier == MonsterModifierTypes.RemoveStatusEffect)
			{
				return ModifierAssetUtils.swordIcon;
			}
			if (modifier == MonsterModifierTypes.ShieldBreaker || modifier == MonsterModifierTypes.IgnoreArmor)
			{
				return ModifierAssetUtils.shieldBrokenIcon;
			}
			if (modifier == MonsterModifierTypes.StaminaSiphon || modifier == MonsterModifierTypes.EitrSiphon)
			{
				return ModifierAssetUtils.potionIcon;
			}
			switch (modifier)
			{
			case MonsterModifierTypes.FoodDrain:
				return ModifierAssetUtils.appleIcon;
			default:
				if (modifier != MonsterModifierTypes.TarDeath)
				{
					if (modifier == MonsterModifierTypes.ElementalImmunity || modifier == MonsterModifierTypes.StaggerImmune)
					{
						return ModifierAssetUtils.shieldIcon;
					}
					if (modifier == MonsterModifierTypes.PersonalShield || modifier == MonsterModifierTypes.ShieldDome)
					{
						return ModifierAssetUtils.circleIcon;
					}
					switch (modifier)
					{
					case MonsterModifierTypes.SoulEater:
						return ModifierAssetUtils.soulIcon;
					case MonsterModifierTypes.PierceImmunity:
						return ModifierAssetUtils.shieldSpearIcon;
					case MonsterModifierTypes.SlashImmunity:
						return ModifierAssetUtils.shieldSwordIcon;
					case MonsterModifierTypes.BluntImmunity:
						return ModifierAssetUtils.shieldMaceIcon;
					default:
						if (modifier != MonsterModifierTypes.Forceful)
						{
							if (modifier == MonsterModifierTypes.BloodLoss || modifier == MonsterModifierTypes.Wet)
							{
								return ModifierAssetUtils.bloodIcon;
							}
							if (modifier == MonsterModifierTypes.Absorption || modifier == MonsterModifierTypes.Vampiric)
							{
								return ModifierAssetUtils.heartIcon;
							}
							switch (modifier)
							{
							case MonsterModifierTypes.Quiet:
								return ModifierAssetUtils.earIcon;
							default:
								if (modifier != MonsterModifierTypes.FireTrail)
								{
									switch (modifier)
									{
									case MonsterModifierTypes.ResistanceNotification:
										return ModifierAssetUtils.potionIcon;
									case MonsterModifierTypes.SplitSpawn:
										return ModifierAssetUtils.skullIcon;
									case MonsterModifierTypes.EliteMonster:
										return ModifierAssetUtils.skullIcon;
									default:
										Debug.Log((object)"Could not find icon for modifier");
										return ModifierAssetUtils.plusSquareIcon;
									}
								}
								goto case MonsterModifierTypes.Knockback;
							case MonsterModifierTypes.Knockback:
							case MonsterModifierTypes.ArmorCharge:
								return ModifierAssetUtils.plusSquareIcon;
							}
						}
						goto case MonsterModifierTypes.FastMovement;
					case MonsterModifierTypes.FastMovement:
					case MonsterModifierTypes.FastAttackSpeed:
					case MonsterModifierTypes.DistantDetection:
						return ModifierAssetUtils.plusSquareIcon;
					}
				}
				goto case MonsterModifierTypes.PoisonDeath;
			case MonsterModifierTypes.PoisonDeath:
			case MonsterModifierTypes.FrostDeath:
			case MonsterModifierTypes.FireDeath:
			case MonsterModifierTypes.HealDeath:
			case MonsterModifierTypes.StaggerDeath:
				return ModifierAssetUtils.skullIcon;
			}
		}

		public static float BossOffenseMult(Character attacker)
		{
			return ((Object)(object)attacker != (Object)null && attacker.IsBoss()) ? ((float)MonsterModifiersPlugin.Cfg_Boss_OffenseMultiplier.Value / 100f) : 1f;
		}

		public static float BossHealMult(Character monster)
		{
			return ((Object)(object)monster != (Object)null && monster.IsBoss()) ? ((float)MonsterModifiersPlugin.Cfg_Boss_HealMultiplier.Value / 100f) : 1f;
		}

		public static float ScaleReductionEffect(float configMult, float bossOffenseMult)
		{
			return 1f - (1f - configMult) * bossOffenseMult;
		}

		public static int GetModifierWeight(MonsterModifierTypes modifier)
		{
			return modifiers[modifier].weight;
		}

		public static int GetAvailableModifierCount(HashSet<MonsterModifierTypes>? excluded = null)
		{
			int num = 0;
			foreach (KeyValuePair<MonsterModifierTypes, ModifierData> modifier in modifiers)
			{
				if (modifier.Value.weight > 0 && (excluded == null || !excluded.Contains(modifier.Key)))
				{
					num++;
				}
			}
			return num;
		}

		public static List<MonsterModifierTypes> RollRandomModifiers(int numModifiers, HashSet<MonsterModifierTypes>? excluded = null, int splitGeneration = 0)
		{
			List<MonsterModifierTypes> list = new List<MonsterModifierTypes>();
			Dictionary<MonsterModifierTypes, ModifierData> dictionary = new Dictionary<MonsterModifierTypes, ModifierData>(modifiers);
			if (excluded != null)
			{
				foreach (MonsterModifierTypes item in excluded)
				{
					dictionary.Remove(item);
				}
			}
			for (int i = 0; i < numModifiers; i++)
			{
				if (dictionary.Count == 0)
				{
					break;
				}
				Dictionary<ModifierCategory, List<MonsterModifierTypes>> dictionary2 = new Dictionary<ModifierCategory, List<MonsterModifierTypes>>();
				foreach (KeyValuePair<MonsterModifierTypes, ModifierData> item2 in dictionary)
				{
					if (item2.Value.weight > 0)
					{
						ModifierCategory value;
						ModifierCategory key = (ModifierCategories.TryGetValue(item2.Key, out value) ? value : ModifierCategory.Utility);
						if (!dictionary2.ContainsKey(key))
						{
							dictionary2[key] = new List<MonsterModifierTypes>();
						}
						dictionary2[key].Add(item2.Key);
					}
				}
				int num = (dictionary2.ContainsKey(ModifierCategory.Offense) ? MonsterModifiersPlugin.Cfg_Offense_Probability.Value : 0);
				int num2 = (dictionary2.ContainsKey(ModifierCategory.Defense) ? MonsterModifiersPlugin.Cfg_Defense_Probability.Value : 0);
				int num3 = (dictionary2.ContainsKey(ModifierCategory.Utility) ? MonsterModifiersPlugin.Cfg_Utility_Probability.Value : 0);
				float num4 = (float)Math.Pow(0.5, splitGeneration);
				int num5 = (dictionary2.ContainsKey(ModifierCategory.SplitSpawn) ? Mathf.RoundToInt((float)MonsterModifiersPlugin.Cfg_SplitSpawn_Probability.Value * num4) : 0);
				int num6 = 0;
				if (MonsterModifiersPlugin.Cfg_EliteMonster_Enabled.Value == MonsterModifiersPlugin.Toggle.On && dictionary2.ContainsKey(ModifierCategory.Elite))
				{
					num6 = MonsterModifiersPlugin.Cfg_EliteMonster_Probability.Value;
				}
				else if (MonsterModifiersPlugin.Cfg_EliteMonster_Enabled.Value == MonsterModifiersPlugin.Toggle.Off)
				{
					if (dictionary2.ContainsKey(ModifierCategory.Offense))
					{
						num += 5;
					}
					if (dictionary2.ContainsKey(ModifierCategory.Defense))
					{
						num2 += 5;
					}
				}
				int num7 = num + num2 + num3 + num5 + num6;
				MonsterModifierTypes monsterModifierTypes;
				if (num7 <= 0)
				{
					int num8 = 0;
					foreach (ModifierData value2 in dictionary.Values)
					{
						num8 += value2.weight;
					}
					if (num8 <= 0)
					{
						break;
					}
					int num9 = Random.Range(0, num8);
					int num10 = 0;
					monsterModifierTypes = MonsterModifierTypes.StaminaSiphon;
					foreach (KeyValuePair<MonsterModifierTypes, ModifierData> item3 in dictionary)
					{
						num10 += item3.Value.weight;
						if (num9 < num10)
						{
							monsterModifierTypes = item3.Key;
							break;
						}
					}
				}
				else
				{
					int num11 = Random.Range(0, num7);
					ModifierCategory key2 = ((num11 >= num) ? ((num11 < num + num2) ? ModifierCategory.Defense : ((num11 < num + num2 + num3) ? ModifierCategory.Utility : ((num11 >= num + num2 + num3 + num5) ? ModifierCategory.Elite : ModifierCategory.SplitSpawn))) : ModifierCategory.Offense);
					List<MonsterModifierTypes> list2 = dictionary2[key2];
					monsterModifierTypes = list2[Random.Range(0, list2.Count)];
				}
				list.Add(monsterModifierTypes);
				dictionary.Remove(monsterModifierTypes);
				if (monsterModifierTypes == MonsterModifierTypes.EliteMonster)
				{
					dictionary.Remove(MonsterModifierTypes.SplitSpawn);
					dictionary.Remove(MonsterModifierTypes.HealDeath);
					dictionary.Remove(MonsterModifierTypes.Vampiric);
					dictionary.Remove(MonsterModifierTypes.Absorption);
				}
			}
			return list;
		}

		public static void RunBiomeChecks()
		{
		}

		public static bool RunRPCDamageChecks(Character character, HitData hit)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			if (hit == null || (Object)(object)character == (Object)null)
			{
				return false;
			}
			if (((DamageTypes)(ref hit.m_damage)).GetTotalDamage() == 0f)
			{
				return false;
			}
			if ((int)hit.m_hitType != 1)
			{
				return false;
			}
			return true;
		}

		public static bool RunRPCDamageChecks(Character character, HitData hit, bool isMonsterAttackingPlayer)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Invalid comparison between Unknown and I4
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between Unknown and I4
			if (hit == null || (Object)(object)character == (Object)null)
			{
				Debug.Log((object)"Hit or character is null");
				return true;
			}
			if (((DamageTypes)(ref hit.m_damage)).GetTotalDamage() == 0f)
			{
				Debug.Log((object)"Total damage is 0");
				return true;
			}
			if (isMonsterAttackingPlayer)
			{
				if ((int)hit.m_hitType != 1)
				{
					Debug.Log((object)"hit type is not enemy hit");
					return true;
				}
			}
			else if ((int)hit.m_hitType != 2)
			{
				Debug.Log((object)"hit type is not player hit");
				return true;
			}
			return true;
		}

		public static bool RunHitChecks(HitData hit, bool isMonsterAttackingPlayer)
		{
			Character attacker = hit.GetAttacker();
			if ((Object)(object)attacker == (Object)null)
			{
				return false;
			}
			if (isMonsterAttackingPlayer && attacker.IsPlayer())
			{
				return false;
			}
			if (!isMonsterAttackingPlayer && attacker.IsPlayer())
			{
				return true;
			}
			return true;
		}
	}
	public class PrefabUtils
	{
		public static GameObject leechDeathVFX;

		public static GameObject leechDeathSFX;

		public static void CreateCustomPrefabs()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Expected O, but got Unknown
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Expected O, but got Unknown
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Expected O, but got Unknown
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Expected O, but got Unknown
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Expected O, but got Unknown
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Expected O, but got Unknown
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Expected O, but got Unknown
			GameObject prefab = PrefabManager.Instance.GetPrefab("shaman_heal_aoe");
			GameObject val = PrefabManager.Instance.CreateClonedPrefab("healCustomPrefab", prefab);
			CustomPrefab val2 = new CustomPrefab(val, false);
			Aoe component = val2.Prefab.GetComponent<Aoe>();
			component.m_statusEffect = "";
			GameObject prefab2 = PrefabManager.Instance.GetPrefab("Mistile");
			GameObject val3 = PrefabManager.Instance.CreateClonedPrefab("mistleCustomPrefab", prefab2);
			CustomPrefab val4 = new CustomPrefab(val3, false);
			Character component2 = (Character)(object)val4.Prefab.GetComponent<Humanoid>();
			component2.m_speed = 0f;
			component2.m_flyFastSpeed = 0f;
			component2.m_flySlowSpeed = 0f;
			component2.m_name = "$modifier_mistile";
			val4.Prefab.GetComponent<CharacterTimedDestruction>().m_timeoutMin = 2f;
			val4.Prefab.GetComponent<CharacterTimedDestruction>().m_timeoutMax = 4f;
			GameObject prefab3 = PrefabManager.Instance.GetPrefab("fx_DvergerMage_Mistile_attack");
			GameObject val5 = PrefabManager.Instance.CreateClonedPrefab("staggerDeathNovaCustomPrefab", prefab3);
			CustomPrefab val6 = new CustomPrefab(val5, false);
			GameObject gameObject = ((Component)ExposedGameObjectExtension.FindDeepChild(val6.Prefab, "shockwave (1)", (IterativeSearchType)1)).gameObject;
			ParticleSystem component3 = gameObject.GetComponent<ParticleSystem>();
			MainModule main = component3.main;
			((MainModule)(ref main)).startRotationX = new MinMaxCurve((float)Math.PI / 2f);
			((MainModule)(ref main)).startRotationY = new MinMaxCurve(0f);
			((MainModule)(ref main)).startRotationZ = new MinMaxCurve(0f);
			GameObject prefab4 = PrefabManager.Instance.GetPrefab("skeleton_bow");
			GameObject val7 = PrefabManager.Instance.CreateClonedPrefab("skeletonBowCustomPrefab_Fire", prefab4);
			CustomItem val8 = new CustomItem(val7, false);
			ItemData itemData = val8.ItemPrefab.GetComponent<ItemDrop>().m_itemData;
			itemData.m_shared.m_attack.m_attackProjectile = PrefabManager.Instance.GetPrefab("bow_projectile_fire");
			GameObject val9 = PrefabManager.Instance.CreateClonedPrefab("skeletonBowCustomPrefab_Frost", prefab4);
			CustomItem val10 = new CustomItem(val9, false);
			ItemData itemData2 = val10.ItemPrefab.GetComponent<ItemDrop>().m_itemData;
			itemData2.m_shared.m_attack.m_attackProjectile = PrefabManager.Instance.GetPrefab("bow_projectile_frost");
			GameObject val11 = PrefabManager.Instance.CreateClonedPrefab("skeletonBowCustomPrefab_Poison", prefab4);
			CustomItem val12 = new CustomItem(val11, false);
			ItemData itemData3 = val12.ItemPrefab.GetComponent<ItemDrop>().m_itemData;
			itemData3.m_shared.m_attack.m_attackProjectile = PrefabManager.Instance.GetPrefab("bow_projectile_poison");
			GameObject prefab5 = PrefabManager.Instance.GetPrefab("draugr_bow");
			GameObject val13 = PrefabManager.Instance.CreateClonedPrefab("draugrBowCustomPrefab_Fire", prefab5);
			CustomItem val14 = new CustomItem(val13, false);
			ItemData itemData4 = val14.ItemPrefab.GetComponent<ItemDrop>().m_itemData;
			itemData4.m_shared.m_attack.m_attackProjectile = PrefabManager.Instance.GetPrefab("bow_projectile_fire");
			GameObject val15 = PrefabManager.Instance.CreateClonedPrefab("draugrBowCustomPrefab_Frost", prefab5);
			CustomItem val16 = new CustomItem(val15, false);
			ItemData itemData5 = val16.ItemPrefab.GetComponent<ItemDrop>().m_itemData;
			itemData5.m_shared.m_attack.m_attackProjectile = PrefabManager.Instance.GetPrefab("bow_projectile_frost");
			GameObject val17 = PrefabManager.Instance.CreateClonedPrefab("draugrBowCustomPrefab_Poison", prefab5);
			CustomItem val18 = new CustomItem(val17, false);
			ItemData itemData6 = val18.ItemPrefab.GetComponent<ItemDrop>().m_itemData;
			itemData6.m_shared.m_attack.m_attackProjectile = PrefabManager.Instance.GetPrefab("bow_projectile_poison");
			PrefabManager.Instance.AddPrefab(val2);
			PrefabManager.Instance.AddPrefab(val4);
			PrefabManager.Instance.AddPrefab(val6);
			ItemManager.Instance.AddItem(val8);
			ItemManager.Instance.AddItem(val10);
			ItemManager.Instance.AddItem(val12);
			ItemManager.Instance.AddItem(val14);
			ItemManager.Instance.AddItem(val16);
			ItemManager.Instance.AddItem(val18);
			leechDeathVFX = PrefabManager.Instance.GetPrefab("vfx_leech_death");
			leechDeathSFX = PrefabManager.Instance.GetPrefab("sfx_leech_death");
			PrefabManager.OnVanillaPrefabsAvailable -= CreateCustomPrefabs;
		}
	}
	public static class SpawnCommands
	{
		[HarmonyPatch(typeof(Terminal), "InitTerminal")]
		private static class Patch_Terminal_InitTerminal
		{
			[Serializable]
			[CompilerGenerated]
			private sealed class <>c
			{
				public static readonly <>c <>9 = new <>c();

				public static ConsoleEvent <>9__1_0;

				internal void <Postfix>b__1_0(ConsoleEventArgs args)
				{
					if (args.Length > 2)
					{
						string creatureName = args[1];
						string modifierName = args[2];
						SpawnModifier(creatureName, modifierName);
					}
					else
					{
						args.Context.AddString("Usage: modifier [creature] [modifier]");
					}
				}
			}

			[HarmonyPriority(800)]
			private static void Prefix(out bool __state)
			{
				__state = Terminal.m_terminalInitialized;
			}

			private static void Postfix(bool __state)
			{
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Expected O, but got Unknown
				if (__state)
				{
					return;
				}
				MonsterModifiersPlugin.MonsterModifiersLogger.LogInfo((object)"Adding Terminal Commands for monster modifier spawning.");
				object obj = <>c.<>9__1_0;
				if (obj == null)
				{
					ConsoleEvent val = delegate(ConsoleEventArgs args)
					{
						if (args.Length > 2)
						{
							string creatureName = args[1];
							string modifierName = args[2];
							SpawnModifier(creatureName, modifierName);
						}
						else
						{
							args.Context.AddString("Usage: modifier [creature] [modifier]");
						}
					};
					<>c.<>9__1_0 = val;
					obj = (object)val;
				}
				new ConsoleCommand("modifier", "[creature] [modifier]", (ConsoleEvent)obj, true, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			}
		}

		public static void SpawnModifier(string creatureName, string modifierName)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			GameObject prefab = ZNetScene.instance.GetPrefab(creatureName);
			MonsterModifierTypes result;
			if ((Object)(object)prefab == (Object)null)
			{
				((Character)Player.m_localPlayer).Message((MessageType)1, "Missing object " + creatureName, 0, (Sprite)null);
			}
			else if (Enum.TryParse<MonsterModifierTypes>(modifierName, ignoreCase: true, out result))
			{
				Vector3 insideUnitSphere = Random.insideUnitSphere;
				GameObject val = Object.Instantiate<GameObject>(prefab, ((Component)Player.m_localPlayer).transform.position + ((Component)Player.m_localPlayer).transform.forward * 2f + Vector3.up + insideUnitSphere, Quaternion.identity);
				Character component = val.GetComponent<Character>();
				if (component.m_nview.GetZDO().IsOwner())
				{
					component.SetLevel(2);
					component.m_nview.GetZDO().Set("modifiers", modifierName);
				}
			}
			else
			{
				((Character)Player.m_localPlayer).Message((MessageType)1, "Invalid modifier name: " + modifierName, 0, (Sprite)null);
			}
		}
	}
	public class StatusEffectUtils
	{
		public static void CreateCustomStatusEffects()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			BloodLoss_SE bloodLoss_SE = ScriptableObject.CreateInstance<BloodLoss_SE>();
			((Object)bloodLoss_SE).name = "BloodLossStatusEffect";
			((StatusEffect)bloodLoss_SE).m_name = "$se_bloodLoss";
			((StatusEffect)bloodLoss_SE).m_icon = ModifierAssetUtils.bloodIconRed;
			CustomStatusEffect val = new CustomStatusEffect((StatusEffect)(object)bloodLoss_SE, false);
			HealDeath_SE healDeath_SE = ScriptableObject.CreateInstance<HealDeath_SE>();
			((Object)healDeath_SE).name = "HealDeathStatusEffect";
			((StatusEffect)healDeath_SE).m_name = "$se_healDeath";
			((StatusEffect)healDeath_SE).m_ttl = 5f;
			((SE_Stats)healDeath_SE).m_tickInterval = 1f;
			((SE_Stats)healDeath_SE).m_healthOverTimeDuration = 5f;
			((SE_Stats)healDeath_SE).m_healthOverTimeInterval = 0.5f;
			((SE_Stats)healDeath_SE).m_healthOverTimeTicks = 10f;
			((SE_Stats)healDeath_SE).m_healthOverTime = 0f;
			CustomStatusEffect val2 = new CustomStatusEffect((StatusEffect)(object)healDeath_SE, false);
			ItemManager.Instance.AddStatusEffect(val);
			ItemManager.Instance.AddStatusEffect(val2);
		}
	}
	public class TranslationUtils
	{
		public static CustomLocalization Localization;

		public static void AddLocalizations()
		{
			Localization = LocalizationManager.Instance.GetLocalization();
			CustomLocalization localization = Localization;
			string text = "English";
			localization.AddTranslation(ref text, new Dictionary<string, string>
			{
				{ "$se_bloodLoss", "Blood Loss" },
				{ "$modifier_mistile", "Stagger Bomb" }
			});
		}
	}
	public class ShaderLogFilter : ILogListener, IDisposable
	{
		private readonly ILogListener _inner;

		private ShaderLogFilter(ILogListener inner)
		{
			_inner = inner;
		}

		public static void Install()
		{
			ICollection<ILogListener> listeners = Logger.Listeners;
			foreach (ILogListener item in listeners)
			{
				if (item is ShaderLogFilter)
				{
					return;
				}
			}
			List<ILogListener> list = new List<ILogListener>(listeners);
			listeners.Clear();
			foreach (ILogListener item2 in list)
			{
				listeners.Add((ILogListener)(object)new ShaderLogFilter(item2));
			}
		}

		public void LogEvent(object sender, LogEventArgs eventArgs)
		{
			if (eventArgs == null || !(eventArgs.Data?.ToString()?.Contains("Failed to find expected binary shader data")).GetValueOrDefault())
			{
				ILogListener inner = _inner;
				if (inner != null)
				{
					inner.LogEvent(sender, eventArgs);
				}
			}
		}

		public void Dispose()
		{
			((IDisposable)_inner)?.Dispose();
		}
	}
	public class WorldUtils
	{
		private static readonly Collider[] s_buffer = (Collider[])(object)new Collider[512];

		public static List<Character> GetAllCharacter(Vector3 position, float range)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.OverlapBoxNonAlloc(position, Vector3.one * range, s_buffer, Quaternion.identity);
			List<Character> list = new List<Character>();
			for (int i = 0; i < num; i++)
			{
				Character component = ((Component)((Component)s_buffer[i]).transform.root).GetComponent<Character>();
				if ((Object)(object)component != (Object)null && !list.Contains(component))
				{
					list.Add(component);
				}
			}
			return list;
		}
	}
	public class YamlUtils
	{
		public static string defaultModifierValues;

		public static void ParseDefaultYamls()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			defaultModifierValues = AssetUtils.LoadTextFromResources("modifierValues.yml");
			IDeserializer val = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).Build();
			ModifierUtils.modifiers = val.Deserialize<Dictionary<MonsterModifierTypes, ModifierData>>((TextReader)new StringReader(defaultModifierValues));
			MonsterModifiersPlugin.MonsterModifiersLogger.LogInfo((object)($"[YamlUtils] Loaded {ModifierUtils.modifiers.Count} modifier entries. " + $"EliteMonster present: {ModifierUtils.modifiers.ContainsKey(MonsterModifierTypes.EliteMonster)}"));
		}
	}
	[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
	public static class RegisterAndCheckVersion
	{
		private static void Prefix(ZNetPeer peer, ref ZNet __instance)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			MonsterModifiersPlugin.MonsterModifiersLogger.LogDebug((object)"Registering version RPC handler");
			peer.m_rpc.Register<ZPackage>("MonsterModifiers_VersionCheck", (Action<ZRpc, ZPackage>)RpcHandlers.RPC_MonsterModifiers_Version);
			MonsterModifiersPlugin.MonsterModifiersLogger.LogDebug((object)"Invoking version check");
			ZPackage val = new ZPackage();
			val.Write("1.3.3");
			peer.m_rpc.Invoke("MonsterModifiers_VersionCheck", new object[1] { val });
		}
	}
	[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
	public static class VerifyClient
	{
		private static bool Prefix(ZRpc rpc, ZPackage pkg, ref ZNet __instance)
		{
			if (!__instance.IsServer() || RpcHandlers.ValidatedPeers.Contains(rpc))
			{
				return true;
			}
			MonsterModifiersPlugin.MonsterModifiersLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") never sent version or couldn't due to previous disconnect, disconnecting"));
			rpc.Invoke("Error", new object[1] { 3 });
			return false;
		}

		private static void Postfix(ZNet __instance)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "MonsterModifiersRequestAdminSync", new object[1] { (object)new ZPackage() });
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "ShowConnectError")]
	public class ShowConnectionError
	{
		private static void Postfix(FejdStartup __instance)
		{
			if (__instance.m_connectionFailedPanel.activeSelf)
			{
				__instance.m_connectionFailedError.fontSizeMax = 25f;
				__instance.m_connectionFailedError.fontSizeMin = 15f;
				TMP_Text connectionFailedError = __instance.m_connectionFailedError;
				connectionFailedError.text = connectionFailedError.text + "\n" + MonsterModifiersPlugin.ConnectionError;
			}
		}
	}
	[HarmonyPatch(typeof(ZNet), "Disconnect")]
	public static class RemoveDisconnectedPeerFromVerified
	{
		private static void Prefix(ZNetPeer peer, ref ZNet __instance)
		{
			if (__instance.IsServer())
			{
				MonsterModifiersPlugin.MonsterModifiersLogger.LogInfo((object)("Peer (" + peer.m_rpc.m_socket.GetHostName() + ") disconnected, removing from validated list"));
				RpcHandlers.ValidatedPeers.Remove(peer.m_rpc);
			}
		}
	}
	public static class RpcHandlers
	{
		public static readonly List<ZRpc> ValidatedPeers = new List<ZRpc>();

		public static void RPC_MonsterModifiers_Version(ZRpc rpc, ZPackage pkg)
		{
			string text = pkg.ReadString();
			MonsterModifiersPlugin.MonsterModifiersLogger.LogInfo((object)("Version check, local: 1.3.3,  remote: " + text));
			if (text != "1.3.3")
			{
				MonsterModifiersPlugin.ConnectionError = "MonsterModifiers Installed: 1.3.3\n Needed: " + text;
				if (ZNet.instance.IsServer())
				{
					MonsterModifiersPlugin.MonsterModifiersLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") has incompatible version, disconnecting..."));
					rpc.Invoke("Error", new object[1] { 3 });
				}
			}
			else if (!ZNet.instance.IsServer())
			{
				MonsterModifiersPlugin.MonsterModifiersLogger.LogInfo((object)"Received same version from server!");
			}
			else
			{
				MonsterModifiersPlugin.MonsterModifiersLogger.LogInfo((object)("Adding peer (" + rpc.m_socket.GetHostName() + ") to validated list"));
				ValidatedPeers.Add(rpc);
			}
		}
	}
}
namespace MonsterModifiers.Visuals
{
	public class BowVisuals
	{
		public static GameObject? GetModifierVisual(string itemName, List<MonsterModifierTypes> modifiers)
		{
			if (!(itemName == "skeleton_bow"))
			{
				if (itemName == "draugr_bow")
				{
					return GetDraugrBowVisual(modifiers);
				}
				return null;
			}
			return GetSkeletonBowVisual(modifiers);
		}

		public static GameObject? GetSkeletonBowVisual(List<MonsterModifierTypes> modifiers)
		{
			if (modifiers.Contains(MonsterModifierTypes.FireInfused))
			{
				return PrefabManager.Instance.GetPrefab("skeletonBowCustomPrefab_Fire");
			}
			if (modifiers.Contains(MonsterModifierTypes.FrostInfused))
			{
				return PrefabManager.Instance.GetPrefab("skeletonBowCustomPrefab_Frost");
			}
			if (modifiers.Contains(MonsterModifierTypes.PoisonInfused))
			{
				return PrefabManager.Instance.GetPrefab("skeletonBowCustomPrefab_Poison");
			}
			return null;
		}

		public static GameObject? GetDraugrBowVisual(List<MonsterModifierTypes> modifiers)
		{
			if (modifiers.Contains(MonsterModifierTypes.FireInfused))
			{
				return PrefabManager.Instance.GetPrefab("draugrBowCustomPrefab_Fire");
			}
			if (modifiers.Contains(MonsterModifierTypes.FrostInfused))
			{
				return PrefabManager.Instance.GetPrefab("draugrBowCustomPrefab_Frost");
			}
			if (modifiers.Contains(MonsterModifierTypes.PoisonInfused))
			{
				return PrefabManager.Instance.GetPrefab("draugrBowCustomPrefab_Poison");
			}
			return null;
		}
	}
}
namespace MonsterModifiers.StatusEffects
{
	public class BloodLoss_SE : StatusEffect
	{
		public int bloodLossAmount = 0;

		public int bloodLossCap;

		private float reductionTimer = 0f;

		private bool shouldRemove = false;

		public override void Setup(Character character)
		{
			((StatusEffect)this).Setup(character);
			bloodLossCap = Mathf.FloorToInt(character.GetMaxHealth());
		}

		public override void UpdateStatusEffect(float dt)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			reductionTimer += dt;
			if (reductionTimer >= 60f)
			{
				bloodLossAmount = Mathf.Max(0, bloodLossAmount - 10);
				shouldRemove = true;
				reductionTimer = 0f;
			}
			if (bloodLossAmount > bloodLossCap)
			{
				bloodLossAmount = 0;
				HitData val = new HitData
				{
					m_damage = 
					{
						m_slash = base.m_character.GetMaxHealth() * 0.3f
					}
				};
				base.m_character.Damage(val);
				Object.Instantiate<GameObject>(PrefabUtils.leechDeathSFX, ((Component)base.m_character).transform.position, ((Component)base.m_character).transform.rotation);
				Object.Instantiate<GameObject>(PrefabUtils.leechDeathVFX, ((Component)base.m_character).transform.position, ((Component)base.m_character).transform.rotation);
				shouldRemove = true;
			}
		}

		public override string GetIconText()
		{
			return bloodLossAmount.ToString();
		}

		public override void OnDamaged(HitData hit, Character attacker)
		{
			if (ModifierUtils.RunRPCDamageChecks(attacker, hit) && ModifierUtils.RunHitChecks(hit, isMonsterAttackingPlayer: true))
			{
				MonsterModifier component = ((Component)attacker).GetComponent<MonsterModifier>();
				if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.BloodLoss))
				{
					bloodLossAmount += Mathf.FloorToInt(hit.GetTotalDamage());
				}
			}
		}

		public override bool IsDone()
		{
			return shouldRemove || ((StatusEffect)this).IsDone();
		}
	}
	public class HealDeath_SE : SE_Stats
	{
		public override void SetLevel(int itemLevel, float skillLevel)
		{
			base.m_healthPerTick = skillLevel / 10f;
		}
	}
}
namespace MonsterModifiers.Patches
{
	[HarmonyPatch(typeof(EnemyHud), "ShowHud")]
	public static class EnemyHud_ShowHud_Patch
	{
		private static void Postfix(EnemyHud __instance, Character c, bool isMount)
		{
			if (!(c.IsPlayer() || isMount))
			{
				MonsterModifier component = ((Component)c).GetComponent<MonsterModifier>();
				if (!((Object)(object)component == (Object)null))
				{
					ChangeEnemyStars(c, component.Modifiers, component.IsBossCharacter, component.OverflowStars);
				}
			}
		}

		public static void ChangeEnemyStars(Character character, List<MonsterModifierTypes> modifiers, bool isBoss = false, int overflowStars = 0)
		{
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			if ((character.GetLevel() <= 1 && !isBoss) || !EnemyHud.instance.m_huds.TryGetValue(character, out var value))
			{
				return;
			}
			GameObject gui = value.m_gui;
			int num = 0;
			int num2 = 7;
			if (CompatibilityUtils.isStarLevelsExpandedInstalled && character.GetLevel() > num2)
			{
				num = 2;
			}
			int num3 = (isBoss ? MonsterModifiersPlugin.Configurations_Boss_Modifiers.Value : 0);
			int num4 = modifiers.Count - num3;
			for (int i = num; i < gui.transform.childCount; i++)
			{
				Transform child = gui.transform.GetChild(i);
				if (!((Object)child).name.StartsWith("level_" + (modifiers.Count - num3 + overflowStars + 1)) && (!((Object)child).name.StartsWith("level_n") || !((Component)child).gameObject.activeSelf))
				{
					continue;
				}
				for (int j = 0; j < ((Component)child).transform.childCount; j++)
				{
					Transform child2 = ((Component)child).transform.GetChild(j);
					if (((Object)child2).name.StartsWith("star") && ((Component)child2).gameObject.activeSelf && j < num4)
					{
						int index = num3 + j;
						((Component)child2).GetComponent<Image>().sprite = ModifierUtils.GetModifierIcon(modifiers[index]);
						((Graphic)((Component)child2).GetComponent<Image>()).color = ModifierUtils.GetModifierColor(modifiers[index]);
						((Component)child2.GetChild(0)).gameObject.SetActive(false);
					}
				}
			}
		}
	}
}
namespace MonsterModifiers.Modifiers
{
	public class Absorption
	{
		[HarmonyPatch(typeof(Character), "RPC_Damage")]
		public class Absorption_Character_RPC_Damage_Patch
		{
			public static void Prefix(Character __instance, HitData hit)
			{
				if (hit == null || (Object)(object)__instance == (Object)null)
				{
					return;
				}
				MonsterModifier component = ((Component)__instance).GetComponent<MonsterModifier>();
				if ((Object)(object)component == (Object)null || !component.Modifiers.Contains(MonsterModifierTypes.Absorption) || ((DamageTypes)(ref hit.m_damage)).GetTotalDamage() == 0f)
				{
					return;
				}
				List<MonsterModifierTypes> modifiers = component.Modifiers;
				float num = ModifierUtils.BossHealMult(__instance);
				if (modifiers.Contains(MonsterModifierTypes.BluntImmunity) && hit.m_damage.m_blunt > 0f)
				{
					float num2 = (float)MonsterModifiersPlugin.Cfg_BluntImmunity_DamageReduction.Value / 100f;
					__instance.Heal(hit.m_damage.m_blunt * num2 * num, true);
				}
				if (modifiers.Contains(MonsterModifierTypes.SlashImmunity) && hit.m_damage.m_slash > 0f)
				{
					float num3 = (float)MonsterModifiersPlugin.Cfg_SlashImmunity_DamageReduction.Value / 100f;
					__instance.Heal(hit.m_damage.m_slash * num3 * num, true);
				}
				if (modifiers.Contains(MonsterModifierTypes.PierceImmunity) && hit.m_damage.m_pierce > 0f)
				{
					float num4 = (float)MonsterModifiersPlugin.Cfg_PierceImmunity_DamageReduction.Value / 100f;
					__instance.Heal(hit.m_damage.m_pierce * num4 * num, true);
				}
				if (modifiers.Contains(MonsterModifierTypes.ElementalImmunity))
				{
					float num5 = (float)MonsterModifiersPlugin.Cfg_ElementalImmunity_DamageReduction.Value / 100f * num;
					if (hit.m_damage.m_fire > 0f)
					{
						__instance.Heal(hit.m_damage.m_fire * num5, true);
					}
					if (hit.m_damage.m_frost > 0f)
					{
						__instance.Heal(hit.m_damage.m_frost * num5, true);
					}
					if (hit.m_damage.m_lightning > 0f)
					{
						__instance.Heal(hit.m_damage.m_lightning * num5, true);
					}
					if (hit.m_damage.m_poison > 0f)
					{
						__instance.Heal(hit.m_damage.m_poison * num5, true);
					}
					if (hit.m_damage.m_spirit > 0f)
					{
						__instance.Heal(hit.m_damage.m_spirit * num5, true);
					}
				}
			}
		}
	}
	public class BloodLoss
	{
		[HarmonyPatch(typeof(Character), "RPC_Damage")]
		public class RemoveMead_Character_RPC_Damage_Patch
		{
			public static void Postfix(Character __instance, HitData hit)
			{
				if (ModifierUtils.RunRPCDamageChecks(__instance, hit) && ModifierUtils.RunHitChecks(hit, isMonsterAttackingPlayer: true))
				{
					Character attacker = hit.GetAttacker();
					MonsterModifier component = ((Component)attacker).GetComponent<MonsterModifier>();
					if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.BloodLoss) && !__instance.IsBlocking() && !__instance.GetSEMan().HaveStatusEffect(StringExtensionMethods.GetStableHashCode("BloodLossStatusEffect")))
					{
						__instance.GetSEMan().AddStatusEffect(StringExtensionMethods.GetStableHashCode("BloodLossStatusEffect"), false, 0, 0f);
					}
				}
			}
		}
	}
	public class DistantDetection
	{
		public static void AddDistantDetection(Character character)
		{
			BaseAI baseAI = character.m_baseAI;
			if ((Object)(object)baseAI != (Object)null)
			{
				baseAI.m_hearRange *= MonsterModifiersPlugin.Cfg_DistantDetection_RangeMultiplier.Value;
				baseAI.m_viewRange *= MonsterModifiersPlugin.Cfg_DistantDetection_RangeMultiplier.Value;
			}
		}

		public static void RemoveDistantDetection(Character character)
		{
			BaseAI baseAI = character.m_baseAI;
			if ((Object)(object)baseAI != (Object)null)
			{
				baseAI.m_hearRange /= MonsterModifiersPlugin.Cfg_DistantDetection_RangeMultiplier.Value;
				baseAI.m_viewRange /= MonsterModifiersPlugin.Cfg_DistantDetection_RangeMultiplier.Value;
			}
		}
	}
	public class EitrSiphon
	{
		[HarmonyPatch(typeof(Character), "RPC_Damage")]
		public class EitrSiphon_Character_RPC_Damage_Patch
		{
			public static void Postfix(Character __instance, HitData hit)
			{
				if (ModifierUtils.RunRPCDamageChecks(__instance, hit) && ModifierUtils.RunHitChecks(hit, isMonsterAttackingPlayer: true) && !__instance.IsBlocking())
				{
					Character attacker = hit.GetAttacker();
					MonsterModifier component = ((Component)attacker).GetComponent<MonsterModifier>();
					if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.EitrSiphon))
					{
						__instance.UseEitr(hit.GetTotalDamage() * ModifierUtils.BossOffenseMult(attacker));
					}
				}
			}
		}
	}
	public class FastAttackSpeed
	{
		[HarmonyPatch(typeof(CharacterAnimEvent), "CustomFixedUpdate")]
		public static class FastAttackSpeed_CharacterAnimEvent_CustomFixedUpdate_Patch
		{
			public static void Prefix(Character ___m_character, ref Animator ___m_animator)
			{
				if (!___m_character.InAttack() || ___m_character.IsPlayer())
				{
					return;
				}
				MonsterModifier component = ((Component)___m_character).GetComponent<MonsterModifier>();
				if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.FastAttackSpeed))
				{
					double num = (double)___m_animator.speed * 10000000.0 % 100.0;
					float value = MonsterModifiersPlugin.Cfg_FastAttackSpeed_AnimatorMultiplier.Value;
					if ((!(num < 30.0) || !(num > 10.0)) && !(___m_animator.speed <= 0.001f))
					{
						___m_animator.speed = ___m_animator.speed * (1f + value) + 1.9E-06f;
					}
				}
			}
		}

		[HarmonyPatch(typeof(Attack), "Start")]
		public static class FastAttackSpeed_Attack_Start_Patch
		{
			private static void Postfix(Humanoid character, ItemData weapon, bool __result)
			{
				if (((Character)character).InAttack() && !((Character)character).IsPlayer())
				{
					MonsterModifier component = ((Component)character).GetComponent<MonsterModifier>();
					if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.FastAttackSpeed) && !((Character)character).IsPlayer() && __result && !((Character)character).IsBoss())
					{
						float value = MonsterModifiersPlugin.Cfg_FastAttackSpeed_IntervalReduction.Value;
						weapon.m_lastAttackTime -= weapon.m_shared.m_aiAttackInterval * Mathf.Max(0f, value);
					}
				}
			}
		}
	}
	public class FastMovement
	{
		public static void AddFastMovement(Character character)
		{
			character.m_speed *= MonsterModifiersPlugin.Cfg_FastMovement_SpeedMultiplier.Value;
			character.m_runSpeed *= MonsterModifiersPlugin.Cfg_FastMovement_SpeedMultiplier.Value;
			character.m_walkSpeed *= MonsterModifiersPlugin.Cfg_FastMovement_SpeedMultiplier.Value;
		}

		public static void RemoveFastMovement(Character character)
		{
			character.m_speed /= MonsterModifiersPlugin.Cfg_FastMovement_SpeedMultiplier.Value;
			character.m_runSpeed /= MonsterModifiersPlugin.Cfg_FastMovement_SpeedMultiplier.Value;
			character.m_walkSpeed /= MonsterModifiersPlugin.Cfg_FastMovement_SpeedMultiplier.Value;
		}
	}
	public class FoodDrain
	{
		[HarmonyPatch(typeof(Character), "RPC_Damage")]
		public class FoodDrain_Character_RPC_Damage_Patch
		{
			public static void Postfix(Character __instance, HitData hit)
			{
				if (!ModifierUtils.RunRPCDamageChecks(__instance, hit) || !ModifierUtils.RunHitChecks(hit, isMonsterAttackingPlayer: true) || __instance.IsBlocking())
				{
					return;
				}
				Character attacker = hit.GetAttacker();
				MonsterModifier component = ((Component)attacker).GetComponent<MonsterModifier>();
				if ((Object)(object)component == (Object)null || !component.Modifiers.Contains(MonsterModifierTypes.FoodDrain))
				{
					return;
				}
				Player val = (Player)(object)((__instance is Player) ? __instance : null);
				if ((Object)(object)val != (Object)null)
				{
					List<Food> foods = val.GetFoods();
					int count = foods.Count;
					if (count > 0)
					{
						int index = Random.Range(0, count);
						float num = ModifierUtils.ScaleReductionEffect(MonsterModifiersPlugin.Cfg_FoodDrain_DurationReduction.Value, ModifierUtils.BossOffenseMult(attacker));
						Food obj = foods[index];
						obj.m_time *= num;
					}
				}
			}
		}
	}
	public class ElementalInfusions
	{
		[HarmonyPatch(typeof(Character), "RPC_Damage")]
		public class ElementalInfusions_Character_RPC_Damage_Patch
		{
			public static void Prefix(Character __instance, HitData hit)
			{
				if (!ModifierUtils.RunRPCDamageChecks(__instance, hit) || !ModifierUtils.RunHitChecks(hit, isMonsterAttackingPlayer: true) || __instance.IsBlocking())
				{
					return;
				}
				Character attacker = hit.GetAttacker();
				MonsterModifier component = ((Component)attacker).GetComponent<MonsterModifier>();
				if (!((Object)(object)component == (Object)null))
				{
					float num = hit.GetTotalDamage() * MonsterModifiersPlugin.Cfg_ElementalInfusion_DamageRatio.Value;
					float num2 = hit.m_damage.m_chop + hit.m_damage.m_pickaxe + hit.m_damage.m_spirit;
					float num3 = (num - num2) * ModifierUtils.BossOffenseMult(attacker);
					if (component.Modifiers.Contains(MonsterModifierTypes.PoisonInfused))
					{
						hit.m_damage.m_poison += num3;
					}
					if (component.Modifiers.Contains(MonsterModifierTypes.FireInfused))
					{
						hit.m_damage.m_fire += num3;
					}
					if (component.Modifiers.Contains(MonsterModifierTypes.LightningInfused))
					{
						hit.m_damage.m_lightning += num3;
					}
					if (component.Modifiers.Contains(MonsterModifierTypes.FrostInfused))
					{
						hit.m_damage.m_frost += num3;
					}
				}
			}
		}
	}
	public class ArmorCharge
	{
		[HarmonyPatch(typeof(Character), "RPC_Damage")]
		public class ArmorCharge_Character_RPC_Damage_Patch
		{
			public static void Prefix(Character __instance, HitData hit)
			{
				if (hit == null || (Object)(object)__instance == (Object)null || !__instance.IsPlayer())
				{
					return;
				}
				Character attacker = hit.GetAttacker();
				if (!((Object)(object)attacker == (Object)null))
				{
					MonsterModifier component = ((Component)attacker).GetComponent<MonsterModifier>();
					if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.ArmorCharge))
					{
						hit.m_damage.m_blunt *= 1.5f;
						hit.m_damage.m_slash *= 1.5f;
						hit.m_damage.m_pierce *= 1.5f;
						hit.m_damage.m_fire *= 1.5f;
						hit.m_damage.m_frost *= 1.5f;
						hit.m_damage.m_lightning *= 1.5f;
						hit.m_damage.m_poison *= 1.5f;
						hit.m_damage.m_spirit *= 1.5f;
					}
				}
			}
		}

		private const float SpeedMultiplier = 1.3f;

		private const float DamageMultiplier = 1.5f;

		public static void Apply(Character character)
		{
			character.m_walkSpeed *= 1.3f;
			character.m_runSpeed *= 1.3f;
			character.m_swimSpeed *= 1.3f;
		}
	}
	public class FireTrail : MonoBehaviour
	{
		private Character _character = null;

		private Vector3 _lastPosition;

		private float _timer;

		private readonly List<GameObject> _activeEffects = new List<GameObject>();

		private const float SpawnInterval = 0.4f;

		private const float MinMoveDistance = 0.5f;

		private const float EffectLifetime = 1.5f;

		public void Init(Character character)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			_character = character;
			_lastPosition = ((Component)character).transform.position;
		}

		private void FixedUpdate()
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_character == (Object)null || _character.IsDead())
			{
				return;
			}
			_timer += Time.fixedDeltaTime;
			if (_timer < 0.4f)
			{
				return;
			}
			_timer = 0f;
			Vector3 position = ((Component)_character).transform.position;
			if (Vector3.Distance(position, _lastPosition) < 0.5f)
			{
				return;
			}
			_lastPosition = position;
			ZNetScene instance = ZNetScene.instance;
			GameObject val = ((instance != null) ? instance.GetPrefab("fx_Hen_Egg_Heat") : null);
			if ((Object)(object)val == (Object)null)
			{
				ZNetScene instance2 = ZNetScene.instance;
				val = ((instance2 != null) ? instance2.GetPrefab("vfx_fire_shortlived") : null);
			}
			if (!((Object)(object)val == (Object)null))
			{
				GameObject val2 = Object.Instantiate<GameObject>(val, position, Quaternion.identity);
				if ((Object)(object)val2 != (Object)null)
				{
					Object.Destroy((Object)(object)val2, 1.5f);
				}
			}
		}
	}
	public class Forceful
	{
		[HarmonyPatch(typeof(Character), "RPC_Damage")]
		public class Forceful_Character_RPC_Damage_Patch
		{
			public static void Prefix(Character __instance, HitData hit)
			{
				if (ModifierUtils.RunRPCDamageChecks(__instance, hit) && ModifierUtils.RunHitChecks(hit, isMonsterAttackingPlayer: true) && !__instance.IsBlocking())
				{
					Character attacker = hit.GetAttacker();
					MonsterModifier component = ((Component)attacker).GetComponent<MonsterModifier>();
					if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.Forceful))
					{
						float value = MonsterModifiersPlugin.Cfg_Forceful_PushMultiplier.Value;
						float num = ModifierUtils.BossOffenseMult(attacker);
						hit.m_pushForce *= 1f + (value - 1f) * num;
					}
				}
			}
		}
	}
	public class ResistanceNotification
	{
		[HarmonyPatch(typeof(Character), "RPC_Damage")]
		public class ResistanceNotification_Character_RPC_Damage_Patch
		{
			public static void Prefix(Character __instance, HitData hit)
			{
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Invalid comparison between Unknown and I4
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
				//IL_010a: Unknown result type (might be due to invalid IL or missing references)
				//IL_010c: 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)
				if (hit == null || (Object)(object)__instance == (Object)null || __instance.IsPlayer() || (int)hit.m_hitType != 2)
				{
					return;
				}
				MonsterModifier component = ((Component)__instance).GetComponent<MonsterModifier>();
				if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.ResistanceNotification) && !((Object)(object)__instance.m_nview == (Object)null))
				{
					ZDOID uid = __instance.m_nview.GetZDO().m_uid;
					if (!HitCounts.ContainsKey(uid))
					{
						HitCounts[uid] = new Dictionary<DamageType, int>();
					}
					CheckAndNotify(__instance, uid, (DamageType)1, hit.m_damage.m_blunt, component, MonsterModifierTypes.BluntImmunity, "$modifier_blunt_resistance");
					CheckAndNotify(__instance, uid, (DamageType)2, hit.m_damage.m_slash, component, MonsterModifierTypes.SlashImmunity, "$modifier_slash_resistance");
					CheckAndNotify(__instance, uid, (DamageType)4, hit.m_damage.m_pierce, component, MonsterModifierTypes.PierceImmunity, "$modifier_pierce_resistance");
					CheckAndNotifyElemental(__instance, uid, hit.m_damage, component);
				}
			}

			private static void CheckAndNotify(Character character, ZDOID id, DamageType type, float damage, MonsterModifier modComp, MonsterModifierTypes immunity, string messageKey)
			{
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: 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_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_0064: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: 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)
				if (damage <= 0f || !modComp.Modifiers.Contains(immunity))
				{
					return;
				}
				Dictionary<DamageType, int> dictionary = HitCounts[id];
				if (!dictionary.ContainsKey(type))
				{
					dictionary[type] = 0;
				}
				if (dictionary[type] < MonsterModifiersPlugin.Cfg_ResistanceNotification_MaxCount.Value)
				{
					dictionary[type]++;
					Player localPlayer = Player.m_localPlayer;
					if (localPlayer != null)
					{
						((Character)localPlayer).Message((MessageType)2, Localization.instance.Localize(messageKey), 0, (Sprite)null);
					}
				}
			}

			private static void CheckAndNotifyElemental(Character character, ZDOID id, DamageTypes dmg, MonsterModifier modComp)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: 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_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_009a: Unknown result type (might be due to invalid IL or missing references)
				//IL_009b: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
				if (!modComp.Modifiers.Contains(MonsterModifierTypes.ElementalImmunity))
				{
					return;
				}
				float num = dmg.m_fire + dmg.m_frost + dmg.m_lightning + dmg.m_poison + dmg.m_spirit;
				if (num <= 0f)
				{
					return;
				}
				Dictionary<DamageType, int> dictionary = HitCounts[id];
				DamageType key = (DamageType)32;
				if (!dictionary.ContainsKey(key))
				{
					dictionary[key] = 0;
				}
				if (dictionary[key] < MonsterModifiersPlugin.Cfg_ResistanceNotification_MaxCount.Value)
				{
					dictionary[key]++;
					Player localPlayer = Player.m_localPlayer;
					if (localPlayer != null)
					{
						((Character)localPlayer).Message((MessageType)2, Localization.instance.Localize("$modifier_elemental_resistance"), 0, (Sprite)null);
					}
				}
			}
		}

		[HarmonyPatch(typeof(Character), "OnDeath")]
		public class ResistanceNotification_Character_OnDeath_Patch
		{
			public static void Prefix(Character __instance)
			{
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.m_nview == (Object)null))
				{
					ZDOID uid = __instance.m_nview.GetZDO().m_uid;
					HitCounts.Remove(uid);
				}
			}
		}

		private static readonly Dictionary<ZDOID, Dictionary<DamageType, int>> HitCounts = new Dictionary<ZDOID, Dictionary<DamageType, int>>();
	}
	public class SplitSpawn
	{
		[HarmonyPatch(typeof(Character), "OnDeath")]
		public static class Character_OnDeath_SplitSpawn_Patch
		{
			public static void Prefix(Character __instance)
			{
				//IL_015c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0161: Unknown result type (might be due to invalid IL or missing references)
				//IL_016c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0176: Unknown result type (might be due to invalid IL or missing references)
				//IL_017b: Unknown result type (might be due to invalid IL or missing references)
				//IL_017d: Unknown result type (might be due to invalid IL or missing references)
				//IL_017f: Unknown result type (might be due to invalid IL or missing references)
				//IL_018b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0192: Unknown result type (might be due to invalid IL or missing references)
				//IL_0197: Unknown result type (might be due to invalid IL or missing references)
				//IL_019c: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d9: 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)
				if ((Object)(object)__instance == (Object)null || __instance.IsPlayer() || (Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsOwner())
				{
					return;
				}
				MonsterModifier component = ((Component)__instance).GetComponent<MonsterModifier>();
				if ((Object)(object)component == (Object)null || !component.Modifiers.Contains(MonsterModifierTypes.SplitSpawn))
				{
					return;
				}
				int level = __instance.GetLevel();
				if (level <= 1)
				{
					return;
				}
				int num = level - 1;
				int level2 = level - 1;
				float value = MonsterModifiersPlugin.Cfg_SplitSpawn_Scale.Value;
				int num2 = ((Component)__instance).GetComponent<MonsterModifier>()?.SplitGeneration ?? 0;
				string text = ((Object)__instance).name.Replace("(Clone)", "").Trim();
				string text2 = text;
				if (MonsterModifiersPlugin.Cfg_SplitSpawn_RandomizeWeapon.Value == MonsterModifiersPlugin.Toggle.On && _bowAliases.TryGetValue(text, out string[] value2) && value2.Length > 1)
				{
					text2 = value2[Random.Range(0, value2.Length)];
				}
				GameObject prefab = ZNetScene.instance.GetPrefab(text2);
				if ((Object)(object)prefab == (Object)null)
				{
					prefab = ZNetScene.instance.GetPrefab(text);
				}
				if ((Object)(object)prefab == (Object)null)
				{
					return;
				}
				Vector3 position = ((Component)__instance).transform.position;
				for (int i = 0; i < num; i++)
				{
					Vector2 val = Random.insideUnitCircle * 2f;
					Vector3 val2 = position + new Vector3(val.x, 0f, val.y);
					float num3 = Random.Range(0f, 360f);
					GameObject val3 = Object.Instantiate<GameObject>(prefab, val2, Quaternion.Euler(0f, num3, 0f));
					val3.transform.localScale = prefab.transform.localScale * value;
					MonsterModifier component2 = val3.GetComponent<MonsterModifier>();
					if ((Object)(object)component2 != (Object)null)
					{
						component2.SplitGeneration = num2 + 1;
						ZNetView component3 = val3.GetComponent<ZNetView>();
						if (((component3 != null) ? component3.GetZDO() : null) != null)
						{
							component3.GetZDO().Set("splitGeneration", num2 + 1);
						}
					}
					Character component4 = val3.GetComponent<Character>();
					if ((Object)(object)component4 != (Object)null)
					{
						component4.SetLevel(level2);
						float num4 = __instance.GetMaxHealth() * MonsterModifiersPlugin.Cfg_SplitSpawn_HP.Value;
						component4.SetMaxHealth(num4);
						component4.SetHealth(num4);
					}
				}
			}
		}

		private static readonly Dictionary<string, string[]> _bowAliases = new Dictionary<string, string[]>
		{
			{
				"Skeleton",
				new string[2] { "Skeleton", "Skeleton_NoArcher" }
			},
			{
				"Draugr",
				new string[2] { "Draugr", "DraugrE