Decompiled source of VargheimMining v1.1.2

VargheimMining.dll

Decompiled 12 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using VargheimProfessions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.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 VargheimMining
{
	[BepInPlugin("digi.vargheim.mining", "VargheimMining", "1.1.2")]
	[BepInDependency("digi.vargheim.professions", "0.4.0")]
	public class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch]
		internal static class Patches
		{
			[HarmonyPatch(typeof(MineRock5), "DamageArea")]
			[HarmonyPrefix]
			private static void Rock5Pre(HitData hit)
			{
				s_digger = ((hit != null) ? hit.GetAttacker() : null);
			}

			[HarmonyPatch(typeof(MineRock5), "DamageArea")]
			[HarmonyFinalizer]
			private static void Rock5Post()
			{
				s_digger = null;
			}

			[HarmonyPatch(typeof(MineRock), "RPC_Hit")]
			[HarmonyPrefix]
			private static void RockPre(HitData hit)
			{
				s_digger = ((hit != null) ? hit.GetAttacker() : null);
			}

			[HarmonyPatch(typeof(MineRock), "RPC_Hit")]
			[HarmonyFinalizer]
			private static void RockPost()
			{
				s_digger = null;
			}

			[HarmonyPatch(typeof(Destructible), "Destroy")]
			[HarmonyPrefix]
			private static void DestrPre(HitData hit)
			{
				s_digger = ((hit != null) ? hit.GetAttacker() : null);
			}

			[HarmonyPatch(typeof(Destructible), "Destroy")]
			[HarmonyFinalizer]
			private static void DestrPost()
			{
				s_digger = null;
			}

			[HarmonyPatch(typeof(DropTable), "GetDropList", new Type[] { })]
			[HarmonyPostfix]
			private static void Drops(List<GameObject> __result)
			{
				if ((Object)(object)s_digger == (Object)null)
				{
					return;
				}
				try
				{
					BonusOre(__result);
				}
				catch
				{
				}
			}

			[HarmonyPatch(typeof(Attack), "DoMeleeAttack")]
			[HarmonyPrefix]
			private static void MeleePre(Attack __instance, out float __state)
			{
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Invalid comparison between Unknown and I4
				__state = -1f;
				ItemData value = Traverse.Create((object)__instance).Field("m_weapon").GetValue<ItemData>();
				Humanoid value2 = Traverse.Create((object)__instance).Field("m_character").GetValue<Humanoid>();
				if (value != null && (Object)(object)value2 != (Object)null && (Object)(object)value2 == (Object)(object)Player.m_localPlayer && (int)value.m_shared.m_skillType == 12 && Api.HasPerk("Mining", PickLevel.Value))
				{
					__state = value.m_durability;
				}
			}

			[HarmonyPatch(typeof(Attack), "DoMeleeAttack")]
			[HarmonyPostfix]
			private static void MeleePost(Attack __instance, float __state)
			{
				if (!(__state < 0f))
				{
					ItemData value = Traverse.Create((object)__instance).Field("m_weapon").GetValue<ItemData>();
					if (value != null && value.m_durability < __state)
					{
						value.m_durability += (__state - value.m_durability) * PickWear.Value;
					}
				}
			}

			[HarmonyPatch(typeof(Inventory), "UpdateTotalWeight")]
			[HarmonyPostfix]
			private static void Weight(Inventory __instance, ref float ___m_totalWeight)
			{
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null || __instance != ((Humanoid)localPlayer).GetInventory() || !Api.HasPerk("Mining", HaulLevel.Value))
				{
					return;
				}
				float num = 0f;
				foreach (ItemData allItem in __instance.GetAllItems())
				{
					if (allItem != null && (Object)(object)allItem.m_dropPrefab != (Object)null && HaulSet.Contains(((Object)allItem.m_dropPrefab).name))
					{
						num += allItem.GetWeight(-1) * HaulFactor.Value;
					}
				}
				___m_totalWeight = Mathf.Max(0f, ___m_totalWeight - num);
			}
		}

		public const string Guid = "digi.vargheim.mining";

		public const string Version = "1.1.2";

		internal const string Flux = "VP_TemperingFlux";

		internal static ConfigEntry<int> FluxLevel;

		internal static ConfigEntry<int> FluxAmount;

		internal static ConfigEntry<string> FluxRecipe;

		private const string Prof = "Mining";

		internal static ConfigEntry<int> ProspectLevel;

		internal static ConfigEntry<int> RichLevel;

		internal static ConfigEntry<int> PickLevel;

		internal static ConfigEntry<int> HaulLevel;

		internal static ConfigEntry<int> CrewLevel;

		internal static ConfigEntry<int> MotherLevel;

		internal static ConfigEntry<float> ProspectRange;

		internal static ConfigEntry<float> RichChance;

		internal static ConfigEntry<float> PickWear;

		internal static ConfigEntry<float> HaulFactor;

		internal static ConfigEntry<float> CrewRange;

		internal static ConfigEntry<float> CrewChance;

		internal static ConfigEntry<float> MotherChance;

		internal static ConfigEntry<string> Ores;

		internal static ConfigEntry<string> Bars;

		internal static HashSet<string> OreSet = new HashSet<string>(StringComparer.Ordinal);

		internal static HashSet<string> HaulSet = new HashSet<string>(StringComparer.Ordinal);

		internal static Plugin Instance;

		private float _next;

		private readonly Dictionary<int, GameObject> _glows = new Dictionary<int, GameObject>();

		[ThreadStatic]
		internal static Character s_digger;

		private void Awake()
		{
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Expected O, but got Unknown
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Expected O, but got Unknown
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a6: Expected O, but got Unknown
			//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03db: Expected O, but got Unknown
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Expected O, but got Unknown
			//IL_041e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0424: Expected O, but got Unknown
			//IL_047f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0485: Expected O, but got Unknown
			//IL_04af: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b5: Expected O, but got Unknown
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			ProspectLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Perks", "ProspectorLevel", 25, "Prospector: ore deposits near you glow while you hold a pickaxe.");
			ProspectRange = ((BaseUnityPlugin)this).Config.Bind<float>("Perks", "ProspectorRange", 30f, "Prospector range in metres.");
			FluxLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Perks", "TemperingFluxLevel", 35, "Tempering flux: level to make Tempering Flux, which smiths need to upgrade modded weapons and armor.");
			FluxRecipe = ((BaseUnityPlugin)this).Config.Bind<string>("Perks", "TemperingFluxRecipe", "Coal:4,Resin:2,Stone:4", "Materials for Tempering Flux (at a workbench).");
			FluxAmount = ((BaseUnityPlugin)this).Config.Bind<int>("Perks", "TemperingFluxAmount", 4, "Tempering Flux per craft.");
			Content.AddItem("Coal", "VP_TemperingFlux", "Tempering Flux", "Crushed coal and stone bound with resin. Smiths need it to upgrade modded weapons and armor. Only a miner can make it.", (Action<SharedData>)delegate(SharedData s)
			{
				s.m_weight = 0.5f;
				s.m_maxStackSize = 50;
			});
			Content.AddRecipe("VP_TemperingFlux", "piece_workbench", 1, Math.Max(1, FluxAmount.Value), FluxRecipe.Value, "Mining", FluxLevel.Value);
			RichLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Perks", "RichVeinLevel", 35, "Rich vein level.");
			RichChance = ((BaseUnityPlugin)this).Config.Bind<float>("Perks", "RichVeinChance", 0.15f, "Rich vein: chance of one extra ore per ore drop.");
			PickLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Perks", "ToughPickLevel", 45, "Tough pick level.");
			PickWear = ((BaseUnityPlugin)this).Config.Bind<float>("Perks", "ToughPickWearReduction", 0.3f, "Tough pick: pickaxe wear reduced by this much (0.3 = 30% less).");
			HaulLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Perks", "OreHaulerLevel", 60, "Ore hauler level.");
			HaulFactor = ((BaseUnityPlugin)this).Config.Bind<float>("Perks", "OreHaulerWeightReduction", 0.25f, "Ore hauler: ore and bars weigh this much less in the miner's inventory.");
			CrewLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Perks", "CrewBossLevel", 75, "Crew boss level.");
			CrewRange = ((BaseUnityPlugin)this).Config.Bind<float>("Perks", "CrewBossRange", 15f, "Crew boss: group members within this range get the bonus.");
			CrewChance = ((BaseUnityPlugin)this).Config.Bind<float>("Perks", "CrewBossChance", 0.25f, "Crew boss: chance of one extra ore per ore drop for group members near a crew boss.");
			MotherLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Perks", "MotherlodeLevel", 100, "Motherlode level.");
			MotherChance = ((BaseUnityPlugin)this).Config.Bind<float>("Perks", "MotherlodeChance", 0.25f, "Motherlode: chance that a piece of a deposit you break drops double ore.");
			Ores = ((BaseUnityPlugin)this).Config.Bind<string>("Perks", "OreItems", "CopperOre,TinOre,IronScrap,IronOre,SilverOre,BlackMetalScrap,FlametalOre,FlametalOreNew,CopperScrap,Obsidian", "Items that count as ore for these perks.");
			Bars = ((BaseUnityPlugin)this).Config.Bind<string>("Perks", "HaulItems", "Copper,Tin,Bronze,Iron,Silver,BlackMetal,Flametal,FlametalNew,CopperOre,TinOre,IronScrap,IronOre,SilverOre,BlackMetalScrap,FlametalOre,FlametalOreNew,CopperScrap", "Items made lighter by Ore hauler.");
			Load();
			((BaseUnityPlugin)this).Config.SettingChanged += delegate
			{
				Load();
			};
			Api.RegisterLadder("Mining", "VargheimMining 1.1.2", "Smoothbrain Mining: up to x3 damage and x2 yield at 100; deposits can break apart from level 50.", (Perk[])(object)new Perk[8]
			{
				new Perk(ProspectLevel.Value, "Prospector", "With a pickaxe in hand, ore deposits within " + ProspectRange.Value + " m glow faintly."),
				new Perk(10, "Tier flux", "Make the Miner's tier material at a workbench, one per biome from that biome's ore and coal (Flint Grit at 10, Copper Flux at 25, Bog Iron Flux at 35 ...). Smiths need it for every modded weapon, shield and metal armor of that tier, plus 1 per upgrade."),
				new Perk(RichLevel.Value, "Rich vein", Pct(RichChance.Value) + " chance of one extra ore per piece mined."),
				new Perk(PickLevel.Value, "Tough pick", "Pickaxe wear " + Pct(PickWear.Value) + " lower."),
				new Perk(50, "Break apart", "Deposits can break apart in one go (Smoothbrain Mining)."),
				new Perk(HaulLevel.Value, "Ore hauler", "Ore and bars weigh " + Pct(HaulFactor.Value) + " less in your inventory."),
				new Perk(CrewLevel.Value, "Crew boss", "Group members mining within " + CrewRange.Value + " m of you get " + Pct(CrewChance.Value) + " more ore."),
				new Perk(MotherLevel.Value, "Motherlode", Pct(MotherChance.Value) + " chance a piece of a deposit you break drops double ore.")
			});
			new Harmony("digi.vargheim.mining").PatchAll(typeof(Patches));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"VargheimMining 1.1.2 loaded.");
		}

		internal static string Pct(float f)
		{
			return Mathf.RoundToInt(f * 100f) + "%";
		}

		private static void Load()
		{
			OreSet = new HashSet<string>(Ores.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries), StringComparer.Ordinal);
			HaulSet = new HashSet<string>(Bars.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries), StringComparer.Ordinal);
		}

		private void Update()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || Time.time < _next)
			{
				return;
			}
			_next = Time.time + 1.5f;
			try
			{
				PublishCrew(localPlayer);
				Prospect(localPlayer);
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)ex.Message);
			}
		}

		private static void PublishCrew(Player p)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			ZNetView component = ((Component)p).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner())
			{
				return;
			}
			int num = 0;
			foreach (Player item in Api.GroupMembersNear(((Component)p).transform.position, CrewRange.Value))
			{
				if (Api.PerkLevelOf(item, "Mining") >= CrewLevel.Value)
				{
					num = 1;
					break;
				}
			}
			if (component.GetZDO().GetInt("vp_mine_crew", 0) != num)
			{
				component.GetZDO().Set("vp_mine_crew", num);
			}
		}

		internal static bool HoldingPickaxe(Player p)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			ItemData currentWeapon = ((Humanoid)p).GetCurrentWeapon();
			if (currentWeapon != null && currentWeapon.m_shared != null)
			{
				return (int)currentWeapon.m_shared.m_skillType == 12;
			}
			return false;
		}

		private static bool HasOre(DropTable t)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if (t == null || t.m_drops == null)
			{
				return false;
			}
			foreach (DropData drop in t.m_drops)
			{
				if ((Object)(object)drop.m_item != (Object)null && OreSet.Contains(((Object)drop.m_item).name))
				{
					return true;
				}
			}
			return false;
		}

		private void Prospect(Player p)
		{
			//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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: 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)
			bool num = Api.HasPerk("Mining", ProspectLevel.Value) && HoldingPickaxe(p);
			List<int> list = new List<int>();
			if (!num)
			{
				foreach (KeyValuePair<int, GameObject> glow in _glows)
				{
					if ((Object)(object)glow.Value != (Object)null)
					{
						Object.Destroy((Object)(object)glow.Value);
					}
				}
				_glows.Clear();
				return;
			}
			Vector3 position = ((Component)p).transform.position;
			float value = ProspectRange.Value;
			HashSet<int> hashSet = new HashSet<int>();
			HashSet<int> hashSet2 = new HashSet<int>();
			Collider[] array = Physics.OverlapSphere(position, value, -1, (QueryTriggerInteraction)2);
			foreach (Collider val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				MineRock5 componentInParent = ((Component)val).GetComponentInParent<MineRock5>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					if (hashSet2.Add(((Object)componentInParent).GetInstanceID()))
					{
						Glow((Component)(object)componentInParent, HasOre(componentInParent.m_dropItems), position, value, hashSet);
					}
					continue;
				}
				MineRock componentInParent2 = ((Component)val).GetComponentInParent<MineRock>();
				if ((Object)(object)componentInParent2 != (Object)null)
				{
					if (hashSet2.Add(((Object)componentInParent2).GetInstanceID()))
					{
						Glow((Component)(object)componentInParent2, HasOre(componentInParent2.m_dropItems), position, value, hashSet);
					}
					continue;
				}
				DropOnDestroyed componentInParent3 = ((Component)val).GetComponentInParent<DropOnDestroyed>();
				if ((Object)(object)componentInParent3 != (Object)null && hashSet2.Add(((Object)componentInParent3).GetInstanceID()) && (Object)(object)((Component)componentInParent3).GetComponent<Destructible>() != (Object)null)
				{
					Glow((Component)(object)componentInParent3, HasOre(componentInParent3.m_dropWhenDestroyed), position, value, hashSet);
				}
			}
			foreach (KeyValuePair<int, GameObject> glow2 in _glows)
			{
				if (!hashSet.Contains(glow2.Key))
				{
					list.Add(glow2.Key);
				}
			}
			foreach (int item in list)
			{
				if ((Object)(object)_glows[item] != (Object)null)
				{
					Object.Destroy((Object)(object)_glows[item]);
				}
				_glows.Remove(item);
			}
		}

		private void Glow(Component c, bool ore, Vector3 me, float r, HashSet<int> seen)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//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_009d: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			if (!ore || (Object)(object)c == (Object)null)
			{
				return;
			}
			Vector3 val = c.transform.position;
			Collider componentInChildren = c.GetComponentInChildren<Collider>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				Bounds bounds = componentInChildren.bounds;
				val = ((Bounds)(ref bounds)).center;
			}
			if (!(Vector3.Distance(val, me) > r))
			{
				int instanceID = ((Object)c).GetInstanceID();
				seen.Add(instanceID);
				if (!_glows.TryGetValue(instanceID, out var value) || !((Object)(object)value != (Object)null))
				{
					value = new GameObject("VargheimProspectorGlow");
					value.transform.SetParent(c.transform, false);
					value.transform.position = val + Vector3.up * 1.5f;
					Light obj = value.AddComponent<Light>();
					obj.type = (LightType)2;
					obj.color = new Color(1f, 0.62f, 0.25f);
					obj.range = 5f;
					obj.intensity = 1.6f;
					obj.shadows = (LightShadows)0;
					_glows[instanceID] = value;
				}
			}
		}

		internal static void BonusOre(List<GameObject> drops)
		{
			Character obj = s_digger;
			Player val = (Player)(object)((obj is Player) ? obj : null);
			if ((Object)(object)val == (Object)null || drops == null || drops.Count == 0)
			{
				return;
			}
			int num = Api.PerkLevelOf(val, "Mining");
			ZNetView component = ((Component)val).GetComponent<ZNetView>();
			bool flag = (Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().GetInt("vp_mine_crew", 0) == 1;
			bool flag2 = num >= MotherLevel.Value && Random.value < MotherChance.Value;
			List<GameObject> list = new List<GameObject>();
			foreach (GameObject drop in drops)
			{
				if (!((Object)(object)drop == (Object)null) && OreSet.Contains(((Object)drop).name))
				{
					if (num >= RichLevel.Value && Random.value < RichChance.Value)
					{
						list.Add(drop);
					}
					if (flag && Random.value < CrewChance.Value)
					{
						list.Add(drop);
					}
					if (flag2)
					{
						list.Add(drop);
					}
				}
			}
			drops.AddRange(list);
		}
	}
}