Decompiled source of PaladinMod v0.7.1

PaladinMod.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("PaladinMod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PaladinMod")]
[assembly: AssemblyTitle("PaladinMod")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PaladinMod
{
	public class BlessingTier
	{
		public string Section;

		public string EffectName;

		public ConfigEntry<float> RegenTotal;

		public ConfigEntry<float> RegenDuration;

		public ConfigEntry<float> EitrCost;

		public ConfigEntry<float> Radius;

		public ConfigEntry<float> Cooldown;

		public int Hash;
	}
	public class ShieldDef
	{
		public string Prefab;

		public string BaseShield;

		public string FallbackName;

		public BlessingTier Blessing;

		public bool HolyFire;
	}
	[BepInPlugin("com.yourname.paladinmod", "PaladinMod", "0.7.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class PaladinPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.yourname.paladinmod";

		public const string PluginName = "PaladinMod";

		public const string PluginVersion = "0.7.1";

		public const string GoldVfxName = "vfx_PaladinPulse";

		public const string ShrinePrefab = "piece_paladin_shrine";

		public const string ShrineName = "Dvergr Paladin Shrine";

		public static int MaxQuality = 6;

		public static GameObject GoldVfx;

		public static GameObject DivineHitVfxLightning;

		public static GameObject DivineHitVfxSpirit;

		public static readonly BlessingTier BlackmetalBlessing = new BlessingTier
		{
			Section = "Black metal blessing",
			EffectName = "SE_PaladinBlessingBlackmetal"
		};

		public static readonly BlessingTier FlametalBlessing = new BlessingTier
		{
			Section = "Flametal blessing",
			EffectName = "SE_PaladinBlessingFlametal"
		};

		public static readonly Dictionary<string, ShieldDef> Shields = new Dictionary<string, ShieldDef>();

		private static readonly ShieldDef[] ShieldList = new ShieldDef[6]
		{
			new ShieldDef
			{
				BaseShield = "ShieldWoodTower",
				FallbackName = "Wood tower shield"
			},
			new ShieldDef
			{
				BaseShield = "ShieldBoneTower",
				FallbackName = "Bone tower shield"
			},
			new ShieldDef
			{
				BaseShield = "ShieldIronTower",
				FallbackName = "Iron tower shield"
			},
			new ShieldDef
			{
				BaseShield = "ShieldSerpentscale",
				FallbackName = "Serpentscale shield"
			},
			new ShieldDef
			{
				BaseShield = "ShieldBlackmetalTower",
				FallbackName = "Black metal tower shield",
				Blessing = BlackmetalBlessing
			},
			new ShieldDef
			{
				BaseShield = "ShieldFlametalTower",
				FallbackName = "Flametal tower shield",
				Blessing = FlametalBlessing,
				HolyFire = true
			}
		};

		public static ConfigEntry<int> BaseShieldQuality;

		public static ConfigEntry<int> MaxUpgrades;

		public static ConfigEntry<float> Reflect;

		public static ConfigEntry<float> ReflectPerLevel;

		public static ConfigEntry<float> DivineUndeadMultiplier;

		public static ConfigEntry<float> DivineOtherMultiplier;

		public static ConfigEntry<string> UndeadPrefixes;

		public static ConfigEntry<string> PulseVfx;

		public static ConfigEntry<float> PulseVfxDuration;

		public static ConfigEntry<float> HitVfxDuration;

		public static ConfigEntry<Color> PulseColor;

		public static ConfigEntry<Color> ShieldTint;

		public static ConfigEntry<Color> ShrineTint;

		private void Awake()
		{
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			BaseShieldQuality = ((BaseUnityPlugin)this).Config.Bind<int>("Crafting", "BaseShieldQuality", 0, "Minimum upgrade level of the vanilla tower shield used for consecration. 0 = fully upgraded.");
			MaxUpgrades = ((BaseUnityPlugin)this).Config.Bind<int>("Crafting", "MaxUpgrades", 5, "Number of upgrades for a consecrated shield (restart needed).");
			Reflect = ((BaseUnityPlugin)this).Config.Bind<float>("Divine damage", "ReflectPercent", 10f, "Percent of blocked damage reflected as divine damage.");
			ReflectPerLevel = ((BaseUnityPlugin)this).Config.Bind<float>("Divine damage", "ReflectPercentPerLevel", 2f, "Extra reflect percent per upgrade level.");
			DivineUndeadMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Divine damage", "UndeadMultiplier", 1.5f, "Divine damage multiplier against undead (weak).");
			DivineOtherMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Divine damage", "OtherMultiplier", 0.5f, "Divine damage multiplier against everything else (resistant).");
			UndeadPrefixes = ((BaseUnityPlugin)this).Config.Bind<string>("Divine damage", "ExtraUndeadPrefixes", "Charred", "Comma-separated creature prefab name prefixes that also count as undead. Creatures in the Undead faction or weak to spirit damage always count.");
			BindBlessing(BlackmetalBlessing, 40f, 20f);
			BindBlessing(FlametalBlessing, 60f, 30f);
			PulseVfx = ((BaseUnityPlugin)this).Config.Bind<string>("Visuals", "PulseVfx", "vfx_Potion_health_medium", "Vanilla effect on each pulse (restart needed). Empty = none.");
			PulseVfxDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "PulseVfxDuration", 1f, "Seconds the pulse effect stays visible.");
			HitVfxDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "DivineHitVfxDuration", 1f, "Seconds the divine hit effect stays on the attacker.");
			PulseColor = ((BaseUnityPlugin)this).Config.Bind<Color>("Visuals", "PulseColor", new Color(1f, 0.8f, 0.3f), "Colour of the pulse and divine hit effects (restart needed).");
			ShieldTint = ((BaseUnityPlugin)this).Config.Bind<Color>("Visuals", "ShieldTint", new Color(1f, 0.85f, 0.45f), "Gold tint of the consecrated shields and their icons (restart needed).");
			ShrineTint = ((BaseUnityPlugin)this).Config.Bind<Color>("Visuals", "ShrineTint", new Color(1f, 0.85f, 0.45f), "Gold tint of the Dvergr Paladin Shrine (restart needed).");
			PrefabManager.OnVanillaPrefabsAvailable += AddItems;
			new Harmony("com.yourname.paladinmod").PatchAll();
		}

		private void BindBlessing(BlessingTier tier, float regenTotal, float eitrCost)
		{
			tier.RegenTotal = ((BaseUnityPlugin)this).Config.Bind<float>(tier.Section, "RegenTotal", regenTotal, "Total HP restored by the blessing (restart needed).");
			tier.RegenDuration = ((BaseUnityPlugin)this).Config.Bind<float>(tier.Section, "RegenDuration", 10f, "Blessing duration in seconds (restart needed).");
			tier.EitrCost = ((BaseUnityPlugin)this).Config.Bind<float>(tier.Section, "EitrCost", eitrCost, "Eitr spent per pulse.");
			tier.Radius = ((BaseUnityPlugin)this).Config.Bind<float>(tier.Section, "Radius", 5f, "Pulse radius in meters.");
			tier.Cooldown = ((BaseUnityPlugin)this).Config.Bind<float>(tier.Section, "Cooldown", 10f, "Seconds between pulses.");
		}

		private void AddItems()
		{
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			PrefabManager.OnVanillaPrefabsAvailable -= AddItems;
			MaxQuality = 1 + Mathf.Max(0, MaxUpgrades.Value);
			CreateShrine();
			ShieldDef[] shieldList = ShieldList;
			foreach (ShieldDef shieldDef in shieldList)
			{
				if ((Object)(object)PrefabManager.Instance.GetPrefab(shieldDef.BaseShield) == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Vanilla shield '" + shieldDef.BaseShield + "' not found; skipping its consecrated version."));
					continue;
				}
				shieldDef.Prefab = "Consecrated" + shieldDef.BaseShield;
				CustomItem val = CreateShield(shieldDef);
				Shields[shieldDef.Prefab] = shieldDef;
				if (shieldDef.Blessing != null && shieldDef.Blessing.Hash == 0)
				{
					CreateBlessing(shieldDef.Blessing, val.ItemDrop.m_itemData.m_shared.m_icons[0]);
				}
			}
			if (!string.IsNullOrEmpty(PulseVfx.Value))
			{
				GoldVfx = PrefabManager.Instance.CreateClonedPrefab("vfx_PaladinPulse", PulseVfx.Value);
				if ((Object)(object)GoldVfx != (Object)null)
				{
					MakeGold(GoldVfx, PulseColor.Value);
				}
			}
			DivineHitVfxLightning = CreateGoldStatusVfx("vfx_PaladinDivineLightning", "Lightning");
			DivineHitVfxSpirit = CreateGoldStatusVfx("vfx_PaladinDivineSpirit", "Spirit");
		}

		private static void CreateBlessing(BlessingTier tier, Sprite icon)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			SE_Stats val = ScriptableObject.CreateInstance<SE_Stats>();
			((Object)val).name = tier.EffectName;
			((StatusEffect)val).m_name = "Paladin's blessing";
			((StatusEffect)val).m_tooltip = "Regenerating health.";
			((StatusEffect)val).m_icon = icon;
			((StatusEffect)val).m_ttl = tier.RegenDuration.Value;
			val.m_healthOverTime = tier.RegenTotal.Value;
			val.m_healthOverTimeDuration = tier.RegenDuration.Value;
			val.m_healthOverTimeInterval = 1f;
			ItemManager.Instance.AddStatusEffect(new CustomStatusEffect((StatusEffect)(object)val, false));
			tier.Hash = ((StatusEffect)val).NameHash();
		}

		private GameObject CreateGoldStatusVfx(string name, string statusEffect)
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = null;
			StatusEffect prefab = Cache.GetPrefab<StatusEffect>(statusEffect);
			if ((Object)(object)prefab != (Object)null && prefab.m_startEffects?.m_effectPrefabs != null)
			{
				EffectData[] effectPrefabs = prefab.m_startEffects.m_effectPrefabs;
				foreach (EffectData val2 in effectPrefabs)
				{
					if ((Object)(object)val2.m_prefab != (Object)null)
					{
						val = val2.m_prefab;
						break;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("No visual effect found on status effect '" + statusEffect + "'; divine hits will have no effect."));
				return null;
			}
			GameObject val3 = PrefabManager.Instance.CreateClonedPrefab(name, val);
			MakeLocalOnly(val3);
			MakeGold(val3, PulseColor.Value);
			return val3;
		}

		private static void MakeLocalOnly(GameObject vfx)
		{
			ZSyncTransform[] componentsInChildren = vfx.GetComponentsInChildren<ZSyncTransform>(true);
			foreach (ZSyncTransform val in componentsInChildren)
			{
				Object.DestroyImmediate((Object)(object)val);
			}
			ZNetView[] componentsInChildren2 = vfx.GetComponentsInChildren<ZNetView>(true);
			foreach (ZNetView val2 in componentsInChildren2)
			{
				Object.DestroyImmediate((Object)(object)val2);
			}
		}

		private static CustomItem CreateShield(ShieldDef def)
		{
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Expected O, but got Unknown
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Expected O, but got Unknown
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected O, but got Unknown
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Expected O, but got Unknown
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Expected O, but got Unknown
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			SharedData shared = PrefabManager.Instance.GetPrefab(def.BaseShield).GetComponent<ItemDrop>().m_itemData.m_shared;
			string text = LocalizationManager.Instance.TryTranslate(shared.m_name.TrimStart(new char[1] { '$' }));
			if (string.IsNullOrEmpty(text) || text.Contains("$") || text == shared.m_name.TrimStart(new char[1] { '$' }))
			{
				text = def.FallbackName;
			}
			int value = BaseShieldQuality.Value;
			string text2 = ((value > 0) ? $"level {value}+" : "fully upgraded");
			string text3 = "Consecrated at a Dvergr Paladin Shrine. ";
			if (def.Blessing != null)
			{
				text3 += "Blocking a blow blesses nearby allies with regeneration, fuelled by Eitr. ";
			}
			text3 += (def.HolyFire ? "Blocked blows return holy fire to the attacker, searing the undead." : "Blocked blows strike the attacker with holy lightning, searing the undead.");
			List<RequirementConfig> list = new List<RequirementConfig>
			{
				new RequirementConfig(def.BaseShield, 1, 0, true),
				new RequirementConfig("Thunderstone", 3, 1, true),
				new RequirementConfig("Coins", 200, 0, true)
			};
			if (def.Blessing != null)
			{
				list.Add(new RequirementConfig("Eitr", 10, 5, true));
			}
			ItemConfig val = new ItemConfig();
			val.Name = "Consecrated " + text;
			val.Description = text3 + " Crafted from a " + text2 + " " + text + ".";
			val.CraftingStation = "piece_paladin_shrine";
			val.MinStationLevel = 1;
			val.Requirements = list.ToArray();
			ItemConfig val2 = val;
			CustomItem val3 = new CustomItem(def.Prefab, def.BaseShield, val2);
			SharedData shared2 = val3.ItemDrop.m_itemData.m_shared;
			shared2.m_maxQuality = MaxQuality;
			Tint(val3.ItemPrefab, ShieldTint.Value);
			Sprite[] icons = shared2.m_icons;
			for (int i = 0; i < icons.Length; i++)
			{
				if ((Object)(object)icons[i] != (Object)null)
				{
					icons[i] = GoldIcon(icons[i], ShieldTint.Value);
				}
			}
			ItemManager.Instance.AddItem(val3);
			return val3;
		}

		private static void CreateShrine()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Expected O, but got Unknown
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Expected O, but got Unknown
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Expected O, but got Unknown
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Expected O, but got Unknown
			PieceConfig val = new PieceConfig();
			val.Name = "Dvergr Paladin Shrine";
			val.Description = "A Dvergr shrine where tower shields are consecrated and upgraded.";
			val.PieceTable = PieceTables.Hammer;
			val.Category = PieceCategories.Crafting;
			val.CraftingStation = CraftingStations.Workbench;
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[3]
			{
				new RequirementConfig("Stone", 20, 0, true),
				new RequirementConfig("Wood", 10, 0, true),
				new RequirementConfig("Thunderstone", 1, 0, true)
			};
			PieceConfig val2 = val;
			CustomPiece val3 = new CustomPiece("piece_paladin_shrine", "guard_stone", val2);
			GameObject piecePrefab = val3.PiecePrefab;
			GameObject val4 = null;
			PrivateArea component = piecePrefab.GetComponent<PrivateArea>();
			if ((Object)(object)component != (Object)null)
			{
				if ((Object)(object)component.m_enabledEffect != (Object)null)
				{
					component.m_enabledEffect.SetActive(true);
				}
				if ((Object)(object)component.m_connectEffect != (Object)null)
				{
					component.m_connectEffect.SetActive(false);
				}
				if ((Object)(object)component.m_inRangeEffect != (Object)null)
				{
					component.m_inRangeEffect.SetActive(false);
				}
				if ((Object)(object)component.m_areaMarker != (Object)null)
				{
					val4 = ((Component)component.m_areaMarker).gameObject;
					val4.SetActive(false);
				}
				Object.DestroyImmediate((Object)(object)component);
			}
			CraftingStation val5 = piecePrefab.AddComponent<CraftingStation>();
			val5.m_name = "Dvergr Paladin Shrine";
			val5.m_areaMarker = val4;
			val5.m_roofCheckPoint = piecePrefab.transform;
			val5.m_craftRequireRoof = false;
			val5.m_craftRequireFire = false;
			val5.m_showBasicRecipies = false;
			val5.m_hasCraftTab = true;
			val5.m_canRepair = true;
			val5.m_discoverRange = 4f;
			val5.m_rangeBuild = 10f;
			val5.m_useDistance = 2f;
			GameObject prefab = PrefabManager.Instance.GetPrefab(CraftingStations.BlackForge);
			CraftingStation val6 = ((prefab != null) ? prefab.GetComponent<CraftingStation>() : null);
			if ((Object)(object)val6 != (Object)null)
			{
				val5.m_craftingSkill = val6.m_craftingSkill;
				val5.m_useAnimation = val6.m_useAnimation;
				val5.m_craftItemEffects = val6.m_craftItemEffects;
				val5.m_craftItemDoneEffects = val6.m_craftItemDoneEffects;
				val5.m_repairItemDoneEffects = val6.m_repairItemDoneEffects;
				val5.m_craftItemDoneFailEffects = val6.m_craftItemDoneFailEffects;
			}
			CraftingStation val7 = val5;
			if (val7.m_craftItemEffects == null)
			{
				val7.m_craftItemEffects = new EffectList();
			}
			val7 = val5;
			if (val7.m_craftItemDoneEffects == null)
			{
				val7.m_craftItemDoneEffects = new EffectList();
			}
			val7 = val5;
			if (val7.m_repairItemDoneEffects == null)
			{
				val7.m_repairItemDoneEffects = new EffectList();
			}
			val7 = val5;
			if (val7.m_craftItemDoneFailEffects == null)
			{
				val7.m_craftItemDoneFailEffects = new EffectList();
			}
			Tint(piecePrefab, ShrineTint.Value);
			Sprite val8 = RenderManager.Instance.Render(piecePrefab, RenderManager.IsometricRotation);
			if ((Object)(object)val8 != (Object)null)
			{
				val3.Piece.m_icon = val8;
			}
			val5.m_icon = val3.Piece.m_icon;
			PieceManager.Instance.AddPiece(val3);
		}

		private static void Tint(GameObject prefab, Color tint)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				Material[] sharedMaterials = val.sharedMaterials;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					if (!((Object)(object)sharedMaterials[j] == (Object)null))
					{
						Material val2 = new Material(sharedMaterials[j]);
						if (val2.HasProperty("_Color"))
						{
							val2.color = tint;
						}
						sharedMaterials[j] = val2;
					}
				}
				val.sharedMaterials = sharedMaterials;
			}
		}

		private static Sprite GoldIcon(Sprite source, Color gold)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: 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_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			Rect textureRect = source.textureRect;
			RenderTexture temporary = RenderTexture.GetTemporary(((Texture)source.texture).width, ((Texture)source.texture).height, 0, (RenderTextureFormat)0);
			Graphics.Blit((Texture)(object)source.texture, temporary);
			RenderTexture active = RenderTexture.active;
			RenderTexture.active = temporary;
			Texture2D val = new Texture2D((int)((Rect)(ref textureRect)).width, (int)((Rect)(ref textureRect)).height, (TextureFormat)4, false);
			val.ReadPixels(textureRect, 0, 0);
			RenderTexture.active = active;
			RenderTexture.ReleaseTemporary(temporary);
			Color[] pixels = val.GetPixels();
			Color val3 = default(Color);
			for (int i = 0; i < pixels.Length; i++)
			{
				Color val2 = pixels[i];
				float num = Mathf.Min(1f, (0.299f * val2.r + 0.587f * val2.g + 0.114f * val2.b) * 1.6f);
				((Color)(ref val3))..ctor(gold.r * num, gold.g * num, gold.b * num, val2.a);
				pixels[i] = Color.Lerp(val2, val3, 0.8f);
			}
			val.SetPixels(pixels);
			val.Apply();
			Sprite val4 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), source.pixelsPerUnit);
			((Object)val4).name = ((Object)source).name + "_gold";
			return val4;
		}

		private static void MakeGold(GameObject vfx, Color gold)
		{
			//IL_0017: 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)
			//IL_001f: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_0075: Expected O, but got Unknown
			//IL_007f: 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)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: 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)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			ParticleSystem[] componentsInChildren = vfx.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val in componentsInChildren)
			{
				MainModule main = val.main;
				((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(gold);
				ColorOverLifetimeModule colorOverLifetime = val.colorOverLifetime;
				if (((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled)
				{
					MinMaxGradient color = ((ColorOverLifetimeModule)(ref colorOverLifetime)).color;
					Gradient obj = ((MinMaxGradient)(ref color)).gradient;
					if (obj == null)
					{
						color = ((ColorOverLifetimeModule)(ref colorOverLifetime)).color;
						obj = ((MinMaxGradient)(ref color)).gradientMax;
					}
					Gradient val2 = obj;
					Gradient val3 = new Gradient();
					val3.SetKeys((GradientColorKey[])(object)new GradientColorKey[2]
					{
						new GradientColorKey(Color.white, 0f),
						new GradientColorKey(Color.white, 1f)
					}, (GradientAlphaKey[])((val2 != null) ? ((Array)val2.alphaKeys) : ((Array)new GradientAlphaKey[2]
					{
						new GradientAlphaKey(1f, 0f),
						new GradientAlphaKey(0f, 1f)
					})));
					((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(val3);
				}
			}
			Light[] componentsInChildren2 = vfx.GetComponentsInChildren<Light>(true);
			foreach (Light val4 in componentsInChildren2)
			{
				val4.color = gold;
			}
		}
	}
	internal static class Paladin
	{
		private static float _nextPulseTime;

		private static float _nextEitrWarning;

		private static readonly List<Player> Nearby = new List<Player>();

		private static readonly FieldRef<Humanoid, ItemData> LeftItem = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_leftItem");

		public static ItemData GetShield(Humanoid humanoid, out ShieldDef def)
		{
			def = null;
			ItemData val = LeftItem.Invoke(humanoid);
			if ((Object)(object)val?.m_dropPrefab == (Object)null)
			{
				return null;
			}
			return PaladinPlugin.Shields.TryGetValue(((Object)val.m_dropPrefab).name, out def) ? val : null;
		}

		public static void TryPulse(Player player, BlessingTier tier)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			if (Time.time < _nextPulseTime)
			{
				return;
			}
			float value = tier.EitrCost.Value;
			if (!((Character)player).HaveEitr(value))
			{
				if (Time.time >= _nextEitrWarning)
				{
					((Character)player).Message((MessageType)1, "Not enough Eitr", 0, (Sprite)null, false);
					_nextEitrWarning = Time.time + 5f;
				}
				return;
			}
			((Character)player).UseEitr(value);
			_nextPulseTime = Time.time + tier.Cooldown.Value;
			Nearby.Clear();
			Player.GetPlayersInRange(((Component)player).transform.position, tier.Radius.Value, Nearby);
			foreach (Player item in Nearby)
			{
				if (!((Character)item).IsDead())
				{
					((Character)item).GetSEMan().AddStatusEffect(tier.Hash, true, 0, 0f, (short)(-1));
				}
			}
			if ((Object)(object)PaladinPlugin.GoldVfx != (Object)null)
			{
				GameObject val = Object.Instantiate<GameObject>(PaladinPlugin.GoldVfx, ((Component)player).transform.position, Quaternion.identity);
				Object.Destroy((Object)(object)val, PaladinPlugin.PulseVfxDuration.Value);
			}
		}

		public static void Reflect(Player player, Character attacker, float blocked, ShieldDef def, int quality)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)attacker == (Object)null || (Object)(object)attacker == (Object)(object)player || attacker.IsDead())
			{
				return;
			}
			float num = PaladinPlugin.Reflect.Value + PaladinPlugin.ReflectPerLevel.Value * (float)(quality - 1);
			float num2 = (IsUndead(attacker) ? PaladinPlugin.DivineUndeadMultiplier.Value : PaladinPlugin.DivineOtherMultiplier.Value);
			float num3 = blocked * num / 100f * num2;
			if (!(num3 <= 0f))
			{
				HitData val = new HitData();
				val.m_damage.m_damage = num3;
				val.m_point = attacker.GetCenterPoint();
				Vector3 val2 = ((Component)attacker).transform.position - ((Component)player).transform.position;
				val.m_dir = ((Vector3)(ref val2)).normalized;
				val.m_blockable = false;
				val.m_dodgeable = false;
				val.SetAttacker((Character)(object)player);
				attacker.Damage(val);
				GameObject val3 = (def.HolyFire ? PaladinPlugin.DivineHitVfxSpirit : PaladinPlugin.DivineHitVfxLightning);
				if ((Object)(object)val3 != (Object)null)
				{
					GameObject val4 = Object.Instantiate<GameObject>(val3, attacker.GetCenterPoint(), Quaternion.identity, ((Component)attacker).transform);
					Object.Destroy((Object)(object)val4, PaladinPlugin.HitVfxDuration.Value);
				}
			}
		}

		public static bool IsUndead(Character character)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_001b: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			if ((int)character.m_faction == 3)
			{
				return true;
			}
			DamageModifier spirit = character.m_damageModifiers.m_spirit;
			if ((int)spirit == 2 || (int)spirit == 6 || (int)spirit == 8)
			{
				return true;
			}
			string prefabName = Utils.GetPrefabName(((Component)character).gameObject);
			string[] array = PaladinPlugin.UndeadPrefixes.Value.Split(new char[1] { ',' });
			foreach (string text in array)
			{
				if (text.Trim().Length > 0 && prefabName.StartsWith(text.Trim()))
				{
					return true;
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Humanoid), "BlockAttack")]
	internal static class PaladinBlockPatch
	{
		private static void Prefix(HitData __0, out float __state)
		{
			__state = __0.GetTotalBlockableDamage();
		}

		private static void Postfix(Humanoid __instance, HitData __0, Character __1, bool __result, float __state)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			if (!__result || (Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			ShieldDef def;
			ItemData shield = Paladin.GetShield(__instance, out def);
			if (shield == null)
			{
				return;
			}
			float num = __state - __0.GetTotalBlockableDamage();
			if (!(num <= 0f))
			{
				Player player = (Player)__instance;
				Paladin.Reflect(player, __1, num, def, shield.m_quality);
				if (def.Blessing != null)
				{
					Paladin.TryPulse(player, def.Blessing);
				}
			}
		}
	}
	[HarmonyPatch(typeof(CraftingStation), "GetLevel")]
	internal static class ShrineLevelPatch
	{
		private static void Postfix(CraftingStation __instance, ref int __result)
		{
			if (__instance.m_name == "Dvergr Paladin Shrine")
			{
				__result = Mathf.Max(__result, PaladinPlugin.MaxQuality);
			}
		}
	}
	internal static class BaseShieldRule
	{
		public static SharedData GetBaseShield(Recipe recipe)
		{
			if ((Object)(object)recipe?.m_item == (Object)null || !PaladinPlugin.Shields.TryGetValue(((Object)recipe.m_item).name, out var value))
			{
				return null;
			}
			Requirement[] resources = recipe.m_resources;
			foreach (Requirement val in resources)
			{
				if ((Object)(object)val.m_resItem != (Object)null && ((Object)val.m_resItem).name == value.BaseShield)
				{
					return val.m_resItem.m_itemData.m_shared;
				}
			}
			return null;
		}

		public static int FindQuality(Inventory inventory, SharedData baseShield)
		{
			int num = PaladinPlugin.BaseShieldQuality.Value;
			if (num <= 0 || num > baseShield.m_maxQuality)
			{
				num = baseShield.m_maxQuality;
			}
			for (int i = num; i <= baseShield.m_maxQuality; i++)
			{
				if (inventory.CountItems(baseShield.m_name, i, true) > 0)
				{
					return i;
				}
			}
			return -1;
		}
	}
	[HarmonyPatch(typeof(Player), "HaveRequirementItems")]
	internal static class PaladinRecipeCheckPatch
	{
		private static void Postfix(Player __instance, Recipe piece, bool discover, int qualityLevel, ref bool __result)
		{
			if (!(!__result || discover) && qualityLevel == 1)
			{
				SharedData baseShield = BaseShieldRule.GetBaseShield(piece);
				if (baseShield != null && BaseShieldRule.FindQuality(((Humanoid)__instance).GetInventory(), baseShield) < 0)
				{
					__result = false;
				}
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
	internal static class PaladinCraftPatch
	{
		public static string BaseName;

		public static int BaseQuality;

		private static readonly FieldRef<InventoryGui, Recipe> CraftRecipe = AccessTools.FieldRefAccess<InventoryGui, Recipe>("m_craftRecipe");

		private static readonly FieldRef<InventoryGui, ItemData> CraftUpgradeItem = AccessTools.FieldRefAccess<InventoryGui, ItemData>("m_craftUpgradeItem");

		private static void Prefix(InventoryGui __instance, Player player)
		{
			BaseName = null;
			if (CraftUpgradeItem.Invoke(__instance) == null)
			{
				SharedData baseShield = BaseShieldRule.GetBaseShield(CraftRecipe.Invoke(__instance));
				if (baseShield != null)
				{
					BaseName = baseShield.m_name;
					BaseQuality = BaseShieldRule.FindQuality(((Humanoid)player).GetInventory(), baseShield);
				}
			}
		}

		private static void Postfix()
		{
			BaseName = null;
		}
	}
	[HarmonyPatch(typeof(Inventory), "RemoveItem", new Type[]
	{
		typeof(string),
		typeof(int),
		typeof(int),
		typeof(bool)
	})]
	internal static class PaladinConsumePatch
	{
		private static void Prefix(string name, ref int itemQuality)
		{
			if (itemQuality < 0 && PaladinCraftPatch.BaseName != null && name == PaladinCraftPatch.BaseName && PaladinCraftPatch.BaseQuality > 0)
			{
				itemQuality = PaladinCraftPatch.BaseQuality;
			}
		}
	}
}