Decompiled source of BetterHauler v0.2.0

BepInEx/plugins/REPO.BetterHauler.dll

Decompiled 14 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("REPO.BetterHauler")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("REPO mod: bigger cargo monitor and wider pickup range for the Hauler")]
[assembly: AssemblyFileVersion("0.2.0.0")]
[assembly: AssemblyInformationalVersion("0.2.0")]
[assembly: AssemblyProduct("REPO.BetterHauler")]
[assembly: AssemblyTitle("REPO.BetterHauler")]
[assembly: AssemblyVersion("0.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 REPO.HaulerTweaks
{
	[BepInPlugin("ningen.repo.betterhauler", "REPO Better Hauler", "0.2.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "ningen.repo.betterhauler";

		public const string PluginName = "REPO Better Hauler";

		public const string PluginVersion = "0.2.0";

		internal static ManualLogSource Log;

		private const string HideFromInGameMenu = "HideFromREPOConfig";

		internal static ConfigEntry<float> MonitorScale;

		internal static ConfigEntry<float> TextScale;

		internal static ConfigEntry<float> PickupRange;

		internal static ConfigEntry<bool> ShowRemaining;

		internal static ConfigEntry<bool> ReplaceMainNumber;

		internal static ConfigEntry<float> RemainingTextSize;

		internal static ConfigEntry<bool> ShowPickupRange;

		internal static ConfigEntry<float> PickupRangeOpacity;

		internal static ConfigEntry<bool> LogCargoBoxLayout;

		internal static ConfigEntry<bool> UnlockDebugConsole;

		internal static ConfigEntry<int> CargoLimit;

		internal static ConfigEntry<bool> UnlimitedCargo;

		internal static ConfigEntry<bool> AcceptAnySize;

		internal const int VanillaCargoLimit = 20000;

		internal const float UnlimitedValue = 1E+09f;

		private void Awake()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Expected O, but got Unknown
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Expected O, but got Unknown
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Expected O, but got Unknown
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Expected O, but got Unknown
			//IL_041d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_042d: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			MonitorScale = ((BaseUnityPlugin)this).Config.Bind<float>("Monitor", "ScreenSize", 1f, new ConfigDescription("Size of the cargo monitor screen. The digits keep their own size, set by TextSize, so this grows the panel without growing the numbers on it. 1.0 = vanilla. Large values can push the screen through the cargo box mesh.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 5f), Array.Empty<object>()));
			TextScale = ((BaseUnityPlugin)this).Config.Bind<float>("Monitor", "TextSize", 1f, new ConfigDescription("Size of the digits, independent of ScreenSize. 1.0 = vanilla. Much above 1.5 and they start spilling outside the screen frame.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 5f), Array.Empty<object>()));
			PickupRange = ((BaseUnityPlugin)this).Config.Bind<float>("Pickup", "PickupRange", 1f, new ConfigDescription("How much wider the cargo box's pickup volume gets. 1.0 = vanilla. The check is a box centred on the cargo box that ignores walls, so large values will vacuum up valuables from the next room. Drops back to vanilla while the Hauler is inside an extraction point. Only the host's value matters in multiplayer.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
			ShowRemaining = ((BaseUnityPlugin)this).Config.Bind<bool>("Monitor", "ShowRemaining", true, "Show how much value the cargo box will still take, on a second smaller line under the main number. Counts down to zero as you fill it. Measured against the bed's cap (vanilla, or CargoLimit if changed); reads NO LIMIT when UnlimitedCargo is on.");
			ReplaceMainNumber = ((BaseUnityPlugin)this).Config.Bind<bool>("Monitor", "ReplaceMainNumber", false, "Put the remaining amount in place of the main number instead of on a second line, so the screen shows one figure that counts down. Needs ShowRemaining on. Ignored while UnlimitedCargo is on, since there's no remaining amount to show.");
			RemainingTextSize = ((BaseUnityPlugin)this).Config.Bind<float>("Monitor", "RemainingTextSize", 0.45f, new ConfigDescription("Size of the remaining-amount line, relative to the main number. Used whenever that line is showing: ShowRemaining on, and ReplaceMainNumber off or overridden by UnlimitedCargo.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 1f), Array.Empty<object>()));
			ShowPickupRange = ((BaseUnityPlugin)this).Config.Bind<bool>("Pickup", "ShowPickupRange", false, "Draw the cargo box's pickup volume as a translucent box so you can see exactly what PickupRange is doing. Purely visual and local to you - it has no collider and is never sent to other players.");
			PickupRangeOpacity = ((BaseUnityPlugin)this).Config.Bind<float>("Pickup", "PickupRangeOpacity", 0.15f, new ConfigDescription("How solid the pickup volume box looks when ShowPickupRange is on.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.02f, 0.6f), Array.Empty<object>()));
			CargoLimit = ((BaseUnityPlugin)this).Config.Bind<int>("Unfair", "CargoLimit", 20000, new ConfigDescription("How much value the Hauler's bed holds before it refuses more, in dollars. 20000 = vanilla. Rounded to the nearest 1,000. In multiplayer only the host's value decides what fits.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5000, 500000), Array.Empty<object>()));
			UnlimitedCargo = ((BaseUnityPlugin)this).Config.Bind<bool>("Unfair", "UnlimitedCargo", false, "No cap at all - the bed never fills. Overrides CargoLimit while on. The screen's remaining line reads NO LIMIT instead of a figure. Host's setting decides in multiplayer.");
			AcceptAnySize = ((BaseUnityPlugin)this).Config.Bind<bool>("Unfair", "AcceptAnySize", false, "Let the bed take valuables of any size. Vanilla only takes small ones and shows \"Too big\" for the rest. Big valuables still have to reach the pickup volume, so this pairs with a higher PickupRange. Host's setting decides in multiplayer.");
			LogCargoBoxLayout = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "LogCargoBoxLayout", false, new ConfigDescription("Print the Hauler cargo box's transform hierarchy to the BepInEx log the first time one spawns. Use this when working out how ScreenSize and TextSize map onto the real objects.", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
			UnlockDebugConsole = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "UnlockDebugConsole", false, new ConfigDescription("Unlock the game's own built-in debug console (backquote key). REPO ships the whole thing, it's just gated behind SemiFunc.DebugTester() which is false in retail builds. Gives you /spawn, /level, /cash, /godmode, /noenemies and friends, with Tab completion. Testing aid, off by default.", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" }));
			MonitorScale.SettingChanged += ReapplyAll;
			TextScale.SettingChanged += ReapplyAll;
			PickupRange.SettingChanged += ReapplyAll;
			ShowPickupRange.SettingChanged += ReapplyAll;
			PickupRangeOpacity.SettingChanged += ReapplyAll;
			ShowRemaining.SettingChanged += ReapplyAll;
			ReplaceMainNumber.SettingChanged += ReapplyAll;
			RemainingTextSize.SettingChanged += ReapplyAll;
			CargoLimit.SettingChanged += SnapCargoLimit;
			UnlimitedCargo.SettingChanged += ReapplyAll;
			AcceptAnySize.SettingChanged += ReapplyAll;
			Harmony val = new Harmony("ningen.repo.betterhauler");
			val.PatchAll();
			CargoPatches.Apply(val);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"REPO Better Hauler 0.2.0 loaded.");
		}

		internal static int SnappedCargoLimit()
		{
			return Mathf.Clamp(Mathf.RoundToInt((float)CargoLimit.Value / 1000f) * 1000, 5000, 500000);
		}

		private static void SnapCargoLimit(object sender, EventArgs e)
		{
			int num = SnappedCargoLimit();
			if (num != CargoLimit.Value)
			{
				CargoLimit.Value = num;
			}
			else
			{
				ReapplyAll(sender, e);
			}
		}

		private static void ReapplyAll(object sender, EventArgs e)
		{
			HaulerTweaks.RefreshRemainingLines();
			ItemValuableBox[] array = Object.FindObjectsOfType<ItemValuableBox>();
			for (int i = 0; i < array.Length; i++)
			{
				HaulerTweaks.Apply(array[i]);
			}
		}
	}
	internal class HaulerTweaksState : MonoBehaviour
	{
		internal bool captured;

		internal Vector3 checkerScale;

		internal Vector3 textScale;

		internal Vector3 assemblyScale;

		internal bool dumped;

		internal bool checkerFiltersTypes;

		internal ItemValuableBox box;

		internal Transform checker;

		internal PhysGrabObjectComponentInsideBoxChecker boxChecker;

		private bool? appliedAtExtraction;

		internal void SyncPickupRange(bool force)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			if (!captured || (Object)(object)box == (Object)null || (Object)(object)checker == (Object)null)
			{
				return;
			}
			bool flag = HaulerTweaks.IsAtExtractionPoint(box);
			if (!force && appliedAtExtraction == flag)
			{
				return;
			}
			appliedAtExtraction = flag;
			float num = (flag ? 1f : Plugin.PickupRange.Value);
			checker.localScale = checkerScale * num;
			HaulerTweaks.UpdateRangeBox(checker);
			if (!((Object)(object)boxChecker != (Object)null) || boxChecker.layerMasksToCheck == null)
			{
				return;
			}
			foreach (LayerMasks item in boxChecker.layerMasksToCheck)
			{
				item.timer = item.checkInterval;
			}
		}

		private void Update()
		{
			SyncPickupRange(force: false);
		}
	}
	internal static class HaulerTweaks
	{
		private static readonly Dictionary<TextScreen, ItemValuableBox> ScreenOwners = new Dictionary<TextScreen, ItemValuableBox>();

		private static readonly string NewLine = '\n'.ToString();

		private static readonly Dictionary<TextScreen, string> LastComposed = new Dictionary<TextScreen, string>();

		private static FieldRef<ItemValuableBox, RoomVolumeCheck> roomVolumeRef;

		private static FieldRef<RoomVolumeCheck, bool> inExtractionRef;

		private static bool extractionRefsResolved;

		private const string PickupRangeBoxName = "HaulerTweaks Range Visualiser";

		internal static void Apply(ItemValuableBox box)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)box == (Object)null)
			{
				return;
			}
			HaulerTweaksState haulerTweaksState = ((Component)box).GetComponent<HaulerTweaksState>();
			if ((Object)(object)haulerTweaksState == (Object)null)
			{
				haulerTweaksState = ((Component)box).gameObject.AddComponent<HaulerTweaksState>();
			}
			TextMeshPro val = (((Object)(object)box.textScreen != (Object)null) ? box.textScreen.displayText : null);
			Transform textScreenAnimatorTransform = box.textScreenAnimatorTransform;
			Transform val2 = (((Object)(object)box.boxChecker != (Object)null) ? ((Component)box.boxChecker).transform : null);
			if (!haulerTweaksState.captured)
			{
				haulerTweaksState.checkerScale = (((Object)(object)val2 != (Object)null) ? val2.localScale : Vector3.one);
				haulerTweaksState.textScale = (((Object)(object)val != (Object)null) ? val.transform.localScale : Vector3.one);
				haulerTweaksState.assemblyScale = (((Object)(object)textScreenAnimatorTransform != (Object)null) ? textScreenAnimatorTransform.localScale : Vector3.one);
				haulerTweaksState.checkerFiltersTypes = (Object)(object)box.boxChecker != (Object)null && box.boxChecker.checkForValuableTypes;
				haulerTweaksState.captured = true;
			}
			if (Plugin.LogCargoBoxLayout.Value && !haulerTweaksState.dumped)
			{
				haulerTweaksState.dumped = true;
				Dump(box, val, textScreenAnimatorTransform, val2);
			}
			box.valueLimit = (Plugin.UnlimitedCargo.Value ? 1E+09f : ((float)Plugin.SnappedCargoLimit()));
			if ((Object)(object)box.boxChecker != (Object)null)
			{
				box.boxChecker.checkForValuableTypes = !Plugin.AcceptAnySize.Value && haulerTweaksState.checkerFiltersTypes;
			}
			haulerTweaksState.box = box;
			haulerTweaksState.checker = val2;
			haulerTweaksState.boxChecker = box.boxChecker;
			if ((Object)(object)val2 != (Object)null)
			{
				haulerTweaksState.SyncPickupRange(force: true);
			}
			else
			{
				Plugin.Log.LogWarning((object)"Cargo box has no boxChecker; pickup range left alone.");
			}
			float value = Plugin.MonitorScale.Value;
			float num = Plugin.TextScale.Value;
			if ((Object)(object)textScreenAnimatorTransform != (Object)null)
			{
				textScreenAnimatorTransform.localScale = haulerTweaksState.assemblyScale * value;
				if (value > 0f)
				{
					num /= value;
				}
			}
			else if (value != 1f)
			{
				Plugin.Log.LogWarning((object)"Cargo box has no textScreenAnimatorTransform; applying ScreenSize to the digits instead.");
				num *= value;
			}
			if ((Object)(object)val != (Object)null)
			{
				val.transform.localScale = haulerTweaksState.textScale * num;
			}
			Plugin.Log.LogInfo((object)string.Format("Tweaked cargo box '{0}': ScreenSize {1}, TextSize {2}, PickupRange {3}, cap {4}", ((Object)box).name, Plugin.MonitorScale.Value, Plugin.TextScale.Value, Plugin.PickupRange.Value, Plugin.UnlimitedCargo.Value ? "unlimited" : box.valueLimit.ToString("0")));
		}

		internal static void RegisterScreen(ItemValuableBox box)
		{
			if ((Object)(object)box == (Object)null || (Object)(object)box.textScreen == (Object)null)
			{
				return;
			}
			List<TextScreen> list = null;
			foreach (KeyValuePair<TextScreen, ItemValuableBox> screenOwner in ScreenOwners)
			{
				if (!((Object)(object)screenOwner.Key != (Object)null) || !((Object)(object)screenOwner.Value != (Object)null))
				{
					if (list == null)
					{
						list = new List<TextScreen>();
					}
					list.Add(screenOwner.Key);
				}
			}
			if (list != null)
			{
				foreach (TextScreen item in list)
				{
					ScreenOwners.Remove(item);
					LastComposed.Remove(item);
				}
			}
			ScreenOwners[box.textScreen] = box;
		}

		internal static ItemValuableBox BoxForScreen(TextScreen screen)
		{
			if ((Object)(object)screen == (Object)null || !ScreenOwners.TryGetValue(screen, out var value))
			{
				return null;
			}
			if (!((Object)(object)value != (Object)null))
			{
				return null;
			}
			return value;
		}

		internal static void AppendRemainingLine(TextScreen screen)
		{
			bool flag = Plugin.ReplaceMainNumber.Value && !Plugin.UnlimitedCargo.Value;
			if (!Plugin.ShowRemaining.Value || flag)
			{
				StripRemainingLine(screen);
				return;
			}
			ItemValuableBox val = BoxForScreen(screen);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)screen.displayText == (Object)null))
			{
				string text = ((TMP_Text)screen.displayText).text;
				if (!LastComposed.TryGetValue(screen, out var value) || !(text == value))
				{
					int num = Mathf.Max(0, Mathf.RoundToInt(val.valueLimit - val.CurrentValue));
					int num2 = Mathf.RoundToInt(Plugin.RemainingTextSize.Value * 100f);
					string text2 = (Plugin.UnlimitedCargo.Value ? "NO LIMIT" : ("$" + SemiFunc.DollarGetString(num) + " LEFT"));
					string text3 = text + NewLine + "<size=" + num2 + "%><alpha=#B4>" + text2;
					((TMP_Text)screen.displayText).richText = true;
					((TMP_Text)screen.displayText).text = text3;
					LastComposed[screen] = text3;
				}
			}
		}

		private static void StripRemainingLine(TextScreen screen)
		{
			if (!LastComposed.TryGetValue(screen, out var value))
			{
				return;
			}
			LastComposed.Remove(screen);
			if (!((Object)(object)screen == (Object)null) && !((Object)(object)screen.displayText == (Object)null) && !(((TMP_Text)screen.displayText).text != value))
			{
				int num = value.LastIndexOf(NewLine[0]);
				if (num >= 0)
				{
					((TMP_Text)screen.displayText).text = value.Substring(0, num);
				}
			}
		}

		internal static void RefreshRemainingLines()
		{
			foreach (TextScreen item in new List<TextScreen>(LastComposed.Keys))
			{
				StripRemainingLine(item);
			}
		}

		internal static bool IsAtExtractionPoint(ItemValuableBox box)
		{
			if (!extractionRefsResolved)
			{
				extractionRefsResolved = true;
				try
				{
					roomVolumeRef = AccessTools.FieldRefAccess<ItemValuableBox, RoomVolumeCheck>("roomVolumeCheck");
					inExtractionRef = AccessTools.FieldRefAccess<RoomVolumeCheck, bool>("inExtractionPoint");
				}
				catch (Exception ex)
				{
					roomVolumeRef = null;
					inExtractionRef = null;
					Plugin.Log.LogWarning((object)("Could not read the cargo box's room check (" + ex.Message + "); using its public InExtractionPoint instead."));
				}
			}
			if (roomVolumeRef != null && inExtractionRef != null)
			{
				RoomVolumeCheck val = roomVolumeRef.Invoke(box);
				if ((Object)(object)val != (Object)null)
				{
					return inExtractionRef.Invoke(val);
				}
			}
			return box.InExtractionPoint;
		}

		internal static void UpdateRangeBox(Transform checker)
		{
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			Transform val = checker.Find("HaulerTweaks Range Visualiser");
			if (!Plugin.ShowPickupRange.Value)
			{
				if ((Object)(object)val != (Object)null)
				{
					Renderer component = ((Component)val).GetComponent<Renderer>();
					if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMaterial != (Object)null)
					{
						Object.Destroy((Object)(object)component.sharedMaterial);
					}
					Object.Destroy((Object)(object)((Component)val).gameObject);
				}
				return;
			}
			if ((Object)(object)val == (Object)null)
			{
				GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3);
				((Object)obj).name = "HaulerTweaks Range Visualiser";
				Collider component2 = obj.GetComponent<Collider>();
				if ((Object)(object)component2 != (Object)null)
				{
					Object.Destroy((Object)(object)component2);
				}
				obj.transform.SetParent(checker, false);
				obj.transform.localPosition = Vector3.zero;
				obj.transform.localRotation = Quaternion.identity;
				obj.transform.localScale = Vector3.one;
				val = obj.transform;
			}
			Renderer component3 = ((Component)val).GetComponent<Renderer>();
			if (!((Object)(object)component3 == (Object)null))
			{
				component3.shadowCastingMode = (ShadowCastingMode)0;
				component3.receiveShadows = false;
				Material material = component3.material;
				MakeTransparent(material);
				material.color = new Color(0.2f, 1f, 0.4f, Plugin.PickupRangeOpacity.Value);
			}
		}

		private static void MakeTransparent(Material material)
		{
			material.SetFloat("_Mode", 3f);
			material.SetInt("_SrcBlend", 5);
			material.SetInt("_DstBlend", 10);
			material.SetInt("_ZWrite", 0);
			material.DisableKeyword("_ALPHATEST_ON");
			material.EnableKeyword("_ALPHABLEND_ON");
			material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
			material.renderQueue = 3000;
			material.SetFloat("_Surface", 1f);
			material.SetFloat("_Blend", 0f);
		}

		private static void Dump(ItemValuableBox box, TextMeshPro text, Transform assembly, Transform checker)
		{
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("=== Hauler cargo box hierarchy ===");
			stringBuilder.AppendLine("root: " + ((Object)((Component)box).transform.root).name);
			stringBuilder.AppendLine("valueLimit: " + box.valueLimit);
			stringBuilder.AppendLine("textScreen: " + Describe(((Object)(object)box.textScreen != (Object)null) ? ((Component)box.textScreen).transform : null));
			stringBuilder.AppendLine("displayText: " + Describe(((Object)(object)text != (Object)null) ? text.transform : null));
			if ((Object)(object)text != (Object)null)
			{
				stringBuilder.AppendLine("  fontSize=" + ((TMP_Text)text).fontSize + " autoSizing=" + ((TMP_Text)text).enableAutoSizing + " min=" + ((TMP_Text)text).fontSizeMin + " max=" + ((TMP_Text)text).fontSizeMax);
			}
			stringBuilder.AppendLine("textScreenAnimatorTransform: " + Describe(assembly));
			stringBuilder.AppendLine("boxChecker: " + Describe(checker));
			if ((Object)(object)checker != (Object)null)
			{
				stringBuilder.AppendLine("  lossyScale (= OverlapBox size) = " + ((object)checker.lossyScale/*cast due to .constrained prefix*/).ToString() + ", childCount = " + checker.childCount);
			}
			stringBuilder.AppendLine("--- tree ---");
			AppendTree(stringBuilder, ((Component)box).transform, 0);
			Plugin.Log.LogInfo((object)stringBuilder.ToString());
		}

		private static string Describe(Transform t)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)t == (Object)null)
			{
				return "<null>";
			}
			return ((Object)t).name + " (localScale=" + ((object)t.localScale/*cast due to .constrained prefix*/).ToString() + ", lossyScale=" + ((object)t.lossyScale/*cast due to .constrained prefix*/).ToString() + ")";
		}

		private static void AppendTree(StringBuilder sb, Transform t, int depth)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = sb.Append(new string(' ', depth * 2)).Append(((Object)t).name).Append("  scale=");
			Vector3 localScale = t.localScale;
			stringBuilder.Append(((Vector3)(ref localScale)).ToString("F3")).AppendLine();
			if (depth < 5)
			{
				for (int i = 0; i < t.childCount; i++)
				{
					AppendTree(sb, t.GetChild(i), depth + 1);
				}
			}
		}
	}
	[HarmonyPatch(typeof(ItemValuableBox), "Start")]
	internal static class ItemValuableBox_Start_Patch
	{
		private static void Postfix(ItemValuableBox __instance)
		{
			HaulerTweaks.Apply(__instance);
			HaulerTweaks.RegisterScreen(__instance);
		}
	}
	[HarmonyPatch(typeof(TextScreen), "Update")]
	internal static class TextScreen_Update_Patch
	{
		private static void Postfix(TextScreen __instance)
		{
			HaulerTweaks.AppendRemainingLine(__instance);
		}
	}
	[HarmonyPatch(typeof(TextScreen), "SetValue")]
	internal static class TextScreen_SetValue_Patch
	{
		private static void Prefix(TextScreen __instance, ref int newValue)
		{
			if (Plugin.ShowRemaining.Value && Plugin.ReplaceMainNumber.Value && !Plugin.UnlimitedCargo.Value)
			{
				ItemValuableBox val = HaulerTweaks.BoxForScreen(__instance);
				if (!((Object)(object)val == (Object)null))
				{
					newValue = Mathf.Max(0, (int)val.valueLimit - newValue);
				}
			}
		}
	}
	[HarmonyPatch(typeof(SemiFunc), "DebugTester")]
	internal static class SemiFunc_DebugTester_Patch
	{
		private static void Postfix(ref bool __result)
		{
			if (Plugin.UnlockDebugConsole.Value)
			{
				__result = true;
			}
		}
	}
	[HarmonyPatch(typeof(DebugConsoleUI), "Awake")]
	internal static class DebugConsoleUI_Awake_Patch
	{
		private static void Postfix(DebugConsoleUI __instance)
		{
			Plugin.Log.LogInfo((object)("DebugConsoleUI is present in this scene (toggle key: " + ((object)Unsafe.As<KeyCode, KeyCode>(ref __instance.toggleKey)/*cast due to .constrained prefix*/).ToString() + "). UnlockDebugConsole=" + Plugin.UnlockDebugConsole.Value));
		}
	}
	internal static class CargoPatches
	{
		private static FieldRef<ItemValuableBox, List<PhysGrabObject>> validObjectsRef;

		private static FieldRef<ItemValuableBox, HashSet<PhysGrabObject>> tooBigRef;

		private static FieldRef<ItemValuableBox, HashSet<PhysGrabObject>> tooFullRef;

		private static FieldRef<ValuableObject, float> dollarValueRef;

		internal static void Apply(Harmony harmony)
		{
			try
			{
				validObjectsRef = AccessTools.FieldRefAccess<ItemValuableBox, List<PhysGrabObject>>("validObjectsInBox");
				tooBigRef = AccessTools.FieldRefAccess<ItemValuableBox, HashSet<PhysGrabObject>>("tooBigOffenders");
				tooFullRef = AccessTools.FieldRefAccess<ItemValuableBox, HashSet<PhysGrabObject>>("tooFullOffenders");
				dollarValueRef = AccessTools.FieldRefAccess<ValuableObject, float>("dollarValueCurrent");
				Patch(harmony, "UpdateStickyMessage", "UpdateStickyMessagePrefix");
			}
			catch (Exception ex)
			{
				validObjectsRef = null;
				Plugin.Log.LogWarning((object)("AcceptAnySize unavailable - the cargo box's internals have changed (" + ex.Message + ")."));
			}
			Patch(harmony, "UpdateTextScreen", "UpdateTextScreenPrefix");
		}

		private static void Patch(Harmony harmony, string method, string prefix)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(ItemValuableBox), method, (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					Plugin.Log.LogWarning((object)("ItemValuableBox." + method + " not found; the feature that patches it is off."));
				}
				else
				{
					harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(CargoPatches), prefix, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Could not patch ItemValuableBox." + method + ": " + ex.Message));
			}
		}

		private static void UpdateStickyMessagePrefix(ItemValuableBox __instance)
		{
			if (!Plugin.AcceptAnySize.Value || validObjectsRef == null || !SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			HashSet<PhysGrabObject> hashSet = tooBigRef.Invoke(__instance);
			if (hashSet == null || hashSet.Count == 0)
			{
				return;
			}
			List<PhysGrabObject> list = validObjectsRef.Invoke(__instance);
			HashSet<PhysGrabObject> hashSet2 = tooFullRef.Invoke(__instance);
			if (list == null)
			{
				return;
			}
			foreach (PhysGrabObject item in hashSet)
			{
				if (!((Object)(object)item == (Object)null))
				{
					ValuableObject component = ((Component)item).GetComponent<ValuableObject>();
					if ((Object)(object)component != (Object)null && hashSet2 != null && __instance.CurrentValue + dollarValueRef.Invoke(component) > __instance.valueLimit)
					{
						hashSet2.Add(item);
					}
					if (!list.Contains(item))
					{
						list.Add(item);
					}
				}
			}
			hashSet.Clear();
		}

		private static bool UpdateTextScreenPrefix()
		{
			return !Plugin.UnlimitedCargo.Value;
		}
	}
}