Decompiled source of FreeCrafting v1.4.1

FreeCrafting.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[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 FreeCrafting
{
	[BepInPlugin("metalpietie.freecrafting", "FreeCrafting", "1.4.1")]
	public class FreeCraftingPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "metalpietie.freecrafting";

		public const string PluginName = "FreeCrafting";

		public const string PluginVersion = "1.4.1";

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<bool> RequireStationLevel;

		internal static ConfigEntry<bool> FreeCraft;

		internal static ConfigEntry<bool> FreeUpgrade;

		internal static ConfigEntry<bool> RepairAnyLevel;

		internal static ConfigEntry<bool> StationInventory;

		internal static ConfigEntry<bool> StationWorkbench;

		internal static ConfigEntry<bool> StationForge;

		internal static ConfigEntry<bool> StationBlackForge;

		internal static ConfigEntry<bool> StationCauldron;

		internal static ConfigEntry<bool> StationStonecutter;

		internal static ConfigEntry<bool> StationArtisan;

		internal static ConfigEntry<bool> StationGaldrTable;

		internal static ConfigEntry<bool> StationFoodPrep;

		internal static ConfigEntry<bool> StationForgeOfPotential;

		internal static ConfigEntry<bool> StationOther;

		internal static ConfigEntry<bool> FreeIdol;

		internal static ConfigEntry<bool> GuaranteedSuccess;

		internal static ConfigEntry<bool> PreventBreaking;

		internal static ConfigEntry<bool> PreventLevelLoss;

		internal static bool Crafting;

		private void Awake()
		{
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Enabled", true, "Master switch. Off = the plugin does nothing.");
			RequireStationLevel = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Require station level", true, "On = you cannot craft or upgrade if the station level is too low (like the normal game). Off = the station level is ignored for crafting and upgrading. Repair has its own setting.");
			FreeCraft = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Types", "Free crafting", true, "Crafting a new item costs no items.");
			FreeUpgrade = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Types", "Free upgrading", true, "Upgrading an item costs no items.");
			RepairAnyLevel = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Types", "Repair at any station level", true, "You can repair an item at its station even if the station level is too low.");
			StationInventory = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Stations", "Inventory (no station)", true, "Crafting from your inventory.");
			StationWorkbench = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Stations", "Workbench", true, "");
			StationForge = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Stations", "Forge", true, "");
			StationBlackForge = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Stations", "Black forge", true, "");
			StationCauldron = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Stations", "Cauldron", true, "");
			StationStonecutter = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Stations", "Stonecutter", true, "");
			StationArtisan = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Stations", "Artisan table", true, "");
			StationGaldrTable = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Stations", "Galdr table", true, "");
			StationFoodPrep = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Stations", "Food preparation table", true, "");
			StationForgeOfPotential = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Stations", "Forge of Potential", false, "The special forge that upgrades items past their normal level. Off by default. On = upgrades there follow the Free upgrading setting. The settings in section 4 work on their own.");
			StationOther = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Stations", "Other stations", true, "Any station not listed above, for example one added by another mod.");
			FreeIdol = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Forge of Potential", "Free idol", false, "On = upgrading at the Forge of Potential costs no idol. Off = the idol is still taken, but nothing else is. Only matters when the Forge of Potential station switch and Free upgrading are on.");
			GuaranteedSuccess = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Forge of Potential", "Guaranteed success", false, "On = every upgrade at the Forge of Potential succeeds (100% chance). It can then never break the item or lower it.");
			PreventBreaking = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Forge of Potential", "Prevent item breaking", false, "On = an upgrade at the Forge of Potential can never destroy your item. A roll that would destroy it counts as a normal failure instead (the item loses one level, unless Prevent level loss is on).");
			PreventLevelLoss = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Forge of Potential", "Prevent level loss", false, "On = a failed upgrade at the Forge of Potential does not lower the item. It stays at the level it was.");
			new Harmony("metalpietie.freecrafting").PatchAll();
		}

		internal static bool StationOn(CraftingStation station)
		{
			if ((Object)(object)station == (Object)null)
			{
				return StationInventory.Value;
			}
			if (station.m_upgrader)
			{
				return StationForgeOfPotential.Value;
			}
			return station.m_name switch
			{
				"$piece_workbench" => StationWorkbench.Value, 
				"$piece_forge" => StationForge.Value, 
				"$piece_blackforge" => StationBlackForge.Value, 
				"$piece_cauldron" => StationCauldron.Value, 
				"$piece_stonecutter" => StationStonecutter.Value, 
				"$piece_artisanstation" => StationArtisan.Value, 
				"$piece_magetable" => StationGaldrTable.Value, 
				"$piece_preptable" => StationFoodPrep.Value, 
				_ => StationOther.Value, 
			};
		}

		internal static bool IsFree(int qualityLevel)
		{
			if (!Enabled.Value || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return false;
			}
			if ((qualityLevel > 1) ? FreeUpgrade.Value : FreeCraft.Value)
			{
				return StationOn(Player.m_localPlayer.GetCurrentCraftingStation());
			}
			return false;
		}

		internal static bool IdolStillCosts()
		{
			if ((Object)(object)Player.m_localPlayer == (Object)null || FreeIdol.Value)
			{
				return false;
			}
			CraftingStation currentCraftingStation = Player.m_localPlayer.GetCurrentCraftingStation();
			if ((Object)(object)currentCraftingStation != (Object)null)
			{
				return currentCraftingStation.m_upgrader;
			}
			return false;
		}

		internal static bool HaveWhatStillCosts(Recipe recipe, int qualityLevel, int amount)
		{
			if (!IdolStillCosts() || recipe.m_resources == null)
			{
				return true;
			}
			Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
			Requirement[] resources = recipe.m_resources;
			foreach (Requirement val in resources)
			{
				if (val.m_upgraderResource && !((Object)(object)val.m_resItem == (Object)null))
				{
					string name = val.m_resItem.m_itemData.m_shared.m_name;
					if (inventory.CountItems(name, -1, true) < val.GetAmount(qualityLevel) * amount)
					{
						return false;
					}
				}
			}
			return true;
		}

		internal static float UpgradeChance(SharedData idol)
		{
			if (!Enabled.Value || !GuaranteedSuccess.Value)
			{
				return idol.m_upgradeChance;
			}
			return 1f;
		}

		internal static float BreakChance(SharedData idol)
		{
			if (!Enabled.Value || !PreventBreaking.Value)
			{
				return idol.m_breakChance;
			}
			return 0f;
		}

		internal static int LevelDrop()
		{
			if (!Enabled.Value || !PreventLevelLoss.Value)
			{
				return 2;
			}
			return 1;
		}
	}
	[HarmonyPatch(typeof(Player), "HaveRequirementItems", new Type[]
	{
		typeof(Recipe),
		typeof(bool),
		typeof(int),
		typeof(int)
	})]
	internal static class HaveRequirementItemsPatch
	{
		private static void Postfix(Recipe piece, bool discover, int qualityLevel, int amount, ref bool __result)
		{
			if (!discover && (Object)(object)piece != (Object)null && piece.m_enabled && FreeCraftingPlugin.IsFree(qualityLevel))
			{
				__result = FreeCraftingPlugin.HaveWhatStillCosts(piece, qualityLevel, amount);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "HaveRequirements", new Type[]
	{
		typeof(Recipe),
		typeof(bool),
		typeof(int),
		typeof(int)
	})]
	internal static class HaveRequirementsPatch
	{
		private static void Postfix(Recipe recipe, bool discover, int qualityLevel, int amount, ref bool __result)
		{
			if (!FreeCraftingPlugin.RequireStationLevel.Value && !discover && (Object)(object)recipe != (Object)null && recipe.m_enabled && FreeCraftingPlugin.IsFree(qualityLevel))
			{
				__result = FreeCraftingPlugin.HaveWhatStillCosts(recipe, qualityLevel, amount);
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
	internal static class DoCraftingPatch
	{
		private static void Prefix()
		{
			FreeCraftingPlugin.Crafting = true;
		}

		private static void Finalizer()
		{
			FreeCraftingPlugin.Crafting = false;
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			MethodInfo operand = AccessTools.Method(typeof(FreeCraftingPlugin), "BreakChance", (Type[])null, (Type[])null);
			MethodInfo operand2 = AccessTools.Method(typeof(FreeCraftingPlugin), "UpgradeChance", (Type[])null, (Type[])null);
			MethodInfo operand3 = AccessTools.Method(typeof(FreeCraftingPlugin), "LevelDrop", (Type[])null, (Type[])null);
			for (int i = 0; i < list.Count; i++)
			{
				CodeInstruction val = list[i];
				if (val.opcode == OpCodes.Ldfld && val.operand is FieldInfo fieldInfo && fieldInfo.DeclaringType == typeof(SharedData) && fieldInfo.Name == "m_breakChance")
				{
					val.opcode = OpCodes.Call;
					val.operand = operand;
				}
				else if (val.opcode == OpCodes.Ldfld && val.operand is FieldInfo fieldInfo2 && fieldInfo2.DeclaringType == typeof(SharedData) && fieldInfo2.Name == "m_upgradeChance")
				{
					val.opcode = OpCodes.Call;
					val.operand = operand2;
				}
				else if (val.opcode == OpCodes.Ldloc_0 && i + 2 < list.Count && list[i + 1].opcode == OpCodes.Ldc_I4_2 && list[i + 2].opcode == OpCodes.Sub)
				{
					list[i + 1].opcode = OpCodes.Call;
					list[i + 1].operand = operand3;
				}
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(Player), "ConsumeResources")]
	internal static class ConsumeResourcesPatch
	{
		private static bool Prefix(ref Requirement[] requirements, int qualityLevel)
		{
			if (!FreeCraftingPlugin.Crafting || !FreeCraftingPlugin.IsFree(qualityLevel))
			{
				return true;
			}
			if (!FreeCraftingPlugin.IdolStillCosts())
			{
				return false;
			}
			requirements = Array.FindAll(requirements, (Requirement requirement) => requirement.m_upgraderResource);
			return true;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "CanRepair")]
	internal static class CanRepairPatch
	{
		internal struct Saved
		{
			public Recipe Recipe;

			public int Level;
		}

		private const int NoLevel = -1000000;

		private static void Prefix(ItemData item, out Saved __state)
		{
			__state = default(Saved);
			if (!FreeCraftingPlugin.Enabled.Value || !FreeCraftingPlugin.RepairAnyLevel.Value || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)ObjectDB.instance == (Object)null || item == null)
			{
				return;
			}
			CraftingStation currentCraftingStation = Player.m_localPlayer.GetCurrentCraftingStation();
			if (!((Object)(object)currentCraftingStation == (Object)null) && FreeCraftingPlugin.StationOn(currentCraftingStation))
			{
				Recipe recipe = ObjectDB.instance.GetRecipe(item);
				if (!((Object)(object)recipe == (Object)null))
				{
					__state = new Saved
					{
						Recipe = recipe,
						Level = recipe.m_minStationLevel
					};
					recipe.m_minStationLevel = -1000000;
				}
			}
		}

		private static void Finalizer(Saved __state)
		{
			if ((Object)(object)__state.Recipe != (Object)null)
			{
				__state.Recipe.m_minStationLevel = __state.Level;
			}
		}
	}
}