Decompiled source of BuildFreedom v0.1.0

BuildFreedom.dll

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

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("BuildFreedom")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("BuildFreedom")]
[assembly: AssemblyTitle("BuildFreedom")]
[assembly: AssemblyVersion("0.1.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 BuildFreedom
{
	internal static class BuildFreedomConfig
	{
		public static ConfigEntry<bool> NoBuildIntegrity;

		public static ConfigEntry<bool> NoRainDamage;

		public static ConfigEntry<bool> StationRangeEnabled;

		public static ConfigEntry<float> WorkbenchRangeMultiplier;

		public static ConfigEntry<float> StonecutterRangeMultiplier;

		public static ConfigEntry<float> OtherStationRangeMultiplier;

		public static ConfigEntry<bool> ResizeRangeCircle;

		public static void Bind(ConfigFile cfg)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Expected O, but got Unknown
			NoBuildIntegrity = cfg.Bind<bool>("1 - Build Integrity", "Enabled", true, "Removes structural support requirements. Pieces never collapse and the hammer support colouring stays blue. Disable to restore vanilla integrity.");
			NoRainDamage = cfg.Bind<bool>("2 - Weather", "NoRainDamage", true, "Treats every piece as if it has a roof over it, so rain never wears structures down. Does not affect your character's shelter/rested status -- that is calculated separately.");
			StationRangeEnabled = cfg.Bind<bool>("3 - Station Range", "Enabled", true, "Master toggle for crafting station build-radius changes.");
			WorkbenchRangeMultiplier = cfg.Bind<float>("3 - Station Range", "WorkbenchMultiplier", 3f, new ConfigDescription("Multiplier applied to the workbench build radius. 3 = triple vanilla.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 20f), Array.Empty<object>()));
			StonecutterRangeMultiplier = cfg.Bind<float>("3 - Station Range", "StonecutterMultiplier", 3f, new ConfigDescription("Multiplier applied to the stonecutter build radius. 3 = triple vanilla.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 20f), Array.Empty<object>()));
			OtherStationRangeMultiplier = cfg.Bind<float>("3 - Station Range", "OtherStationsMultiplier", 1f, new ConfigDescription("Multiplier for every other crafting station (forge, artisan table, galdr table, black forge...). Leave at 1 to only affect workbench and stonecutter.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 20f), Array.Empty<object>()));
			ResizeRangeCircle = cfg.Bind<bool>("3 - Station Range", "ResizeRangeCircle", true, "Also resize the on-screen radius circle so it matches the real build range. Turn this off if the circle causes visual issues at very large radii.");
			StationRangeEnabled.SettingChanged += delegate
			{
				StationRangePatch.ReapplyAll();
			};
			WorkbenchRangeMultiplier.SettingChanged += delegate
			{
				StationRangePatch.ReapplyAll();
			};
			StonecutterRangeMultiplier.SettingChanged += delegate
			{
				StationRangePatch.ReapplyAll();
			};
			OtherStationRangeMultiplier.SettingChanged += delegate
			{
				StationRangePatch.ReapplyAll();
			};
			ResizeRangeCircle.SettingChanged += delegate
			{
				StationRangePatch.ReapplyAll();
			};
		}
	}
	[BepInPlugin("com.demonforge.buildfreedom", "BuildFreedom", "0.1.0")]
	public class BuildFreedomPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.demonforge.buildfreedom";

		public const string PluginName = "BuildFreedom";

		public const string PluginVersion = "0.1.0";

		internal static ManualLogSource Log;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			BuildFreedomConfig.Bind(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("com.demonforge.buildfreedom");
			ApplyFeature("NoBuildIntegrity", typeof(NoBuildIntegrityPatch));
			ApplyFeature("NoRainDamage", typeof(NoRainDamagePatch));
			ApplyFeature("StationRange", typeof(StationRangePatch));
			Log.LogInfo((object)"BuildFreedom 0.1.0 loaded.");
		}

		private void ApplyFeature(string featureName, Type patchClass)
		{
			try
			{
				_harmony.PatchAll(patchClass);
				Log.LogInfo((object)("[" + featureName + "] patched successfully."));
			}
			catch (Exception ex)
			{
				Log.LogError((object)("[" + featureName + "] FAILED to patch -- this feature is disabled for this session. Other features are unaffected."));
				Log.LogError((object)ex);
			}
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
}
namespace BuildFreedom.Patches
{
	[HarmonyPatch(typeof(WearNTear), "UpdateSupport")]
	internal static class NoBuildIntegrityPatch
	{
		private const float FlatSupport = 1000f;

		private const BindingFlags Flags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private static FieldInfo _supportField;

		private static bool _resolved;

		private static void Resolve()
		{
			_resolved = true;
			_supportField = typeof(WearNTear).GetField("m_support", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? typeof(WearNTear).GetField("m_currentSupport", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? typeof(WearNTear).GetField("m_supportValue", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (_supportField != null)
			{
				BuildFreedomPlugin.Log.LogInfo((object)("[NoBuildIntegrity] using support field: " + _supportField.Name));
				return;
			}
			IEnumerable<string> values = from f in typeof(WearNTear).GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
				where f.FieldType == typeof(float)
				select f.Name;
			BuildFreedomPlugin.Log.LogWarning((object)("[NoBuildIntegrity] no support field found. Float fields on WearNTear: " + string.Join(", ", values)));
		}

		private static bool Prefix(WearNTear __instance)
		{
			if (!BuildFreedomConfig.NoBuildIntegrity.Value)
			{
				return true;
			}
			if (!_resolved)
			{
				Resolve();
			}
			_supportField?.SetValue(__instance, 1000f);
			return false;
		}
	}
	[HarmonyPatch(typeof(WearNTear), "HaveRoof")]
	internal static class NoRainDamagePatch
	{
		private static bool Prefix(ref bool __result)
		{
			if (!BuildFreedomConfig.NoRainDamage.Value)
			{
				return true;
			}
			__result = true;
			return false;
		}
	}
	[HarmonyPatch(typeof(CraftingStation))]
	internal static class StationRangePatch
	{
		private static readonly Dictionary<CraftingStation, float> BaseRange = new Dictionary<CraftingStation, float>();

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void AwakePostfix(CraftingStation __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				BaseRange[__instance] = __instance.m_rangeBuild;
				Apply(__instance);
			}
		}

		internal static void ReapplyAll()
		{
			PruneDestroyed();
			foreach (CraftingStation item in BaseRange.Keys.ToList())
			{
				Apply(item);
			}
		}

		private static void Apply(CraftingStation station)
		{
			if ((Object)(object)station == (Object)null || !BaseRange.TryGetValue(station, out var value))
			{
				return;
			}
			float num = (BuildFreedomConfig.StationRangeEnabled.Value ? MultiplierFor(station) : 1f);
			station.m_rangeBuild = value * num;
			if (BuildFreedomConfig.ResizeRangeCircle.Value && (Object)(object)station.m_areaMarker != (Object)null)
			{
				CircleProjector val = station.m_areaMarker.GetComponent<CircleProjector>() ?? station.m_areaMarker.GetComponentInChildren<CircleProjector>(true);
				if ((Object)(object)val != (Object)null)
				{
					val.m_radius = station.m_rangeBuild;
					val.m_nrOfSegments = Mathf.Clamp(Mathf.RoundToInt(station.m_rangeBuild * 4f), 20, 400);
				}
			}
		}

		private static float MultiplierFor(CraftingStation station)
		{
			string prefabName = Utils.GetPrefabName(((Component)station).gameObject);
			if (prefabName.IndexOf("workbench", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return BuildFreedomConfig.WorkbenchRangeMultiplier.Value;
			}
			if (prefabName.IndexOf("stonecutter", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return BuildFreedomConfig.StonecutterRangeMultiplier.Value;
			}
			return BuildFreedomConfig.OtherStationRangeMultiplier.Value;
		}

		private static void PruneDestroyed()
		{
			List<CraftingStation> list = BaseRange.Keys.Where((CraftingStation s) => (Object)(object)s == (Object)null).ToList();
			foreach (CraftingStation item in list)
			{
				BaseRange.Remove(item);
			}
		}
	}
}