Decompiled source of EitrMagicExtended v1.0.4

EitrMagicExtended.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using ConditionalConfigSync;
using HarmonyLib;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Eitr Magic Extended")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Eitr Magic Extended")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("74db0e1d-cae4-4bbe-ada5-bc95e2bb7415")]
[assembly: AssemblyFileVersion("1.0.4")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.4.0")]
[module: UnverifiableCode]
namespace EitrMagicExtended;

[BepInPlugin("shudnal.EitrMagicExtended", "Eitr Magic Extended", "1.0.4")]
[BepInDependency("_shudnal.ConditionalConfigSync", "1.0.5")]
public class EitrMagicExtended : BaseUnityPlugin
{
	[HarmonyPatch(typeof(Hud), "UpdateEitr")]
	public class Hud_UpdateEitr_HideEitrValue
	{
		public static void Prefix(Hud __instance)
		{
			TMP_Text eitrText = __instance.m_eitrText;
			if (eitrText != null)
			{
				((Component)eitrText).gameObject.SetActive(!hideEitrValue.Value);
			}
		}
	}

	[HarmonyPatch(typeof(Player), "UpdateStats", new Type[] { typeof(float) })]
	public static class Player_UpdateStats_EitrRegenMultiplier
	{
		public static float s_eitrRegenTimeMultiplier = 1f;

		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			FieldInfo field = typeof(Player_UpdateStats_EitrRegenMultiplier).GetField("s_eitrRegenTimeMultiplier");
			for (int i = 1; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Mul && list[i - 1].opcode == OpCodes.Ldfld && ((FieldInfo)list[i - 1].operand).Name == "m_eiterRegen")
				{
					list.Insert(i + 1, new CodeInstruction(OpCodes.Ldsfld, (object)field));
					list.Insert(i + 2, new CodeInstruction(OpCodes.Mul, (object)null));
					break;
				}
			}
			return list;
		}

		[HarmonyPriority(100)]
		public static void Prefix(Player __instance, out float? __state)
		{
			__state = s_eitrRegenTimeMultiplier;
			s_eitrRegenTimeMultiplier = 1f;
			__instance.m_eitrRegenDelay = baseEitrRegenDelay.Value;
			__instance.m_eiterRegen = baseEitrRegen.Value;
			if (((Character)__instance).InIntro() || ((Character)__instance).IsTeleporting())
			{
				return;
			}
			if (extraEitrRegeneration.Value && extraEitrRegenerationPercent.Value > 0f && extraEitrRegenerationPoints.Value > 0)
			{
				__instance.m_eiterRegen *= 1f + ExtraEitr.GetMultiplier(__instance);
			}
			float value = linearRegenerationThreshold.Value;
			float value2 = linearRegenerationMultiplier.Value;
			if (!linearRegeneration.Value || value <= 0f || value >= 1f || value2 <= 0f)
			{
				return;
			}
			float maxEitr = ((Character)__instance).GetMaxEitr();
			if (maxEitr != 0f)
			{
				float eitrPercentage = ((Character)__instance).GetEitrPercentage();
				float eitr = __instance.GetEitr();
				float num = eitr / maxEitr;
				if (eitrPercentage < value)
				{
					s_eitrRegenTimeMultiplier = Mathf.Lerp(value2, 1f, Mathf.Clamp01(num / value));
				}
				else if (eitrPercentage > value)
				{
					s_eitrRegenTimeMultiplier = Mathf.Lerp(1f / value2, 1f, Mathf.Clamp01((1f - num) / (1f - value)));
				}
			}
		}

		private static void Postfix(ref float? __state)
		{
			Restore(ref __state);
		}

		private static void Finalizer(ref float? __state)
		{
			Restore(ref __state);
		}

		private static void Restore(ref float? state)
		{
			if (state.HasValue)
			{
				s_eitrRegenTimeMultiplier = state.Value;
				state = null;
			}
		}
	}

	public const string pluginID = "shudnal.EitrMagicExtended";

	public const string pluginName = "Eitr Magic Extended";

	public const string pluginVersion = "1.0.4";

	private readonly Harmony harmony = new Harmony("shudnal.EitrMagicExtended");

	internal static readonly ConfigSync configSync = new ConfigSync("shudnal.EitrMagicExtended")
	{
		DisplayName = "Eitr Magic Extended",
		CurrentVersion = "1.0.4",
		MinimumRequiredVersion = "1.0.4"
	};

	public static ConfigEntry<bool> configLocked;

	public static ConfigEntry<bool> loggingEnabled;

	public static ConfigEntry<bool> linearRegeneration;

	public static ConfigEntry<float> linearRegenerationMultiplier;

	public static ConfigEntry<float> linearRegenerationThreshold;

	public static ConfigEntry<bool> extraEitrRegeneration;

	public static ConfigEntry<float> extraEitrRegenerationPercent;

	public static ConfigEntry<int> extraEitrRegenerationPoints;

	public static ConfigEntry<bool> extraEitrRegenerationOnlyFood;

	public static ConfigEntry<bool> baseEitr;

	public static ConfigEntry<float> elementalMagicBaseEitrIncrease;

	public static ConfigEntry<float> bloodMagicBaseEitrIncrease;

	public static ConfigEntry<float> baseEitrRegen;

	public static ConfigEntry<float> baseEitrRegenDelay;

	public static ConfigEntry<bool> baseEitrNonLinear;

	public static ConfigEntry<float> baseEitrElementalMagicPower;

	public static ConfigEntry<float> baseEitrElementalMagicCoefficient;

	public static ConfigEntry<float> baseEitrBloodMagicPower;

	public static ConfigEntry<float> baseEitrBloodMagicCoefficient;

	public static ConfigEntry<bool> preventZeroDamageShieldSpam;

	public static ConfigEntry<bool> preventLookVectorConsoleSpam;

	public static ConfigEntry<bool> changeShieldColorByHealth;

	public static ConfigEntry<Color> shieldTargetColorZeroHealth;

	public static ConfigEntry<bool> addShieldStaffSecondaryAttack;

	public static ConfigEntry<StaffShieldPatches.HitType> shieldFullProtectionFrom;

	public static ConfigEntry<bool> hideEitrValue;

	public static EitrMagicExtended instance;

	private void Awake()
	{
		instance = this;
		ConfigInit();
		((ConditionalConfigSync)configSync).AddLockingConfigEntry<bool>(configLocked);
		harmony.PatchAll();
		Game.isModded = true;
	}

	private void OnDestroy()
	{
		Harmony obj = harmony;
		if (obj != null)
		{
			obj.UnpatchSelf();
		}
		instance = null;
	}

	private void ConfigInit()
	{
		//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
		configLocked = config("1 - General", "Lock Configuration", defaultValue: true, "Configuration is locked and can be changed by server admins only.");
		loggingEnabled = config("1 - General", "Logging enabled", defaultValue: false, "Enable logging. [Not Synced with Server]", synchronizedSetting: false);
		linearRegeneration = config("2 - Linear regeneration change", "Enabled", defaultValue: true, "Enable linear change of eitr regeneration rate. Overall time to regenerate eitr to 100% is still almost the same.");
		linearRegenerationMultiplier = config("2 - Linear regeneration change", "Multiplier", 3f, "Multiplier of regeneration rate when eitr is 0.\nIf value is above 1. Eitr will regenerate faster at lower values and proportionally slower at higher values.\nIf value is below 1. Eitr will regenerate slower at lower values and proportionally higher at higher values.");
		linearRegenerationThreshold = config("2 - Linear regeneration change", "Regeneration threshold", 0.5f, "Inflection point of eitr regeneration rate. Eitr regeneration rate is normal only in that point.\nIn that point regeneration rate changes its sign.\nIf set value is outside of 0-1 range eitr will regenerate normally");
		extraEitrRegeneration = config("3 - Extra eitr regeneration", "Enabled", defaultValue: true, "Enable increased eitr regeneration by X% per every Y point of additional eitr");
		extraEitrRegenerationPercent = config("3 - Extra eitr regeneration", "Percent", 1f, "Eitr regeneration increased by X%");
		extraEitrRegenerationPoints = config("3 - Extra eitr regeneration", "Points", 5, "Eitr regeneration increased per every Y points of additional eitr");
		extraEitrRegenerationOnlyFood = config("3 - Extra eitr regeneration", "Eitr from food only", defaultValue: true, "Only eitr gain from food is counted for increased regeneration");
		baseEitr = config("4 - Base eitr", "Enabled", defaultValue: true, "Base eitr will be increased proportionally to skills where set value reached at skill level 100.");
		elementalMagicBaseEitrIncrease = config("4 - Base eitr", "Elemental Magic", 40f, "Base eitr will be increased by set value when Elemental Magic skill is level 100");
		bloodMagicBaseEitrIncrease = config("4 - Base eitr", "Blood Magic", 40f, "Base eitr will be increased by set value when Blood Magic skill is level 100");
		baseEitrRegen = config("4 - Base eitr", "Base Regeneration rate", 2f, "Basic eitr regeneration rate per second.");
		baseEitrRegenDelay = config("4 - Base eitr", "Base Regeneration delay", 2f, "Delay amount before eitr regeneration starts.");
		baseEitrNonLinear = config("4 - Base eitr - Non linear", "Enabled", defaultValue: false, "Base eitr will increase using function X * (skill ^ Y) \"X multiplied by skill raised to the power of Y\"");
		baseEitrElementalMagicCoefficient = config("4 - Base eitr - Non linear", "Elemental Magic Coefficient", 3f, "X in formula");
		baseEitrElementalMagicPower = config("4 - Base eitr - Non linear", "Elemental Magic Power", 0.5f, "Y in formula");
		baseEitrBloodMagicCoefficient = config("4 - Base eitr - Non linear", "Blood Magic Coefficient", 3f, "X in formula");
		baseEitrBloodMagicPower = config("4 - Base eitr - Non linear", "Blood Magic Power", 0.5f, "Y in formula");
		preventZeroDamageShieldSpam = config("5 - Shield", "Prevent zero damage hit effect", defaultValue: true, "If you take 0 damage shield not play hit effect. Could prevent occasional hit effect spam.");
		preventLookVectorConsoleSpam = config("5 - Shield", "Prevent Look Rotation Viewing Vector Is Zero console message", defaultValue: true, "If shield takes damage from an indirect hit this message will no longer be shown in log file or console.");
		changeShieldColorByHealth = config("5 - Shield", "Change shield color depending on capacity", defaultValue: true, "Gradually changes shield color tint to different color depending on its current capacity.");
		shieldTargetColorZeroHealth = config<Color>("5 - Shield", "Change shield color at zero health to", new Color(1f, 0f, 1f, 0.5f), "Shield will have this color at 0 health.");
		addShieldStaffSecondaryAttack = config("5 - Shield", "Add shield staff secondary attack to break shield", defaultValue: true, "Shield staff can now break current shield with secondary attack. No skill point obtained this way.");
		shieldFullProtectionFrom = config("5 - Shield", "Shield grants full protection from", StaffShieldPatches.HitType.None, "Shield will absorb all damage from given hit type and completely prevent health damage.");
		hideEitrValue = config("6 - Misc", "Hide eitr bar text", defaultValue: false, "Hide eitr text value on eitr bar");
	}

	private ConfigEntry<T> config<T>(string group, string name, T defaultValue, ConfigDescription description, bool synchronizedSetting = true)
	{
		ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, defaultValue, description);
		((ConditionalConfigSync)configSync).AddConfigEntry<T>(val, (ConfigSyncMode)1, synchronizedSetting);
		return val;
	}

	private ConfigEntry<T> config<T>(string group, string name, T defaultValue, string description, bool synchronizedSetting = true)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Expected O, but got Unknown
		return config(group, name, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting);
	}

	public static void LogInfo(object message)
	{
		if (loggingEnabled.Value)
		{
			((BaseUnityPlugin)instance).Logger.LogInfo(message);
		}
	}

	public static void LogWarning(object data)
	{
		if (loggingEnabled.Value)
		{
			((BaseUnityPlugin)instance).Logger.LogWarning(data);
		}
	}

	public string GetStringConfig(string fieldName)
	{
		return (((object)this).GetType().GetField(fieldName).GetValue(this) as ConfigEntry<string>).Value;
	}

	public float GetFloatConfig(string fieldName)
	{
		return (((object)this).GetType().GetField(fieldName).GetValue(this) as ConfigEntry<float>).Value;
	}
}
internal static class ExtraEitr
{
	[HarmonyPatch(typeof(Player), "GetTotalFoodValue")]
	public static class Player_GetTotalFoodValue_BaseEitrIncrease
	{
		[HarmonyPriority(100)]
		public static void Postfix(Player __instance, ref float eitr)
		{
			if (EitrMagicExtended.baseEitr.Value && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
			{
				eitr += GetAdditionalBaseEitr(__instance);
			}
		}
	}

	[HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[]
	{
		typeof(ItemData),
		typeof(int),
		typeof(bool),
		typeof(float),
		typeof(int),
		typeof(bool)
	})]
	public static class ItemDrop_ItemData_GetTooltip_EitrRegenTooltipForFoodRegen
	{
		private static string[] tooltipTokens = new string[4] { "$se_staminaregen", "$item_food_regen", "$item_food_duration", "$item_food_eitr" };

		[HarmonyPriority(800)]
		[HarmonyAfter(new string[] { "shudnal.StaminaExtended" })]
		[HarmonyBefore(new string[] { "shudnal.MyLittleUI" })]
		private static void Postfix(ItemData item, ref string __result)
		{
			if (!IsFoodItemForExtraEitrRegeneration(item, out var foodEitr))
			{
				return;
			}
			int num = -1;
			string[] array = tooltipTokens;
			foreach (string value in array)
			{
				num = __result.IndexOf(value, StringComparison.InvariantCulture);
				if (num != -1)
				{
					break;
				}
			}
			if (num != -1)
			{
				string text = $"\n$se_eitrregen: <color=#9090ffff>{GetEitrRegenerationValueFromEitrPoints(foodEitr):P1}</color> ($item_current:<color=yellow>{GetMultiplier(Player.m_localPlayer):P1}</color>)";
				int num2 = __result.IndexOf("\n", num, StringComparison.InvariantCulture);
				if (num2 != -1)
				{
					__result = __result.Insert(num2, text);
				}
				else
				{
					__result += text;
				}
			}
		}
	}

	[HarmonyPatch(typeof(TextsDialog), "AddActiveEffects")]
	public static class TextsDialog_AddActiveEffects_SeasonTooltipWhenBuffDisabled
	{
		private static void Postfix(TextsDialog __instance)
		{
			if (!((Object)(object)Player.m_localPlayer == (Object)null))
			{
				float multiplier = GetMultiplier(Player.m_localPlayer);
				if (!(multiplier < 0.01f))
				{
					TextInfo obj = __instance.m_texts[0];
					obj.m_text += Localization.instance.Localize(string.Format("\n$se_eitrregen ({0}): <color=orange>{1:P1}</color>", EitrMagicExtended.extraEitrRegenerationOnlyFood.Value ? "$item_food" : "$hud_misc", multiplier));
				}
			}
		}
	}

	public static float GetMultiplier(Player player)
	{
		float maxEitr = default(float);
		if (EitrMagicExtended.extraEitrRegenerationOnlyFood.Value)
		{
			float num = default(float);
			float num2 = default(float);
			player.GetTotalFoodValue(ref num, ref num2, ref maxEitr);
		}
		else
		{
			maxEitr = ((Character)player).GetMaxEitr();
		}
		return GetEitrRegenerationValueFromEitrPoints(maxEitr - GetAdditionalBaseEitr(player));
	}

	private static float GetEitrRegenerationValueFromEitrPoints(float points)
	{
		return EitrMagicExtended.extraEitrRegenerationPercent.Value / 100f * points / (float)EitrMagicExtended.extraEitrRegenerationPoints.Value;
	}

	private static bool IsFoodItemForExtraEitrRegeneration(ItemData item, out float foodEitr)
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Invalid comparison between Unknown and I4
		foodEitr = 0f;
		if (!EitrMagicExtended.extraEitrRegeneration.Value || (Object)(object)Player.m_localPlayer == (Object)null)
		{
			return false;
		}
		if ((int)item.m_shared.m_itemType == 2)
		{
			foodEitr = item.m_shared.m_foodEitr;
		}
		return foodEitr > 0f || ((Object)(object)item.m_shared.m_appendToolTip != (Object)null && IsFoodItemForExtraEitrRegeneration(item.m_shared.m_appendToolTip.m_itemData, out foodEitr));
	}

	private static float GetAdditionalBaseEitr(Player player)
	{
		if (!EitrMagicExtended.baseEitr.Value)
		{
			return 0f;
		}
		if (EitrMagicExtended.baseEitrNonLinear.Value)
		{
			return EitrMagicExtended.baseEitrBloodMagicCoefficient.Value * Mathf.Pow(GetSkillFactor(player, (SkillType)10) * 100f, EitrMagicExtended.baseEitrBloodMagicPower.Value) + EitrMagicExtended.baseEitrElementalMagicCoefficient.Value * Mathf.Pow(GetSkillFactor(player, (SkillType)9) * 100f, EitrMagicExtended.baseEitrElementalMagicPower.Value);
		}
		return GetSkillFactor(player, (SkillType)9) * EitrMagicExtended.elementalMagicBaseEitrIncrease.Value + GetSkillFactor(player, (SkillType)10) * EitrMagicExtended.bloodMagicBaseEitrIncrease.Value;
	}

	private static float GetSkillFactor(Player player, SkillType skillType)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		return ((Character)player).GetSkills().m_skillData.ContainsKey(skillType) ? ((Character)player).GetSkillFactor(skillType) : 0f;
	}
}
public static class StaffShieldPatches
{
	[Flags]
	public enum HitType
	{
		None = 0,
		Undefined = 1,
		EnemyHit = 2,
		PlayerHit = 4,
		Fall = 8,
		Drowning = 0x10,
		Burning = 0x20,
		Freezing = 0x40,
		Poisoned = 0x80,
		Water = 0x100,
		Smoke = 0x200,
		EdgeOfWorld = 0x400,
		Impact = 0x800,
		Cart = 0x1000,
		Tree = 0x2000,
		Self = 0x4000,
		Structural = 0x8000,
		Turret = 0x10000,
		Boat = 0x20000,
		Stalagtite = 0x40000,
		Catapult = 0x80000,
		CinderFire = 0x100000,
		AshlandsOcean = 0x200000,
		AshlandsLava = 0x400000,
		Incinerator = 0x800000,
		DrawBridge = 0x1000000,
		All = 0x1FFFFFF
	}

	[HarmonyPatch(typeof(SE_Shield), "OnDamaged")]
	public static class SE_Shield_OnDamaged_PreventEffectSpam
	{
		[HarmonyPriority(0)]
		private static bool Prefix(ref HitData hit)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if (EitrMagicExtended.preventZeroDamageShieldSpam.Value && hit.GetTotalDamage() == 0f)
			{
				return false;
			}
			if (EitrMagicExtended.preventLookVectorConsoleSpam.Value && ((Vector3)(ref hit.m_dir)).sqrMagnitude < 0.1f)
			{
				hit.m_dir = Vector3.down;
			}
			return true;
		}

		private static void Postfix(SE_Shield __instance, ref HitData hit)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			UpdateShieldColor(__instance);
			if (IsFullProtected(hit.m_hitType) && hit.GetTotalDamage() > 0f)
			{
				DamageText instance = DamageText.instance;
				if (instance != null)
				{
					instance.ShowText(((StatusEffect)__instance).m_character.GetDamageModifier(((DamageTypes)(ref hit.m_damage)).GetMajorityDamageType()), ((StatusEffect)__instance).m_character.GetTopPoint(), hit.GetTotalDamage(), true);
				}
				((DamageTypes)(ref hit.m_damage)).Modify(0f);
			}
		}
	}

	[HarmonyPatch(typeof(SE_Shield), "IsDone")]
	public static class SE_Shield_IsDone_ClearCachedSphere
	{
		private static void Postfix(SE_Shield __instance, bool __result)
		{
			if (__result)
			{
				s_shieldSpheres.Remove(__instance);
			}
		}
	}

	[HarmonyPatch(typeof(ZoneSystem), "OnDestroy")]
	public static class ZoneSystem_OnDestroy_ClearSpheresCache
	{
		private static void Postfix()
		{
			s_shieldSpheres.Clear();
		}
	}

	[HarmonyPatch(typeof(ZoneSystem), "Start")]
	public static class ZoneSystem_Start_PatchStaffShield
	{
		[HarmonyPriority(0)]
		private static void Postfix()
		{
			if (EitrMagicExtended.addShieldStaffSecondaryAttack.Value)
			{
				ObjectDB instance = ObjectDB.instance;
				object item;
				if (instance == null)
				{
					item = null;
				}
				else
				{
					GameObject itemPrefab = instance.GetItemPrefab("StaffShield");
					item = ((itemPrefab == null) ? null : itemPrefab.GetComponent<ItemDrop>()?.m_itemData);
				}
				PatchStaffShield((ItemData)item);
			}
		}
	}

	[HarmonyPatch(typeof(Player), "Load")]
	public static class Player_Load_PatchStaffShield
	{
		[HarmonyPriority(0)]
		private static void Postfix(Player __instance)
		{
			if (EitrMagicExtended.addShieldStaffSecondaryAttack.Value)
			{
				CollectionExtensions.Do<ItemData>((IEnumerable<ItemData>)((Humanoid)__instance).GetInventory().m_inventory, (Action<ItemData>)PatchStaffShield);
			}
		}
	}

	[HarmonyPatch(typeof(Humanoid), "EquipItem")]
	public static class Humanoid_EquipItem_PatchStaffShield
	{
		[HarmonyPriority(0)]
		private static void Postfix(ItemData item, bool __result)
		{
			if (__result && EitrMagicExtended.addShieldStaffSecondaryAttack.Value)
			{
				PatchStaffShield(item);
			}
		}
	}

	[HarmonyPatch(typeof(Humanoid), "StartAttack")]
	public static class Humanoid_StartAttack_Staff
	{
		public static ItemData staffshield;

		public static Attack attack;

		private static bool Prefix(Humanoid __instance, bool secondaryAttack)
		{
			if (secondaryAttack && (Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				ItemData currentWeapon = __instance.GetCurrentWeapon();
				if (currentWeapon != null && currentWeapon.m_shared.m_name == "$item_staffshield")
				{
					return (Object)(object)currentWeapon.m_shared.m_attackStatusEffect == (Object)null || ((Character)Player.m_localPlayer).GetSEMan().HaveStatusEffect(currentWeapon.m_shared.m_attackStatusEffect.NameHash());
				}
			}
			return true;
		}

		private static void Postfix(Humanoid __instance, bool __result)
		{
			if (__result && (Object)(object)__instance == (Object)(object)Player.m_localPlayer && __instance.m_currentAttackIsSecondary)
			{
				ItemData currentWeapon = __instance.GetCurrentWeapon();
				if (currentWeapon != null && currentWeapon.m_shared.m_name == "$item_staffshield")
				{
					staffshield = currentWeapon;
					attack = __instance.m_currentAttack;
				}
			}
		}
	}

	[HarmonyPatch(typeof(Attack), "FireProjectileBurst")]
	public static class Attack_FireProjectileBurst_Staff
	{
		private static void Prefix(Attack __instance, ref bool __state)
		{
			if (__state = __instance == Humanoid_StartAttack_Staff.attack && __instance.m_weapon == Humanoid_StartAttack_Staff.staffshield)
			{
				Humanoid_StartAttack_Staff.staffshield.m_shared.m_attackStatusEffectChance = 0f;
			}
		}

		private static void Postfix(bool __state)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			if (__state)
			{
				Humanoid_StartAttack_Staff.staffshield.m_shared.m_attackStatusEffectChance = 1f;
				StatusEffect attackStatusEffect = Humanoid_StartAttack_Staff.staffshield.m_shared.m_attackStatusEffect;
				SE_Shield val = (SE_Shield)(object)((attackStatusEffect is SE_Shield) ? attackStatusEffect : null);
				if (val != null)
				{
					val.m_breakEffects.Create(((Character)Player.m_localPlayer).GetCenterPoint(), ((Component)Player.m_localPlayer).transform.rotation, ((Component)Player.m_localPlayer).transform, ((Character)Player.m_localPlayer).GetRadius() * 2f, -1, default(ZDOID));
					((Character)Player.m_localPlayer).GetSEMan().RemoveStatusEffect((StatusEffect)(object)val, false);
				}
			}
		}
	}

	private static readonly Dictionary<SE_Shield, MeshRenderer> s_shieldSpheres = new Dictionary<SE_Shield, MeshRenderer>();

	private static readonly MaterialPropertyBlock s_matBlock = new MaterialPropertyBlock();

	private const string itemDataStaffShieldName = "$item_staffshield";

	private const string itemDropStaffShieldName = "StaffShield";

	private static bool IsFullProtected(HitType hitType)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		return EitrMagicExtended.shieldFullProtectionFrom.Value != HitType.None && EitrMagicExtended.shieldFullProtectionFrom.Value.HasFlag(GetHitType(hitType));
	}

	private static HitType GetHitType(HitType hitType)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Expected I4, but got Unknown
		if (1 == 0)
		{
		}
		HitType result = (int)hitType switch
		{
			0 => HitType.Undefined, 
			1 => HitType.EnemyHit, 
			2 => HitType.PlayerHit, 
			3 => HitType.Fall, 
			4 => HitType.Drowning, 
			5 => HitType.Burning, 
			6 => HitType.Freezing, 
			7 => HitType.Poisoned, 
			8 => HitType.Water, 
			9 => HitType.Smoke, 
			10 => HitType.EdgeOfWorld, 
			11 => HitType.Impact, 
			12 => HitType.Cart, 
			13 => HitType.Tree, 
			14 => HitType.Self, 
			15 => HitType.Structural, 
			16 => HitType.Turret, 
			17 => HitType.Boat, 
			18 => HitType.Stalagtite, 
			19 => HitType.Catapult, 
			20 => HitType.CinderFire, 
			21 => HitType.AshlandsOcean, 
			22 => HitType.AshlandsLava, 
			23 => HitType.Incinerator, 
			24 => HitType.DrawBridge, 
			_ => HitType.All, 
		};
		if (1 == 0)
		{
		}
		return result;
	}

	private static void UpdateShieldColor(SE_Shield shield)
	{
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		if (!EitrMagicExtended.changeShieldColorByHealth.Value || shield.m_totalAbsorbDamage <= 0f || ((StatusEffect)shield).m_startEffectInstances == null || ((StatusEffect)shield).m_startEffectInstances.Length == 0 || !Object.op_Implicit((Object)(object)((StatusEffect)shield).m_startEffectInstances[0]))
		{
			return;
		}
		if (!s_shieldSpheres.TryGetValue(shield, out var value) || !Object.op_Implicit((Object)(object)value))
		{
			Transform val = ((StatusEffect)shield).m_startEffectInstances[0].transform.Find("Sphere");
			value = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<MeshRenderer>() : null);
			if (!Object.op_Implicit((Object)(object)value))
			{
				return;
			}
			s_shieldSpheres[shield] = value;
		}
		if (Object.op_Implicit((Object)(object)((Renderer)value).sharedMaterial))
		{
			((Renderer)value).GetPropertyBlock(s_matBlock);
			s_matBlock.SetColor(ShaderProps._Color, Color.Lerp(((Renderer)value).sharedMaterial.color, EitrMagicExtended.shieldTargetColorZeroHealth.Value, shield.m_damage / shield.m_totalAbsorbDamage));
			((Renderer)value).SetPropertyBlock(s_matBlock);
		}
	}

	public static void PatchStaffShield(ItemData item)
	{
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Expected O, but got Unknown
		if (item == null || item.m_shared.m_name != "$item_staffshield")
		{
			return;
		}
		Attack attack = item.m_shared.m_secondaryAttack;
		if (attack != null && !(attack.m_attackAnimation == "staff_trollsummon"))
		{
			CollectionExtensions.Do<FieldInfo>((IEnumerable<FieldInfo>)((object)attack).GetType().GetFields(), (Action<FieldInfo>)delegate(FieldInfo f)
			{
				f.SetValue(attack, f.GetValue(item.m_shared.m_attack));
			});
			Attack obj = attack;
			obj.m_attackEitr *= 0.5f;
			Attack obj2 = attack;
			obj2.m_attackHealthPercentage *= 0.5f;
			attack.m_attackAnimation = "staff_trollsummon";
			attack.m_startEffect = new EffectList();
		}
	}
}