Decompiled source of HereComesTheVein v1.2.0

plugins/HereComesTheVein/HereComesTheVein.dll

Decompiled 2 days 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.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("1.2.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.2.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 HereComesTheVein
{
	[BepInPlugin("r4v9n1.herecomesthevein", "HereComesTheVein", "1.2.0")]
	public sealed class HereComesTheVeinPlugin : BaseUnityPlugin
	{
		internal struct DropScopeState
		{
			internal bool Entered;

			internal DropTable PreviousDropTable;

			internal bool PreviousObsidianVeinBonusPending;
		}

		public const string PluginGuid = "r4v9n1.herecomesthevein";

		public const string PluginName = "HereComesTheVein";

		public const string PluginVersion = "1.2.0";

		internal const float IronOreReplacementChance = 0.2f;

		internal const float ObsidianIronOreReplacementChance = 0.2f;

		internal const string ObsidianVeinPrefabName = "MineRock_Obsidian";

		internal const float ObsidianVeinBonusIronChance = 0.2f;

		internal const int ObsidianVeinBonusIronMin = 1;

		internal const int ObsidianVeinBonusIronMax = 3;

		internal const float SurtlingCoreReplacementChance = 0.01f;

		internal const float CoalReplacementChance = 0.1f;

		internal const float TinOreReplacementChance = 0.05f;

		[ThreadStatic]
		private static DropTable _activeMiningDropTable;

		[ThreadStatic]
		private static bool _activeObsidianVeinBonusPending;

		internal static ManualLogSource ModLog;

		private static GameObject _ironOrePrefab;

		private static GameObject _surtlingCorePrefab;

		private static GameObject _coalPrefab;

		private static bool _warnedMissingCoal;

		private static GameObject _tinOrePrefab;

		private static bool _warnedMissingTinOre;

		private static bool _warnedMissingIronOre;

		private static bool _warnedMissingSurtlingCore;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			ModLog = ((BaseUnityPlugin)this).Logger;
			_harmony = new Harmony("r4v9n1.herecomesthevein");
			_harmony.PatchAll(typeof(HereComesTheVeinPlugin).Assembly);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("HereComesTheVein 1.2.0 loaded. From vanilla rock mining, each CopperOre result has a 20% chance to become IronOre, each Obsidian result from obsidian veins a 20% chance to become IronOre (plus a 20% chance per destroyed obsidian vein of 1-3 bonus IronOre), and each Stone result a 1% chance to become SurtlingCore, 10% Coal or 5% TinOre, one-for-one after Valheim generates the final drop list; runtime=" + (Application.isBatchMode ? "dedicated-server" : "client") + "."));
		}

		private void OnDestroy()
		{
			if (_harmony != null)
			{
				_harmony.UnpatchSelf();
			}
		}

		internal static DropScopeState EnterMiningDropScope(DropTable dropTable, bool obsidianVein = false)
		{
			DropScopeState result = new DropScopeState
			{
				Entered = false,
				PreviousDropTable = _activeMiningDropTable,
				PreviousObsidianVeinBonusPending = _activeObsidianVeinBonusPending
			};
			if (dropTable == null)
			{
				return result;
			}
			_activeMiningDropTable = dropTable;
			_activeObsidianVeinBonusPending = obsidianVein;
			result.Entered = true;
			return result;
		}

		internal static void ExitMiningDropScope(DropScopeState state)
		{
			if (state.Entered)
			{
				_activeMiningDropTable = state.PreviousDropTable;
				_activeObsidianVeinBonusPending = state.PreviousObsidianVeinBonusPending;
			}
		}

		internal static void ConvertMiningDrops(DropTable dropTable, List<GameObject> drops)
		{
			if (dropTable == null || dropTable != _activeMiningDropTable || drops == null)
			{
				return;
			}
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			int num5 = 0;
			for (int i = 0; i < drops.Count; i++)
			{
				GameObject item = drops[i];
				if (IsItem(item, "CopperOre"))
				{
					if (!(Random.value >= 0.2f))
					{
						GameObject val = ResolvePrefab("IronOre", ref _ironOrePrefab, ref _warnedMissingIronOre);
						if ((Object)(object)val != (Object)null)
						{
							drops[i] = val;
							num++;
						}
					}
				}
				else if (IsItem(item, "Obsidian"))
				{
					if (!(Random.value >= 0.2f))
					{
						GameObject val2 = ResolvePrefab("IronOre", ref _ironOrePrefab, ref _warnedMissingIronOre);
						if ((Object)(object)val2 != (Object)null)
						{
							drops[i] = val2;
							num2++;
						}
					}
				}
				else
				{
					if (!IsItem(item, "Stone"))
					{
						continue;
					}
					float value = Random.value;
					if (value < 0.01f)
					{
						GameObject val3 = ResolvePrefab("SurtlingCore", ref _surtlingCorePrefab, ref _warnedMissingSurtlingCore);
						if ((Object)(object)val3 != (Object)null)
						{
							drops[i] = val3;
							num3++;
						}
					}
					else if (value < 0.11f)
					{
						GameObject val4 = ResolvePrefab("Coal", ref _coalPrefab, ref _warnedMissingCoal);
						if ((Object)(object)val4 != (Object)null)
						{
							drops[i] = val4;
							num4++;
						}
					}
					else if (value < 0.16f)
					{
						GameObject val5 = ResolvePrefab("TinOre", ref _tinOrePrefab, ref _warnedMissingTinOre);
						if ((Object)(object)val5 != (Object)null)
						{
							drops[i] = val5;
							num5++;
						}
					}
				}
			}
			int num6 = 0;
			if (_activeObsidianVeinBonusPending)
			{
				_activeObsidianVeinBonusPending = false;
				if (Random.value < 0.2f)
				{
					GameObject val6 = ResolvePrefab("IronOre", ref _ironOrePrefab, ref _warnedMissingIronOre);
					if ((Object)(object)val6 != (Object)null)
					{
						num6 = Random.Range(1, 4);
						for (int j = 0; j < num6; j++)
						{
							drops.Add(val6);
						}
					}
				}
			}
			if (num > 0 || num2 > 0 || num6 > 0 || num3 > 0 || num4 > 0 || num5 > 0)
			{
				ManualLogSource modLog = ModLog;
				if (modLog != null)
				{
					modLog.LogDebug((object)("Substituted " + num + " CopperOre drop(s) with IronOre (20%), " + num2 + " Obsidian drop(s) with IronOre (20%), added " + num6 + " bonus IronOre from an obsidian vein (20% roll), " + num3 + " Stone drop(s) with SurtlingCore (1%), " + num4 + " Stone drop(s) with Coal (10%) and " + num5 + " Stone drop(s) with TinOre (5%)."));
				}
			}
		}

		private static GameObject ResolvePrefab(string prefabName, ref GameObject cached, ref bool warned)
		{
			if ((Object)(object)cached != (Object)null)
			{
				return cached;
			}
			if ((Object)(object)ObjectDB.instance == (Object)null)
			{
				return null;
			}
			cached = ObjectDB.instance.GetItemPrefab(prefabName);
			if ((Object)(object)cached == (Object)null && !warned)
			{
				warned = true;
				ManualLogSource modLog = ModLog;
				if (modLog != null)
				{
					modLog.LogWarning((object)("ObjectDB could not resolve " + prefabName + "; those drops were left unchanged."));
				}
			}
			return cached;
		}

		internal static bool IsItem(GameObject item, string prefabName)
		{
			if ((Object)(object)item == (Object)null)
			{
				return false;
			}
			string text = ((Object)item).name ?? string.Empty;
			if (text.EndsWith("(Clone)", StringComparison.Ordinal))
			{
				text = text.Substring(0, text.Length - "(Clone)".Length);
			}
			return string.Equals(text, prefabName, StringComparison.OrdinalIgnoreCase);
		}
	}
	[HarmonyPatch]
	internal static class CopperDropListPatch
	{
		private static MethodBase TargetMethod()
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(DropTable), "GetDropList", Type.EmptyTypes, (Type[])null);
			if (methodInfo == null || methodInfo.ReturnType != typeof(List<GameObject>))
			{
				throw new MissingMethodException("Current Valheim DropTable.GetDropList() contract was not found.");
			}
			return methodInfo;
		}

		[HarmonyPostfix]
		private static void Postfix(DropTable __instance, List<GameObject> __result)
		{
			HereComesTheVeinPlugin.ConvertMiningDrops(__instance, __result);
		}
	}
	[HarmonyPatch]
	internal static class MineRockDropScopePatch
	{
		private static MethodBase TargetMethod()
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(MineRock), "RPC_Hit", new Type[3]
			{
				typeof(long),
				typeof(HitData),
				typeof(int)
			}, (Type[])null);
			if (methodInfo == null || methodInfo.ReturnType != typeof(void))
			{
				throw new MissingMethodException("Current Valheim MineRock.RPC_Hit(long, HitData, int) contract was not found.");
			}
			return methodInfo;
		}

		private static void Prefix(MineRock __instance, ref HereComesTheVeinPlugin.DropScopeState __state)
		{
			__state = HereComesTheVeinPlugin.EnterMiningDropScope(__instance?.m_dropItems);
		}

		private static Exception Finalizer(Exception __exception, HereComesTheVeinPlugin.DropScopeState __state)
		{
			HereComesTheVeinPlugin.ExitMiningDropScope(__state);
			return __exception;
		}
	}
	[HarmonyPatch]
	internal static class ObsidianVeinDropScopePatch
	{
		private static MethodBase TargetMethod()
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(DropOnDestroyed), "OnDestroyed", Type.EmptyTypes, (Type[])null);
			if (methodInfo == null || methodInfo.ReturnType != typeof(void))
			{
				throw new MissingMethodException("Current Valheim DropOnDestroyed.OnDestroyed() contract was not found.");
			}
			return methodInfo;
		}

		private static void Prefix(DropOnDestroyed __instance, ref HereComesTheVeinPlugin.DropScopeState __state)
		{
			DropTable dropTable = (((Object)(object)__instance != (Object)null && HereComesTheVeinPlugin.IsItem(((Component)__instance).gameObject, "MineRock_Obsidian")) ? __instance.m_dropWhenDestroyed : null);
			__state = HereComesTheVeinPlugin.EnterMiningDropScope(dropTable, obsidianVein: true);
		}

		private static Exception Finalizer(Exception __exception, HereComesTheVeinPlugin.DropScopeState __state)
		{
			HereComesTheVeinPlugin.ExitMiningDropScope(__state);
			return __exception;
		}
	}
	[HarmonyPatch]
	internal static class MineRock5DropScopePatch
	{
		private static MethodBase TargetMethod()
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(MineRock5), "DamageArea", new Type[2]
			{
				typeof(int),
				typeof(HitData)
			}, (Type[])null);
			if (methodInfo == null || methodInfo.ReturnType != typeof(bool))
			{
				throw new MissingMethodException("Current Valheim MineRock5.DamageArea(int, HitData) contract was not found.");
			}
			return methodInfo;
		}

		private static void Prefix(MineRock5 __instance, ref HereComesTheVeinPlugin.DropScopeState __state)
		{
			__state = HereComesTheVeinPlugin.EnterMiningDropScope(__instance?.m_dropItems);
		}

		private static Exception Finalizer(Exception __exception, HereComesTheVeinPlugin.DropScopeState __state)
		{
			HereComesTheVeinPlugin.ExitMiningDropScope(__state);
			return __exception;
		}
	}
}