Decompiled source of GreydwarfWand v1.0.2

BepInEx/plugins/L4zerShark_Team-GreydwarfWand/GreydwarfWand.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
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.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Greydwarf Wand")]
[assembly: AssemblyDescription("Early-game stamina-powered wand for Valheim")]
[assembly: AssemblyCompany("GreydwarfWand Contributors")]
[assembly: AssemblyProduct("GreydwarfWand")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.2.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 GreydwarfWand
{
	[BepInPlugin("org.valheimmods.greydwarfwand", "GreydwarfWand", "1.0.2")]
	[BepInDependency("com.jotunn.jotunn", "2.30.0")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class GreydwarfWandPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "org.valheimmods.greydwarfwand";

		public const string PluginName = "GreydwarfWand";

		public const string PluginVersion = "1.0.2";

		private bool refreshPending;

		internal static ManualLogSource Log { get; private set; }

		internal static WandSettings Settings { get; private set; }

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			Settings = new WandSettings(((BaseUnityPlugin)this).Config);
			((BaseUnityPlugin)this).Config.SettingChanged += OnSettingChanged;
			PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabsAvailable;
			ItemManager.OnItemsRegistered += QueueRefresh;
			SynchronizationManager.OnConfigurationSynchronized += OnSynchronized;
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.SettingChanged -= OnSettingChanged;
			PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailable;
			ItemManager.OnItemsRegistered -= QueueRefresh;
			SynchronizationManager.OnConfigurationSynchronized -= OnSynchronized;
		}

		private void OnSettingChanged(object sender, SettingChangedEventArgs args)
		{
			if ((object)args.ChangedSetting != Settings.ModelScale && (object)args.ChangedSetting != Settings.TintProjectileCyan)
			{
				QueueRefresh();
			}
		}

		private void OnSynchronized(object sender, ConfigurationSynchronizationEventArgs args)
		{
			QueueRefresh();
		}

		private void QueueRefresh()
		{
			refreshPending = true;
		}

		private void LateUpdate()
		{
			if (!refreshPending || !WandFactory.Ready)
			{
				return;
			}
			refreshPending = false;
			try
			{
				WandFactory.Refresh();
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Could not apply wand settings: " + ex));
			}
		}

		private void OnVanillaPrefabsAvailable()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailable;
			try
			{
				WandFactory.Create();
				QueueRefresh();
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Greydwarf Wand is unavailable: " + ex.Message));
			}
		}
	}
	internal static class VisualUtils
	{
		private static readonly Color Wisplight = new Color(0.35f, 0.85f, 1f, 1f);

		internal static void ScaleModel(GameObject itemPrefab, float scale)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_00d4: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			if ((Object)(object)itemPrefab == (Object)null || Mathf.Approximately(scale, 1f))
			{
				return;
			}
			try
			{
				List<Transform> list = new List<Transform>();
				foreach (Transform item2 in itemPrefab.transform)
				{
					Transform val = item2;
					if (((Object)val).name.StartsWith("attach", StringComparison.OrdinalIgnoreCase))
					{
						list.Add(val);
					}
				}
				if (list.Count == 0)
				{
					foreach (Transform item3 in itemPrefab.transform)
					{
						Transform item = item3;
						list.Add(item);
					}
					GreydwarfWandPlugin.Log.LogWarning((object)"No 'attach' transform on the staff prefab; scaling all child transforms instead.");
				}
				foreach (Transform item4 in list)
				{
					item4.localScale *= scale;
				}
				GreydwarfWandPlugin.Log.LogInfo((object)$"Scaled the wand model to {scale:0.##}x across {list.Count} transform(s).");
			}
			catch (Exception ex)
			{
				GreydwarfWandPlugin.Log.LogWarning((object)("Could not scale the wand model: " + ex.Message));
			}
		}

		internal static void TintCyan(GameObject projectile)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)projectile == (Object)null)
			{
				return;
			}
			try
			{
				ParticleSystem[] componentsInChildren = projectile.GetComponentsInChildren<ParticleSystem>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					TintParticles(componentsInChildren[i]);
				}
				Light[] componentsInChildren2 = projectile.GetComponentsInChildren<Light>(true);
				for (int i = 0; i < componentsInChildren2.Length; i++)
				{
					componentsInChildren2[i].color = Wisplight;
				}
				TrailRenderer[] componentsInChildren3 = projectile.GetComponentsInChildren<TrailRenderer>(true);
				foreach (TrailRenderer obj in componentsInChildren3)
				{
					obj.startColor = WithAlphaOf(obj.startColor);
					obj.endColor = WithAlphaOf(obj.endColor);
				}
				LineRenderer[] componentsInChildren4 = projectile.GetComponentsInChildren<LineRenderer>(true);
				foreach (LineRenderer obj2 in componentsInChildren4)
				{
					obj2.startColor = WithAlphaOf(obj2.startColor);
					obj2.endColor = WithAlphaOf(obj2.endColor);
				}
			}
			catch (Exception ex)
			{
				GreydwarfWandPlugin.Log.LogWarning((object)("Could not tint the bolt: " + ex.Message));
			}
		}

		private static void TintParticles(ParticleSystem particles)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				MainModule main = particles.main;
				((MainModule)(ref main)).startColor = new MinMaxGradient(Wisplight);
			}
			catch (Exception)
			{
			}
		}

		private static Color WithAlphaOf(Color original)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			return new Color(Wisplight.r, Wisplight.g, Wisplight.b, original.a);
		}
	}
	internal static class WandFactory
	{
		internal const string WandPrefabName = "WisplightWand";

		internal const string BoltPrefabName = "wisplight_bolt";

		internal const string NameToken = "$item_greydwarfwand";

		internal const string DescriptionToken = "$item_greydwarfwand_description";

		private static CustomItem item;

		private static GameObject bolt;

		private static ItemType staffItemType;

		internal static bool Ready { get; private set; }

		internal static void Create()
		{
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Expected O, but got Unknown
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Expected O, but got Unknown
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Expected O, but got Unknown
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Expected O, but got Unknown
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Expected O, but got Unknown
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Expected O, but got Unknown
			if (Ready)
			{
				return;
			}
			PrefabManager manager = PrefabManager.Instance;
			ItemDrop component = RequirePrefab("StaffIceShards").GetComponent<ItemDrop>();
			ItemDrop component2 = RequirePrefab("StaffFireball").GetComponent<ItemDrop>();
			if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component2) || (Object)(object)component.m_itemData.m_shared.m_attack?.m_attackProjectile == (Object)null || component2.m_itemData.m_shared.m_attack == null)
			{
				throw new InvalidOperationException("Vanilla staff casting data is missing. Check Valheim and Jotunn compatibility.");
			}
			if (Object.op_Implicit((Object)(object)manager.GetPrefab("WisplightWand")) || Object.op_Implicit((Object)(object)manager.GetPrefab("wisplight_bolt")))
			{
				throw new InvalidOperationException("Wand prefab names are already registered. Remove the old WisplightWand DLL and duplicate installations.");
			}
			bool boltRegistered = false;
			bool itemAttempted = false;
			try
			{
				ItemConfig val = BuildItemConfig();
				item = new CustomItem("WisplightWand", "StaffIceShards", val);
				if ((Object)(object)item.ItemPrefab == (Object)null || (Object)(object)item.ItemDrop == (Object)null)
				{
					throw new InvalidOperationException("Could not clone the wand item.");
				}
				SharedData val2 = (SharedData)typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(component.m_itemData.m_shared, null);
				item.ItemDrop.m_itemData.m_shared = val2;
				staffItemType = val2.m_itemType;
				val2.m_attack = component2.m_itemData.m_shared.m_attack.Clone();
				val2.m_secondaryAttack = new Attack();
				val2.m_attack.m_startEffect = new EffectList();
				val2.m_attack.m_triggerEffect = new EffectList();
				val2.m_attack.m_burstEffect = new EffectList();
				bolt = manager.CreateClonedPrefab("wisplight_bolt", component.m_itemData.m_shared.m_attack.m_attackProjectile);
				if (!Object.op_Implicit((Object)(object)bolt) || !Object.op_Implicit((Object)(object)bolt.GetComponent<Projectile>()) || !Object.op_Implicit((Object)(object)bolt.GetComponent<ZNetView>()))
				{
					throw new InvalidOperationException("Could not create a networked frost bolt. Registration stopped.");
				}
				val2.m_attack.m_attackProjectile = bolt;
				ApplyGameplay();
				VisualUtils.ScaleModel(item.ItemPrefab, GreydwarfWandPlugin.Settings.ModelScale.Value);
				if (GreydwarfWandPlugin.Settings.TintProjectileCyan.Value)
				{
					VisualUtils.TintCyan(bolt);
				}
				ApplyIcon(item.ItemDrop);
				CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
				string text = "English";
				localization.AddTranslation(ref text, new Dictionary<string, string>
				{
					{
						"$item_greydwarfwand".TrimStart('$'),
						"Greydwarf Wand"
					},
					{
						"$item_greydwarfwand_description".TrimStart('$'),
						"Fine wood, an ancient seed, and a greydwarf's eye. A cold blue spark answers your aim, powered by stamina instead of Eitr."
					}
				});
				manager.AddPrefab(bolt);
				if ((Object)(object)manager.GetPrefab("wisplight_bolt") != (Object)(object)bolt)
				{
					throw new InvalidOperationException("Jotunn rejected the bolt prefab.");
				}
				boltRegistered = true;
				itemAttempted = true;
				if (!ItemManager.Instance.AddItem(item))
				{
					throw new InvalidOperationException("Jotunn rejected the wand item.");
				}
				manager.RegisterToZNetScene(bolt);
				Ready = true;
				GreydwarfWandPlugin.Log.LogInfo((object)"Greydwarf Wand registered: one cyan bolt per cast, stamina powered, quality 1–3.");
			}
			catch (Exception ex)
			{
				GreydwarfWandPlugin.Log.LogError((object)("Wand registration failed: " + ex));
				Cleanup(delegate
				{
					if (itemAttempted)
					{
						ItemManager.Instance.RemoveItem(item);
					}
				});
				Cleanup(delegate
				{
					if (boltRegistered)
					{
						manager.RemovePrefab("wisplight_bolt");
					}
				});
				Cleanup(delegate
				{
					CustomItem obj = item;
					if (Object.op_Implicit((Object)(object)((obj != null) ? obj.ItemPrefab : null)))
					{
						Object.Destroy((Object)(object)item.ItemPrefab);
					}
				});
				Cleanup(delegate
				{
					if (Object.op_Implicit((Object)(object)bolt))
					{
						Object.Destroy((Object)(object)bolt);
					}
				});
				item = null;
				bolt = null;
				throw;
			}
		}

		private static void Cleanup(Action action)
		{
			try
			{
				action();
			}
			catch (Exception ex)
			{
				GreydwarfWandPlugin.Log.LogError((object)("Wand cleanup also failed: " + ex));
			}
		}

		private static GameObject RequirePrefab(string name)
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab(name);
			if (!Object.op_Implicit((Object)(object)prefab))
			{
				throw new InvalidOperationException("Required vanilla prefab is missing: " + name);
			}
			return prefab;
		}

		private static ItemConfig BuildItemConfig()
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Expected O, but got Unknown
			WandSettings settings = GreydwarfWandPlugin.Settings;
			string text = settings.CraftingStation.Value.Trim();
			if (text.Length > 0 && !Object.op_Implicit((Object)(object)RequirePrefab(text).GetComponent<CraftingStation>()))
			{
				throw new InvalidOperationException("Configured prefab is not a crafting station: " + text);
			}
			List<RequirementConfig> list = new List<RequirementConfig>();
			AddRequirement(list, "FineWood", settings.FineWoodAmount.Value);
			AddRequirement(list, "RoundLog", settings.CoreWoodAmount.Value);
			AddRequirement(list, "GreydwarfEye", settings.GreydwarfEyeAmount.Value);
			AddRequirement(list, "AncientSeed", settings.AncientSeedAmount.Value);
			return new ItemConfig
			{
				Name = "$item_greydwarfwand",
				Description = "$item_greydwarfwand_description",
				Amount = 1,
				CraftingStation = text,
				RepairStation = text,
				MinStationLevel = settings.MinStationLevel.Value,
				Requirements = list.ToArray()
			};
		}

		private static void AddRequirement(List<RequirementConfig> list, string name, int amount)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)RequirePrefab(name).GetComponent<ItemDrop>()))
			{
				throw new InvalidOperationException("Recipe material has no ItemDrop: " + name);
			}
			list.Add(new RequirementConfig(name, amount, amount, true));
		}

		internal static void Refresh()
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			if (Ready)
			{
				ApplyGameplay();
				Recipe recipe = item.Recipe.Recipe;
				ItemConfig val = BuildItemConfig();
				recipe.m_repairStation = (recipe.m_craftingStation = (string.IsNullOrEmpty(val.CraftingStation) ? null : RequirePrefab(val.CraftingStation).GetComponent<CraftingStation>()));
				recipe.m_minStationLevel = val.MinStationLevel;
				List<Requirement> list = new List<Requirement>();
				RequirementConfig[] requirements = val.Requirements;
				foreach (RequirementConfig val2 in requirements)
				{
					list.Add(new Requirement
					{
						m_resItem = RequirePrefab(val2.Item).GetComponent<ItemDrop>(),
						m_amount = val2.Amount,
						m_amountPerLevel = val2.AmountPerLevel,
						m_recover = true
					});
				}
				recipe.m_resources = list.ToArray();
			}
		}

		private static void ApplyGameplay()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			WandSettings settings = GreydwarfWandPlugin.Settings;
			SharedData shared = item.ItemDrop.m_itemData.m_shared;
			shared.m_name = "$item_greydwarfwand";
			shared.m_description = "$item_greydwarfwand_description";
			shared.m_skillType = (SkillType)9;
			shared.m_itemType = (ItemType)(settings.OneHandedEquip.Value ? 3 : ((int)staffItemType));
			shared.m_damages = new DamageTypes
			{
				m_damage = settings.BaseDamage.Value,
				m_frost = settings.FrostDamage.Value,
				m_spirit = settings.SpiritDamage.Value
			};
			shared.m_damagesPerLevel = new DamageTypes
			{
				m_frost = settings.DamagePerLevel.Value
			};
			shared.m_attackForce = settings.Knockback.Value;
			shared.m_attackStatusEffect = null;
			shared.m_spawnOnHit = null;
			shared.m_spawnOnHitTerrain = null;
			shared.m_ammoType = "";
			shared.m_weight = 1f;
			shared.m_value = 20;
			shared.m_maxStackSize = 1;
			shared.m_maxQuality = 3;
			shared.m_useDurability = false;
			shared.m_canBeReparied = true;
			shared.m_teleportable = true;
			ConfigureAttack(shared.m_attack);
			TuneProjectile(bolt.GetComponent<Projectile>());
		}

		internal static void ConfigureAttack(Attack attack)
		{
			WandSettings settings = GreydwarfWandPlugin.Settings;
			attack.m_attackStamina = settings.StaminaPerCast.Value;
			attack.m_attackEitr = settings.EitrPerCast.Value;
			attack.m_attackHealth = 0f;
			attack.m_attackHealthPercentage = 0f;
			attack.m_attackKillsSelf = false;
			attack.m_drawStaminaDrain = (attack.m_drawEitrDrain = 0f);
			attack.m_reloadStaminaDrain = (attack.m_reloadEitrDrain = 0f);
			attack.m_requiresReload = (attack.m_bowDraw = (attack.m_consumeItem = false));
			attack.m_loopingAttack = false;
			attack.m_projectiles = (attack.m_projectileBursts = 1);
			attack.m_burstInterval = 0f;
			attack.m_perBurstResourceUsage = true;
			attack.m_projectileAccuracy = (attack.m_projectileAccuracyMin = 0f);
			attack.m_skillAccuracy = (attack.m_randomVelocity = false);
			attack.m_projectileVel = (attack.m_projectileVelMin = settings.ProjectileSpeed.Value);
			attack.m_useCharacterFacing = (attack.m_useCharacterFacingYAim = false);
			attack.m_launchAngle = 0f;
			attack.m_spawnOnHit = (attack.m_spawnOnTrigger = null);
			attack.m_damageMultiplier = 1f;
			attack.m_damageMultiplierPerMissingHP = 0f;
			attack.m_damageMultiplierByTotalHealthMissing = 0f;
		}

		internal static void TuneProjectile(Projectile projectile)
		{
			WandSettings settings = GreydwarfWandPlugin.Settings;
			projectile.m_gravity = (projectile.m_drag = 0f);
			projectile.m_ttl = settings.AttackRange.Value / settings.ProjectileSpeed.Value;
			projectile.m_aoe = 0f;
			projectile.m_spawnOnHit = null;
			projectile.m_randomSpawnOnHit = new List<GameObject>();
			projectile.m_spawnOnTtl = (projectile.m_respawnItemOnHit = false);
			projectile.m_onlySpawnedProjectilesDealDamage = false;
			projectile.m_hitMidFlight = (projectile.m_onlyStopOnTerrain = false);
			projectile.m_bounce = (projectile.m_bounceOnWater = false);
			projectile.m_stayAfterHitStatic = (projectile.m_stayAfterHitDynamic = false);
			projectile.m_statusEffect = "";
		}

		private static void ApplyIcon(ItemDrop drop)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			if ((int)SystemInfo.graphicsDeviceType == 4)
			{
				return;
			}
			try
			{
				string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? "", "greydwarfwand_icon.png");
				Sprite val;
				if (File.Exists(text))
				{
					val = AssetUtils.LoadSpriteFromFile(text);
				}
				else
				{
					using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("GreydwarfWand.icon.png");
					using MemoryStream memoryStream = new MemoryStream();
					stream.CopyTo(memoryStream);
					Texture2D val2 = new Texture2D(2, 2);
					if (!ImageConversion.LoadImage(val2, memoryStream.ToArray()))
					{
						throw new InvalidDataException("Invalid embedded icon.");
					}
					val = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f));
				}
				if (Object.op_Implicit((Object)(object)val))
				{
					drop.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { val };
				}
			}
			catch (Exception ex)
			{
				GreydwarfWandPlugin.Log.LogWarning((object)("Using vanilla inventory icon: " + ex.Message));
			}
		}
	}
	internal class WandSettings
	{
		private static readonly ConfigurationManagerAttributes Synced = new ConfigurationManagerAttributes
		{
			IsAdminOnly = true
		};

		public ConfigEntry<string> CraftingStation { get; }

		public ConfigEntry<int> MinStationLevel { get; }

		public ConfigEntry<int> FineWoodAmount { get; }

		public ConfigEntry<int> CoreWoodAmount { get; }

		public ConfigEntry<int> GreydwarfEyeAmount { get; }

		public ConfigEntry<int> AncientSeedAmount { get; }

		public ConfigEntry<float> StaminaPerCast { get; }

		public ConfigEntry<float> EitrPerCast { get; }

		public ConfigEntry<float> ProjectileSpeed { get; }

		public ConfigEntry<float> AttackRange { get; }

		public ConfigEntry<float> BaseDamage { get; }

		public ConfigEntry<float> FrostDamage { get; }

		public ConfigEntry<float> SpiritDamage { get; }

		public ConfigEntry<float> DamagePerLevel { get; }

		public ConfigEntry<float> Knockback { get; }

		public ConfigEntry<float> ModelScale { get; }

		public ConfigEntry<bool> OneHandedEquip { get; }

		public ConfigEntry<bool> TintProjectileCyan { get; }

		public WandSettings(ConfigFile config)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Expected O, but got Unknown
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Expected O, but got Unknown
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Expected O, but got Unknown
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Expected O, but got Unknown
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Expected O, but got Unknown
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Expected O, but got Unknown
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Expected O, but got Unknown
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Expected O, but got Unknown
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Expected O, but got Unknown
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Expected O, but got Unknown
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Expected O, but got Unknown
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d2: Expected O, but got Unknown
			//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0402: Expected O, but got Unknown
			CraftingStation = config.Bind<string>("1 - Crafting", "CraftingStation", "piece_workbench", new ConfigDescription("Prefab name of the crafting station. Empty allows crafting by hand.", (AcceptableValueBase)null, new object[1] { Synced }));
			MinStationLevel = config.Bind<int>("1 - Crafting", "MinStationLevel", 1, new ConfigDescription("Crafting station level required.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 5), new object[1] { Synced }));
			FineWoodAmount = config.Bind<int>("1 - Crafting", "FineWoodAmount", 1, new ConfigDescription("Fine wood required.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { Synced }));
			CoreWoodAmount = config.Bind<int>("1 - Crafting", "CoreWoodAmount", 1, new ConfigDescription("Core wood required.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { Synced }));
			GreydwarfEyeAmount = config.Bind<int>("1 - Crafting", "GreydwarfEyeAmount", 1, new ConfigDescription("Greydwarf eyes required.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { Synced }));
			AncientSeedAmount = config.Bind<int>("1 - Crafting", "AncientSeedAmount", 1, new ConfigDescription("Ancient seeds required.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { Synced }));
			StaminaPerCast = config.Bind<float>("2 - Casting", "StaminaPerCast", 12f, new ConfigDescription("Stamina drained per bolt.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), new object[1] { Synced }));
			EitrPerCast = config.Bind<float>("2 - Casting", "EitrPerCast", 0f, new ConfigDescription("Eitr drained per bolt. Left at 0 so the wand works before Mistlands. Raise it if you would rather the wand behaved like a vanilla staff.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), new object[1] { Synced }));
			ProjectileSpeed = config.Bind<float>("2 - Casting", "ProjectileSpeed", 45f, new ConfigDescription("Speed of the bolt in metres per second.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 200f), new object[1] { Synced }));
			AttackRange = config.Bind<float>("2 - Casting", "AttackRange", 60f, new ConfigDescription("How far the bolt travels before fizzling out.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 300f), new object[1] { Synced }));
			BaseDamage = config.Bind<float>("3 - Damage", "BaseDamage", 8f, new ConfigDescription("Raw (unresisted) damage per bolt.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 500f), new object[1] { Synced }));
			FrostDamage = config.Bind<float>("3 - Damage", "FrostDamage", 10f, new ConfigDescription("Frost damage per bolt.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 500f), new object[1] { Synced }));
			SpiritDamage = config.Bind<float>("3 - Damage", "SpiritDamage", 0f, new ConfigDescription("Spirit damage per bolt. Effective against the undead.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 500f), new object[1] { Synced }));
			DamagePerLevel = config.Bind<float>("3 - Damage", "DamagePerLevel", 3f, new ConfigDescription("Extra frost damage gained per upgrade level.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[1] { Synced }));
			Knockback = config.Bind<float>("3 - Damage", "Knockback", 15f, new ConfigDescription("Force applied to whatever the bolt hits.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), new object[1] { Synced }));
			ModelScale = config.Bind<float>("4 - Appearance", "ModelScale", 0.5f, new ConfigDescription("Restart required. Size of the wand model relative to the vanilla staff it is built from. 0.5 reads as a hand-held wand rather than a two-handed staff.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), Array.Empty<object>()));
			OneHandedEquip = config.Bind<bool>("4 - Appearance", "OneHandedEquip", false, new ConfigDescription("EXPERIMENTAL. Equip the wand as a true one-handed weapon so a shield can be used alongside it. Valheim's casting animations are authored for the left-hand staff slot, so the wand may sit in the wrong hand or animate oddly. Off by default: the wand still occupies the staff slot but is drawn at wand size. Re-equip after changing.", (AcceptableValueBase)null, new object[1] { Synced }));
			TintProjectileCyan = config.Bind<bool>("4 - Appearance", "TintProjectileCyan", true, "Restart required. Push the bolt's particles, trail and light toward cyan. Turn off to keep the unaltered ice-shard colouring.");
		}
	}
}