Decompiled source of DeepNorthOutputMultiplier v1.0.1

DeepNorthOutputMultiplier.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Utils;
using UnityEngine;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace DeepNorthOutput;

[BepInPlugin("made.deepnorth.outputmultiplier", "DeepNorthOutputMultiplier", "1.0.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
[SynchronizationMode(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
	public const string Guid = "made.deepnorth.outputmultiplier";

	public const string Name = "DeepNorthOutputMultiplier";

	public const string Version = "1.0.1";

	internal static Plugin Instance;

	internal static ConfigEntry<bool> Enabled;

	internal static ConfigEntry<int> Smelter;

	internal static ConfigEntry<int> BlastFurnace;

	internal static ConfigEntry<int> CharcoalKiln;

	internal static ConfigEntry<int> Windmill;

	internal static ConfigEntry<int> SpinningWheel;

	internal static ConfigEntry<int> EitrRefinery;

	internal static ConfigEntry<int> OtherSmelters;

	internal static ConfigEntry<int> CookingStation;

	internal static ConfigEntry<int> IronCookingStation;

	internal static ConfigEntry<int> Oven;

	internal static ConfigEntry<int> OtherCooking;

	internal static ConfigEntry<int> Fermenter;

	internal static ConfigEntry<bool> MultiplyBurnt;

	private static readonly HashSet<string> seen = new HashSet<string>();

	private ConfigEntry<int> Mult(string section, string key, int def, string desc)
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Expected O, but got Unknown
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Expected O, but got Unknown
		ConfigFile config = ((BaseUnityPlugin)this).Config;
		string text = desc + " 1 = vanilla.";
		AcceptableValueRange<int> obj = new AcceptableValueRange<int>(1, 20);
		object[] array = new object[1];
		ConfigurationManagerAttributes val = new ConfigurationManagerAttributes();
		val.IsAdminOnly = true;
		array[0] = val;
		return config.Bind<int>(section, key, def, new ConfigDescription(text, (AcceptableValueBase)(object)obj, array));
	}

	private void Awake()
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Expected O, but got Unknown
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Expected O, but got Unknown
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: 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_01c9: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		ConfigFile config = ((BaseUnityPlugin)this).Config;
		object[] array = new object[1];
		ConfigurationManagerAttributes val = new ConfigurationManagerAttributes();
		val.IsAdminOnly = true;
		array[0] = val;
		Enabled = config.Bind<bool>("0 - General", "Enabled", true, new ConfigDescription("Turn the whole mod on or off.", (AcceptableValueBase)null, array));
		Smelter = Mult("1 - Smelting", "Smelter", 5, "Bars per ore in the Smelter.");
		BlastFurnace = Mult("1 - Smelting", "Blast furnace", 5, "Bars per ore in the Blast furnace.");
		CharcoalKiln = Mult("1 - Smelting", "Charcoal kiln", 5, "Multiplies coal from the Charcoal kiln.");
		Windmill = Mult("1 - Smelting", "Windmill", 5, "Multiplies barley flour from the Windmill.");
		SpinningWheel = Mult("1 - Smelting", "Spinning wheel", 5, "Multiplies linen thread from the Spinning wheel.");
		EitrRefinery = Mult("1 - Smelting", "Eitr refinery", 5, "Multiplies eitr from the Eitr refinery.");
		OtherSmelters = Mult("1 - Smelting", "Other smelter-type stations", 5, "Any other station that works like a smelter (Deep North or modded). Only stackable outputs are multiplied.");
		CookingStation = Mult("2 - Cooking", "Cooking station", 5, "Multiplies food from the wooden Cooking station.");
		IronCookingStation = Mult("2 - Cooking", "Iron cooking station", 5, "Multiplies food from the Iron cooking station.");
		Oven = Mult("2 - Cooking", "Stone oven", 5, "Multiplies food from the Stone oven.");
		OtherCooking = Mult("2 - Cooking", "Other cooking-type stations", 5, "Any other cooking-type station (Deep North or modded). Gear and other non-stackable outputs are never multiplied.");
		ConfigFile config2 = ((BaseUnityPlugin)this).Config;
		object[] array2 = new object[1];
		val = new ConfigurationManagerAttributes();
		val.IsAdminOnly = true;
		array2[0] = val;
		MultiplyBurnt = config2.Bind<bool>("2 - Cooking", "Multiply burnt food", false, new ConfigDescription("If false, burnt food (coal) is not multiplied.", (AcceptableValueBase)null, array2));
		Fermenter = Mult("3 - Fermenter", "Fermenter", 5, "Multiplies meads/drinks tapped from the Fermenter.");
		new Harmony("made.deepnorth.outputmultiplier").PatchAll(typeof(Plugin).Assembly);
		((BaseUnityPlugin)this).Logger.LogInfo((object)"DeepNorthOutputMultiplier 1.0.1 loaded");
	}

	internal static void Note(string kind, string token, string prefab, int mult)
	{
		string item = kind + "|" + token + "|" + prefab;
		if (seen.Add(item))
		{
			((BaseUnityPlugin)Instance).Logger.LogInfo((object)(kind + " '" + prefab + "' (" + token + ") -> x" + mult));
		}
	}

	internal static string PrefabName(GameObject go)
	{
		string name = ((Object)go).name;
		int num = name.IndexOf("(Clone)", StringComparison.Ordinal);
		return (num < 0) ? name : name.Substring(0, num);
	}

	internal static int SmelterMult(Smelter s)
	{
		if (!Enabled.Value)
		{
			return 1;
		}
		string text = s.m_name ?? string.Empty;
		string prefab = PrefabName(((Component)s).gameObject);
		int num = text switch
		{
			"$piece_smelter" => Smelter.Value, 
			"$piece_blastfurnace" => BlastFurnace.Value, 
			"$piece_charcoalkiln" => CharcoalKiln.Value, 
			"$piece_windmill" => Windmill.Value, 
			"$piece_spinningwheel" => SpinningWheel.Value, 
			"$piece_eitrrefinery" => EitrRefinery.Value, 
			_ => OtherSmelters.Value, 
		};
		Note("Smelter", text, prefab, num);
		return num;
	}

	internal static int CookMult(CookingStation c)
	{
		if (!Enabled.Value)
		{
			return 1;
		}
		string text = c.m_name ?? string.Empty;
		string text2 = PrefabName(((Component)c).gameObject);
		int num = ((!(text2 == "piece_cookingstation") && !(text == "$piece_cookingstation")) ? ((!(text2 == "piece_cookingstation_iron") && !(text == "$piece_cookingstation_iron")) ? ((!(text2 == "piece_oven") && !(text == "$piece_oven")) ? OtherCooking.Value : Oven.Value) : IronCookingStation.Value) : CookingStation.Value);
		Note("Cooking", text, text2, num);
		return num;
	}

	internal static int MaxStack(string prefabName, out bool found)
	{
		found = false;
		if ((Object)(object)ObjectDB.instance == (Object)null)
		{
			return 1;
		}
		GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefabName);
		if ((Object)(object)itemPrefab == (Object)null)
		{
			return 1;
		}
		ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
		if ((Object)(object)component == (Object)null)
		{
			return 1;
		}
		found = true;
		return Math.Max(1, component.m_itemData.m_shared.m_maxStackSize);
	}
}
[HarmonyPatch(typeof(Smelter), "Spawn")]
internal static class Smelter_Spawn_Patch
{
	[ThreadStatic]
	private static bool inside;

	private static readonly MethodInfo spawn = AccessTools.Method(typeof(Smelter), "Spawn", (Type[])null, (Type[])null);

	private static readonly MethodInfo getConv = AccessTools.Method(typeof(Smelter), "GetItemConversion", (Type[])null, (Type[])null);

	[HarmonyPriority(800)]
	private static void Prefix(Smelter __instance, string ore, ref int stack, out int __state)
	{
		__state = 0;
		if (inside || stack <= 0)
		{
			return;
		}
		int num = Plugin.SmelterMult(__instance);
		if (num <= 1)
		{
			return;
		}
		int num2 = int.MaxValue;
		object obj = getConv.Invoke(__instance, new object[1] { ore });
		if (obj != null)
		{
			ItemDrop value = Traverse.Create(obj).Field("m_to").GetValue<ItemDrop>();
			if ((Object)(object)value != (Object)null)
			{
				int maxStackSize = value.m_itemData.m_shared.m_maxStackSize;
				if (maxStackSize <= 1)
				{
					return;
				}
				num2 = maxStackSize;
			}
		}
		long num3 = (long)stack * (long)num;
		if (num3 > num2)
		{
			stack = num2;
			__state = (int)Math.Min(num3 - num2, 2147483647L);
		}
		else
		{
			stack = (int)num3;
		}
	}

	private static void Postfix(Smelter __instance, string ore, int __state)
	{
		if (__state <= 0)
		{
			return;
		}
		int val = int.MaxValue;
		object obj = getConv.Invoke(__instance, new object[1] { ore });
		if (obj != null)
		{
			ItemDrop value = Traverse.Create(obj).Field("m_to").GetValue<ItemDrop>();
			if ((Object)(object)value != (Object)null)
			{
				val = Math.Max(1, value.m_itemData.m_shared.m_maxStackSize);
			}
		}
		int num = __state;
		inside = true;
		try
		{
			while (num > 0)
			{
				int num2 = Math.Min(num, val);
				spawn.Invoke(__instance, new object[2] { ore, num2 });
				num -= num2;
			}
		}
		finally
		{
			inside = false;
		}
	}
}
[HarmonyPatch(typeof(CookingStation), "SpawnItem")]
internal static class CookingStation_SpawnItem_Patch
{
	[ThreadStatic]
	private static bool inside;

	private static readonly MethodInfo spawnItem = AccessTools.Method(typeof(CookingStation), "SpawnItem", (Type[])null, (Type[])null);

	private static void Postfix(CookingStation __instance, string name, int slot, Vector3 userPoint, bool cheated)
	{
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		if (inside)
		{
			return;
		}
		int num = Plugin.CookMult(__instance);
		if (num <= 1 || (!Plugin.MultiplyBurnt.Value && (Object)(object)__instance.m_overCookedItem != (Object)null && name == ((Object)((Component)__instance.m_overCookedItem).gameObject).name))
		{
			return;
		}
		bool found;
		int num2 = Plugin.MaxStack(name, out found);
		if (!found || num2 <= 1)
		{
			return;
		}
		inside = true;
		try
		{
			for (int i = 1; i < num; i++)
			{
				spawnItem.Invoke(__instance, new object[4] { name, slot, userPoint, cheated });
			}
		}
		finally
		{
			inside = false;
		}
	}
}
[HarmonyPatch(typeof(Fermenter), "DelayedTap")]
internal static class Fermenter_DelayedTap_Patch
{
	[HarmonyPriority(800)]
	private static void Prefix(Fermenter __instance, out List<int> __state)
	{
		__state = null;
		if (!Plugin.Enabled.Value)
		{
			return;
		}
		int value = Plugin.Fermenter.Value;
		if (value <= 1 || __instance.m_conversion == null)
		{
			return;
		}
		Plugin.Note("Fermenter", __instance.m_name, Plugin.PrefabName(((Component)__instance).gameObject), value);
		__state = new List<int>();
		foreach (ItemConversion item in __instance.m_conversion)
		{
			__state.Add(item.m_producedItems);
			item.m_producedItems *= value;
		}
	}

	private static void Postfix(Fermenter __instance, List<int> __state)
	{
		if (__state != null)
		{
			for (int i = 0; i < __state.Count && i < __instance.m_conversion.Count; i++)
			{
				__instance.m_conversion[i].m_producedItems = __state[i];
			}
		}
	}
}