Decompiled source of GuaranteedGasPrinter v1.5.0

GuaranteedGasPrinter.dll

Decompiled 11 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("GuaranteedGasPrinter")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GuaranteedGasPrinter")]
[assembly: AssemblyTitle("GuaranteedGasPrinter")]
[assembly: AssemblyVersion("1.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 GuaranteedGasPrinter
{
	[BepInPlugin("com.rowan.GuaranteedGasPrinter", "GuaranteedGasPrinter", "1.5.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class GuaranteedGasPrinterPlugin : BaseUnityPlugin
	{
		public const string GUID = "com.rowan.GuaranteedGasPrinter";

		public const string NAME = "GuaranteedGasPrinter";

		public const string VERSION = "1.5.0";

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<string> TargetItem;

		internal static ConfigEntry<int> PrintersPerStage;

		internal static ConfigEntry<bool> SkipSpecialStages;

		internal static ConfigEntry<bool> Announce;

		internal static ConfigEntry<bool> VerboseLog;

		internal static ConfigEntry<bool> SpawnNearPlayer;

		internal static ConfigEntry<float> MinDistance;

		internal static ConfigEntry<float> MaxDistance;

		internal static ConfigEntry<bool> PlaceByExistingInteractable;

		internal static ManualLogSource Log;

		private static GuaranteedGasPrinterPlugin _instance;

		public void Awake()
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Expected O, but got Unknown
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Expected O, but got Unknown
			_instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Spawn a guaranteed printer for a chosen item on every stage.");
			TargetItem = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Item", "Gasoline", "Item the printer should print. Accepts the internal name (Gasoline) or the display name (Gasoline).");
			PrintersPerStage = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Printers Per Stage", 1, new ConfigDescription("How many guaranteed printers to add each stage.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 5), Array.Empty<object>()));
			SkipSpecialStages = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Skip Special Stages", true, "Don't add the printer in the Bazaar, Void Fields, Commencement, or similar non-standard stages.");
			Announce = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Announce In Chat", true, "Print a chat message when the guaranteed printer spawns.");
			VerboseLog = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Verbose Log", true, "Write detailed spawn diagnostics to the BepInEx log.");
			SpawnNearPlayer = ((BaseUnityPlugin)this).Config.Bind<bool>("Placement", "Spawn Near Player", true, "Place the guaranteed printer close to the player spawn so it is easy to find. Turn off for a random spot anywhere on the map.");
			MinDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Placement", "Min Distance", 0f, new ConfigDescription("Closest the printer may spawn to the player (metres).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), Array.Empty<object>()));
			PlaceByExistingInteractable = ((BaseUnityPlugin)this).Config.Bind<bool>("Placement", "Place Beside Existing Chest", true, "Prefer dropping the printer next to a chest or shrine the game already placed. Those sit where players actually walk, so the printer is easy to find.");
			MaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Placement", "Max Distance", 25f, new ConfigDescription("Furthest the printer may spawn from the player (metres). Keep this small so the printer lands in plain sight at stage start.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 500f), Array.Empty<object>()));
			Stage.onStageStartGlobal += OnStageStart;
			if (Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"))
			{
				try
				{
					RiskOfOptionsCompat.Init();
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("RiskOfOptions integration failed: " + ex.Message));
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"GuaranteedGasPrinter 1.5.0 loaded.");
		}

		public void OnDestroy()
		{
			Stage.onStageStartGlobal -= OnStageStart;
		}

		private static void V(string msg)
		{
			if (VerboseLog != null && VerboseLog.Value)
			{
				Log.LogInfo((object)("[GGP] " + msg));
			}
		}

		private static void OnStageStart(Stage stage)
		{
			if (!Enabled.Value)
			{
				V("disabled in config; skipping");
			}
			else if (!NetworkServer.active)
			{
				V("not server; skipping");
			}
			else if ((Object)(object)_instance == (Object)null)
			{
				Log.LogWarning((object)"[GGP] no plugin instance");
			}
			else
			{
				((MonoBehaviour)_instance).StartCoroutine(_instance.SpawnRoutine(stage));
			}
		}

		private IEnumerator SpawnRoutine(Stage stage)
		{
			yield return (object)new WaitForSeconds(2f);
			string text = "unknown";
			try
			{
				SceneDef val = (((Object)(object)stage != (Object)null) ? stage.sceneDef : null);
				if ((Object)(object)val == (Object)null)
				{
					val = SceneCatalog.GetSceneDefForCurrentScene();
				}
				if ((Object)(object)val != (Object)null)
				{
					text = val.baseSceneName ?? val.cachedName ?? "unnamed";
					V("stage start: " + text + " (type " + ((object)Unsafe.As<SceneType, SceneType>(ref val.sceneType)/*cast due to .constrained prefix*/).ToString() + ")");
					if (SkipSpecialStages.Value && (int)val.sceneType != 1)
					{
						V("scene type is not a normal Stage; skipping (turn off 'Skip Special Stages' to force)");
						yield break;
					}
				}
				else
				{
					V("no scene def available; continuing anyway");
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[GGP] scene check failed: " + ex.Message));
			}
			ItemDef val2 = FindItem(TargetItem.Value);
			if ((Object)(object)val2 == (Object)null)
			{
				Log.LogWarning((object)("[GGP] item '" + TargetItem.Value + "' not found - no printer spawned. Check the spelling in Mod Options."));
				yield break;
			}
			V("target item resolved: " + ((Object)val2).name + " (tier " + ((object)val2.tier/*cast due to .constrained prefix*/).ToString() + ")");
			InteractableSpawnCard printerCard = GetPrinterCard(val2.tier);
			if ((Object)(object)printerCard == (Object)null)
			{
				Log.LogWarning((object)("[GGP] could not load a printer spawn card for tier " + ((object)val2.tier/*cast due to .constrained prefix*/).ToString() + " - no printer spawned."));
				yield break;
			}
			V("printer card: " + ((Object)printerCard).name);
			if ((Object)(object)DirectorCore.instance == (Object)null)
			{
				Log.LogWarning((object)"[GGP] DirectorCore not ready - no printer spawned.");
				yield break;
			}
			int num = 0;
			List<float> list = new List<float>();
			for (int i = 0; i < PrintersPerStage.Value; i++)
			{
				if (SpawnOnePrinter(printerCard, val2, out var distanceFromPlayer))
				{
					num++;
					list.Add(distanceFromPlayer);
				}
			}
			V("spawned " + num + "/" + PrintersPerStage.Value + " printer(s) on " + text);
			if (num > 0 && Announce.Value)
			{
				string text2 = "";
				if (list.Count > 0 && list[0] >= 0f)
				{
					text2 = " <style=cStack>(~" + Mathf.RoundToInt(list[0]) + "m away)</style>";
				}
				Chat.AddMessage("<style=cIsUtility>Guaranteed printer:</style> " + Language.GetString(val2.nameToken) + ((num > 1) ? (" x" + num) : "") + text2);
			}
			else if (num == 0)
			{
				Log.LogWarning((object)("[GGP] every placement attempt failed on " + text + " (the stage may have no free interactable nodes)."));
			}
		}

		private IEnumerator ReassertPickup(ShopTerminalBehavior terminal, ItemDef item)
		{
			PickupIndex pickup = PickupCatalog.FindPickupIndex(item.itemIndex);
			for (int frame = 0; frame < 3; frame++)
			{
				yield return null;
				if ((Object)(object)terminal == (Object)null)
				{
					yield break;
				}
				try
				{
					terminal.SetPickupIndex(pickup, false);
				}
				catch
				{
					yield break;
				}
			}
			yield return (object)new WaitForSeconds(1f);
			if ((Object)(object)terminal != (Object)null)
			{
				try
				{
					terminal.SetPickupIndex(pickup, false);
					V("re-asserted printer stock as " + ((Object)item).name);
				}
				catch
				{
				}
			}
		}

		private static Transform FindPlayerTransform()
		{
			try
			{
				foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
				{
					if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance.master == (Object)null))
					{
						CharacterBody body = instance.master.GetBody();
						if ((Object)(object)body != (Object)null)
						{
							return ((Component)body).transform;
						}
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private static bool TryFindNearestInteractable(Vector3 from, out Vector3 position)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			position = Vector3.zero;
			try
			{
				PurchaseInteraction[] array = Object.FindObjectsOfType<PurchaseInteraction>();
				float num = float.MaxValue;
				bool flag = false;
				PurchaseInteraction[] array2 = array;
				foreach (PurchaseInteraction val in array2)
				{
					if (!((Object)(object)val == (Object)null) && ((Component)val).gameObject.activeInHierarchy)
					{
						float num2 = Vector3.Distance(from, ((Component)val).transform.position);
						if (num2 < num)
						{
							num = num2;
							position = ((Component)val).transform.position;
							flag = true;
						}
					}
				}
				if (flag)
				{
					V("anchor: nearest existing interactable is " + Mathf.RoundToInt(num) + "m away");
				}
				else
				{
					V("no existing interactables found to anchor to");
				}
				return flag;
			}
			catch (Exception ex)
			{
				V("interactable scan failed: " + ex.Message);
				return false;
			}
		}

		private bool SpawnOnePrinter(InteractableSpawnCard card, ItemDef item, out float distanceFromPlayer)
		{
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Expected O, but got Unknown
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Expected O, but got Unknown
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Expected O, but got Unknown
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Expected O, but got Unknown
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			distanceFromPlayer = -1f;
			Transform val = (SpawnNearPlayer.Value ? FindPlayerTransform() : null);
			List<KeyValuePair<string, DirectorPlacementRule>> list = new List<KeyValuePair<string, DirectorPlacementRule>>();
			if ((Object)(object)val != (Object)null)
			{
				if (PlaceByExistingInteractable.Value && TryFindNearestInteractable(val.position, out var position))
				{
					list.Add(new KeyValuePair<string, DirectorPlacementRule>("beside nearest chest/shrine", new DirectorPlacementRule
					{
						placementMode = (PlacementMode)3,
						position = position
					}));
				}
				list.Add(new KeyValuePair<string, DirectorPlacementRule>("near player " + MinDistance.Value + "-" + MaxDistance.Value + "m", new DirectorPlacementRule
				{
					placementMode = (PlacementMode)1,
					spawnOnTarget = val,
					minDistance = MinDistance.Value,
					maxDistance = MaxDistance.Value
				}));
				list.Add(new KeyValuePair<string, DirectorPlacementRule>("widened 0-200m", new DirectorPlacementRule
				{
					placementMode = (PlacementMode)1,
					spawnOnTarget = val,
					minDistance = 0f,
					maxDistance = 200f
				}));
				list.Add(new KeyValuePair<string, DirectorPlacementRule>("nearest node to player", new DirectorPlacementRule
				{
					placementMode = (PlacementMode)3,
					position = val.position
				}));
			}
			list.Add(new KeyValuePair<string, DirectorPlacementRule>("anywhere (random)", new DirectorPlacementRule
			{
				placementMode = (PlacementMode)4
			}));
			foreach (KeyValuePair<string, DirectorPlacementRule> item2 in list)
			{
				try
				{
					Xoroshiro128Plus val2 = new Xoroshiro128Plus((ulong)Random.Range(1, int.MaxValue));
					DirectorSpawnRequest val3 = new DirectorSpawnRequest((SpawnCard)(object)card, item2.Value, val2);
					val3.ignoreTeamMemberLimit = true;
					GameObject val4 = DirectorCore.instance.TrySpawnObject(val3);
					if ((Object)(object)val4 == (Object)null)
					{
						V("placement '" + item2.Key + "' found no spot; trying next");
						continue;
					}
					ShopTerminalBehavior val5 = val4.GetComponent<ShopTerminalBehavior>() ?? val4.GetComponentInChildren<ShopTerminalBehavior>();
					if ((Object)(object)val5 != (Object)null)
					{
						val5.SetPickupIndex(PickupCatalog.FindPickupIndex(item.itemIndex), false);
						((MonoBehaviour)this).StartCoroutine(ReassertPickup(val5, item));
					}
					else
					{
						V("WARNING: spawned object has no ShopTerminalBehavior");
					}
					if ((Object)(object)val != (Object)null)
					{
						distanceFromPlayer = Vector3.Distance(val.position, val4.transform.position);
					}
					string text = (((Object)(object)val != (Object)null) ? ((object)val.position/*cast due to .constrained prefix*/).ToString() : "n/a");
					float num = (((Object)(object)val != (Object)null) ? (val4.transform.position.y - val.position.y) : 0f);
					V("printer placed via '" + item2.Key + "' at " + ((object)val4.transform.position/*cast due to .constrained prefix*/).ToString() + " | player at " + text + ((distanceFromPlayer >= 0f) ? (" | " + Mathf.RoundToInt(distanceFromPlayer) + "m away, " + Mathf.RoundToInt(num) + "m vertical") : "") + " | active=" + val4.activeInHierarchy + " | stocked with " + ((Object)item).name);
					return true;
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)("[GGP] placement '" + item2.Key + "' threw: " + ex.Message));
				}
			}
			return false;
		}

		private static ItemDef FindItem(string wanted)
		{
			if (string.IsNullOrWhiteSpace(wanted))
			{
				return null;
			}
			string text = wanted.Trim().ToUpperInvariant();
			ItemDef val = null;
			for (int i = 0; i < ItemCatalog.itemCount; i++)
			{
				ItemDef itemDef = ItemCatalog.GetItemDef((ItemIndex)i);
				if ((Object)(object)itemDef == (Object)null)
				{
					continue;
				}
				if ((((Object)itemDef).name ?? "").ToUpperInvariant() == text)
				{
					return itemDef;
				}
				if ((Object)(object)val == (Object)null)
				{
					string text2 = "";
					try
					{
						text2 = Language.GetString(itemDef.nameToken) ?? "";
					}
					catch
					{
					}
					if (text2.ToUpperInvariant() == text)
					{
						val = itemDef;
					}
				}
			}
			return val;
		}

		private static InteractableSpawnCard GetPrinterCard(ItemTier tier)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected I4, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			string[] array = (tier - 1) switch
			{
				0 => new string[1] { "RoR2/Base/DuplicatorLarge/iscDuplicatorLarge.asset" }, 
				1 => new string[1] { "RoR2/Base/DuplicatorMilitary/iscDuplicatorMilitary.asset" }, 
				3 => new string[1] { "RoR2/Base/DuplicatorWild/iscDuplicatorWild.asset" }, 
				_ => new string[1] { "RoR2/Base/Duplicator/iscDuplicator.asset" }, 
			};
			foreach (string text in array)
			{
				try
				{
					InteractableSpawnCard val = Addressables.LoadAssetAsync<InteractableSpawnCard>((object)text).WaitForCompletion();
					if ((Object)(object)val != (Object)null)
					{
						return val;
					}
				}
				catch (Exception ex)
				{
					V("addressable '" + text + "' failed: " + ex.Message);
				}
			}
			try
			{
				ClassicStageInfo instance = ClassicStageInfo.instance;
				DirectorCardCategorySelection val2 = (((Object)(object)instance != (Object)null) ? instance.interactableCategories : null);
				if ((Object)(object)val2 != (Object)null)
				{
					Category[] categories = val2.categories;
					for (int i = 0; i < categories.Length; i++)
					{
						DirectorCard[] cards = categories[i].cards;
						for (int j = 0; j < cards.Length; j++)
						{
							SpawnCard spawnCard = cards[j].spawnCard;
							InteractableSpawnCard val3 = (InteractableSpawnCard)(object)((spawnCard is InteractableSpawnCard) ? spawnCard : null);
							if ((Object)(object)val3 != (Object)null && (Object)(object)((SpawnCard)val3).prefab != (Object)null && (Object)(object)((SpawnCard)val3).prefab.GetComponentInChildren<ShopTerminalBehavior>() != (Object)null)
							{
								V("fallback card from stage: " + ((Object)val3).name);
								return val3;
							}
						}
					}
				}
			}
			catch (Exception ex2)
			{
				V("stage-card fallback failed: " + ex2.Message);
			}
			return null;
		}
	}
	internal static class RiskOfOptionsCompat
	{
		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void Init()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_00ba: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Expected O, but got Unknown
			ModSettingsManager.SetModDescription("Guarantees a 3D printer for a chosen item on every stage.");
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(GuaranteedGasPrinterPlugin.Enabled));
			ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(GuaranteedGasPrinterPlugin.TargetItem));
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(GuaranteedGasPrinterPlugin.PrintersPerStage, new IntSliderConfig
			{
				min = 1,
				max = 5
			}));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(GuaranteedGasPrinterPlugin.SkipSpecialStages));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(GuaranteedGasPrinterPlugin.Announce));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(GuaranteedGasPrinterPlugin.VerboseLog));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(GuaranteedGasPrinterPlugin.SpawnNearPlayer));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(GuaranteedGasPrinterPlugin.PlaceByExistingInteractable));
			ModSettingsManager.AddOption((BaseOption)new SliderOption(GuaranteedGasPrinterPlugin.MinDistance, new SliderConfig
			{
				min = 0f,
				max = 200f
			}));
			ModSettingsManager.AddOption((BaseOption)new SliderOption(GuaranteedGasPrinterPlugin.MaxDistance, new SliderConfig
			{
				min = 10f,
				max = 500f
			}));
		}
	}
}