Decompiled source of S1API Forked v2.8.1

Mods/S1API.Il2Cpp.MelonLoader.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using HarmonyLib;
using Il2Cpp;
using Il2CppFishNet;
using Il2CppFishNet.Connection;
using Il2CppFishNet.Managing;
using Il2CppFishNet.Managing.Client;
using Il2CppFishNet.Managing.Object;
using Il2CppFishNet.Managing.Scened;
using Il2CppFishNet.Managing.Server;
using Il2CppFishNet.Managing.Transporting;
using Il2CppFishNet.Object;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne;
using Il2CppScheduleOne.AvatarFramework;
using Il2CppScheduleOne.AvatarFramework.Animation;
using Il2CppScheduleOne.AvatarFramework.Customization;
using Il2CppScheduleOne.AvatarFramework.Equipping;
using Il2CppScheduleOne.Building;
using Il2CppScheduleOne.Calling;
using Il2CppScheduleOne.Cartel;
using Il2CppScheduleOne.Combat;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Dialogue;
using Il2CppScheduleOne.Economy;
using Il2CppScheduleOne.Effects;
using Il2CppScheduleOne.EntityFramework;
using Il2CppScheduleOne.Equipping;
using Il2CppScheduleOne.GameTime;
using Il2CppScheduleOne.Growing;
using Il2CppScheduleOne.Interaction;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.Law;
using Il2CppScheduleOne.Levelling;
using Il2CppScheduleOne.Map;
using Il2CppScheduleOne.Messaging;
using Il2CppScheduleOne.Money;
using Il2CppScheduleOne.NPCs;
using Il2CppScheduleOne.NPCs.Actions;
using Il2CppScheduleOne.NPCs.Behaviour;
using Il2CppScheduleOne.NPCs.Relation;
using Il2CppScheduleOne.NPCs.Responses;
using Il2CppScheduleOne.NPCs.Schedules;
using Il2CppScheduleOne.Noise;
using Il2CppScheduleOne.ObjectScripts;
using Il2CppScheduleOne.Persistence;
using Il2CppScheduleOne.Persistence.Datas;
using Il2CppScheduleOne.Persistence.Loaders;
using Il2CppScheduleOne.PlayerScripts;
using Il2CppScheduleOne.PlayerScripts.Health;
using Il2CppScheduleOne.Police;
using Il2CppScheduleOne.Product;
using Il2CppScheduleOne.Product.Packaging;
using Il2CppScheduleOne.Property;
using Il2CppScheduleOne.Quests;
using Il2CppScheduleOne.ScriptableObjects;
using Il2CppScheduleOne.Storage;
using Il2CppScheduleOne.UI;
using Il2CppScheduleOne.UI.MainMenu;
using Il2CppScheduleOne.UI.Phone;
using Il2CppScheduleOne.UI.Phone.ContactsApp;
using Il2CppScheduleOne.UI.Phone.Messages;
using Il2CppScheduleOne.UI.Phone.ProductManagerApp;
using Il2CppScheduleOne.UI.Relations;
using Il2CppScheduleOne.UI.Shop;
using Il2CppScheduleOne.UI.WorldspacePopup;
using Il2CppScheduleOne.Variables;
using Il2CppScheduleOne.Vehicles;
using Il2CppScheduleOne.Vehicles.Modification;
using Il2CppScheduleOne.Vision;
using Il2CppScheduleOne.VoiceOver;
using Il2CppSystem;
using Il2CppSystem.Collections;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using S1API;
using S1API.AssetBundles;
using S1API.Avatar;
using S1API.Building;
using S1API.Conditions;
using S1API.Console;
using S1API.Economy;
using S1API.Entities;
using S1API.Entities.Appearances.AccessoryFields;
using S1API.Entities.Appearances.Base;
using S1API.Entities.Appearances.BodyLayerFields;
using S1API.Entities.Appearances.CustomizationFields;
using S1API.Entities.Appearances.FaceLayerFields;
using S1API.Entities.Behaviour;
using S1API.Entities.Customer;
using S1API.Entities.Dealer;
using S1API.Entities.Dialogue;
using S1API.Entities.Interfaces;
using S1API.Entities.Relation;
using S1API.Entities.Schedule;
using S1API.GameTime;
using S1API.Internal;
using S1API.Internal.Abstraction;
using S1API.Internal.Entities;
using S1API.Internal.Items;
using S1API.Internal.Lifecycle;
using S1API.Internal.Map;
using S1API.Internal.Patches;
using S1API.Internal.Shops;
using S1API.Internal.Utils;
using S1API.Items;
using S1API.Law;
using S1API.Lifecycle;
using S1API.Logging;
using S1API.Map;
using S1API.Map.Buildings;
using S1API.Map.DeliveryLocations;
using S1API.Messaging;
using S1API.Money;
using S1API.PhoneApp;
using S1API.PhoneCalls;
using S1API.PhoneCalls.Constants;
using S1API.Products;
using S1API.Properties;
using S1API.Properties.Interfaces;
using S1API.Properties.Internal;
using S1API.Properties.Tokens;
using S1API.Quests;
using S1API.Quests.Constants;
using S1API.Quests.Identifiers;
using S1API.Saveables;
using S1API.Shops;
using S1API.Storage;
using S1API.Storages;
using S1API.Utils;
using S1API.Vehicles;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(global::S1API.S1API), "S1API (Forked by Bars)", "2.8.1", "KaBooMa", null)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ifBars")]
[assembly: AssemblyConfiguration("Il2CppMelon")]
[assembly: AssemblyDescription("A Schedule One Mono / Il2Cpp Cross Compatibility Layer (Forked from the original S1API by Kabooma)")]
[assembly: AssemblyFileVersion("2.8.1.0")]
[assembly: AssemblyInformationalVersion("2.8.1+f356ae01af1cc38d41ccb07070a54ab1e614b497")]
[assembly: AssemblyProduct("S1API")]
[assembly: AssemblyTitle("S1API")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ifBars/S1API")]
[assembly: AssemblyVersion("2.8.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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;
		}
	}
}
public class ClickHandler
{
	private readonly UnityAction _callback;

	public ClickHandler(UnityAction callback)
	{
		_callback = callback;
	}

	public void OnClick()
	{
		_callback.Invoke();
	}
}
namespace S1API
{
	public class S1API : MelonMod
	{
		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (sceneName == "Main")
			{
				GameLifecycle.Initialize();
			}
		}

		public override void OnSceneWasUnloaded(int buildIndex, string sceneName)
		{
			SceneStateCleaner.ResetForSceneChange(sceneName, afterUnload: true);
			if (sceneName == "Main")
			{
				GameLifecycle.Reset();
			}
		}

		public override void OnSceneWasInitialized(int buildIndex, string sceneName)
		{
			NPCNetworkBootstrap.EnsurePrefabsWarmup();
			SceneStateCleaner.ResetForSceneChange(sceneName, afterUnload: false);
		}
	}
}
namespace S1API.Vehicles
{
	public class LandVehicle
	{
		internal LandVehicle S1LandVehicle = null;

		internal bool _isDeferredByName = false;

		internal StorageInstance _storage;

		private static readonly Log _logger = new Log("S1API.LandVehicle");

		private static readonly FieldInfo? VehiclePriceField = typeof(LandVehicle).GetField("vehiclePrice", BindingFlags.NonPublic);

		private NetworkConnection? _conn;

		private string _guid = string.Empty;

		public float VehiclePrice
		{
			get
			{
				return S1LandVehicle.VehiclePrice;
			}
			set
			{
				VehiclePriceField?.SetValue(S1LandVehicle, value);
			}
		}

		public float TopSpeed
		{
			get
			{
				return S1LandVehicle.TopSpeed;
			}
			set
			{
				S1LandVehicle.TopSpeed = value;
			}
		}

		public bool IsPlayerOwned
		{
			get
			{
				return S1LandVehicle.IsPlayerOwned;
			}
			set
			{
				SetIsPlayerOwned(value);
			}
		}

		public VehicleColor Color
		{
			get
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Expected I4, but got Unknown
				return (VehicleColor)S1LandVehicle.OwnedColor;
			}
			set
			{
				SetColor(value);
			}
		}

		public string GUID => _guid;

		public StorageInstance Storage => _storage;

		public LandVehicle(string vehicleCode)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			LandVehicle vehiclePrefab = NetworkSingleton<VehicleManager>.Instance.GetVehiclePrefab(vehicleCode);
			if ((Object)(object)vehiclePrefab == (Object)null)
			{
				_logger.Error("SpawnVehicle: '" + vehicleCode + "' is not a valid vehicle code!");
				return;
			}
			LandVehicle component = Object.Instantiate<GameObject>(((Component)vehiclePrefab).gameObject).GetComponent<LandVehicle>();
			component.SetGUID(GUIDManager.GenerateUniqueGUID());
			NetworkSingleton<VehicleManager>.Instance.AllVehicles.Add(component);
			S1LandVehicle = component;
			SetConnection();
			UpdateGuidFromGame();
			_storage = new StorageInstance(component.Storage);
		}

		public void Spawn(Vector3 position, Quaternion rotation)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (!InstanceFinder.IsServer)
			{
				_logger.Warning("Spawn can only be called on the server!");
				return;
			}
			if ((Object)(object)S1LandVehicle == (Object)null)
			{
				throw new Exception("Unable to spawn vehicle, S1LandVehicle is null!");
			}
			((Component)S1LandVehicle).transform.position = position;
			((Component)S1LandVehicle).transform.rotation = rotation;
			((NetworkBehaviour)NetworkSingleton<VehicleManager>.Instance).Spawn(((Component)S1LandVehicle).gameObject, (NetworkConnection)null, default(Scene));
		}

		internal LandVehicle(LandVehicle landVehicle)
		{
			S1LandVehicle = landVehicle;
			SetConnection();
			UpdateGuidFromGame();
			_storage = new StorageInstance(landVehicle.Storage);
			_isDeferredByName = false;
		}

		internal LandVehicle(string vehicleName, bool isDeferred)
		{
			_isDeferredByName = isDeferred;
		}

		private void SetConnection()
		{
			NetworkManager networkManager = InstanceFinder.NetworkManager;
			if (networkManager.IsClientOnly)
			{
				NetworkConnection connection = InstanceFinder.ClientManager.Connection;
				if (connection != (NetworkConnection)null && connection.IsValid)
				{
					_conn = connection;
				}
			}
			else if (networkManager.IsServerOnly || (networkManager.IsServer && !networkManager.IsClient))
			{
				NetworkConnection owner = ((NetworkBehaviour)S1LandVehicle).Owner;
				if (owner != (NetworkConnection)null && owner.IsValid)
				{
					_conn = owner;
				}
			}
		}

		private void SetIsPlayerOwned(bool isPlayerOwned)
		{
			S1LandVehicle.SetIsPlayerOwned(_conn, isPlayerOwned);
			if (isPlayerOwned)
			{
				NetworkSingleton<VehicleManager>.Instance.PlayerOwnedVehicles.Add(S1LandVehicle);
			}
			else
			{
				NetworkSingleton<VehicleManager>.Instance.PlayerOwnedVehicles.Remove(S1LandVehicle);
			}
		}

		private void SetColor(VehicleColor color)
		{
			MethodInfo method = typeof(LandVehicle).GetMethod("SetOwnedColor", BindingFlags.Instance | BindingFlags.NonPublic);
			if (method == null)
			{
				_logger.Error("SetOwnedColor method not found!");
				return;
			}
			method.Invoke(S1LandVehicle, new object[2]
			{
				_conn,
				(object)(EVehicleColor)color
			});
		}

		private void UpdateGuidFromGame()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				PropertyInfo property = typeof(LandVehicle).GetProperty("GUID", BindingFlags.Instance | BindingFlags.Public);
				if (!(property == null))
				{
					Guid val = (Guid)(property.GetValue(S1LandVehicle) ?? ((object)default(Guid)));
					_guid = ((object)(Guid)(ref val)).ToString();
				}
			}
			catch
			{
			}
		}
	}
	public enum ParkingAlignment
	{
		FrontToKerb,
		RearToKerb
	}
	public enum VehicleColor
	{
		Black,
		DarkGrey,
		LightGrey,
		White,
		Yellow,
		Orange,
		Red,
		DullRed,
		Pink,
		Purple,
		Navy,
		DarkBlue,
		LightBlue,
		Cyan,
		LightGreen,
		DarkGreen,
		Custom
	}
	public static class VehicleRegistry
	{
		private static readonly Dictionary<object, LandVehicle> _cache = new Dictionary<object, LandVehicle>();

		public static LandVehicle[] GetAll()
		{
			try
			{
				List<LandVehicle> allVehicles = NetworkSingleton<VehicleManager>.Instance.AllVehicles;
				if (allVehicles == null)
				{
					return Array.Empty<LandVehicle>();
				}
				List<LandVehicle> list = new List<LandVehicle>();
				Enumerator<LandVehicle> enumerator = allVehicles.GetEnumerator();
				while (enumerator.MoveNext())
				{
					LandVehicle current = enumerator.Current;
					if ((Object)(object)current != (Object)null)
					{
						LandVehicle landVehicle = Wrap(current);
						if (landVehicle != null)
						{
							list.Add(landVehicle);
						}
					}
				}
				return list.ToArray();
			}
			catch
			{
				return Array.Empty<LandVehicle>();
			}
		}

		public static LandVehicle GetByGUID(string guid)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(guid))
			{
				return null;
			}
			try
			{
				Guid val = default(Guid);
				((Guid)(ref val))..ctor(guid);
				LandVehicle @object = GUIDManager.GetObject<LandVehicle>(val);
				if ((Object)(object)@object == (Object)null)
				{
					return null;
				}
				return Wrap(@object);
			}
			catch
			{
				return null;
			}
		}

		public static LandVehicle GetByName(string gameObjectName)
		{
			if (string.IsNullOrEmpty(gameObjectName))
			{
				return null;
			}
			try
			{
				GameObject val = GameObject.Find(gameObjectName);
				if ((Object)(object)val != (Object)null)
				{
					LandVehicle component = val.GetComponent<LandVehicle>();
					if ((Object)(object)component != (Object)null)
					{
						return Wrap(component);
					}
				}
				List<LandVehicle> allVehicles = NetworkSingleton<VehicleManager>.Instance.AllVehicles;
				if (allVehicles != null)
				{
					for (int i = 0; i < allVehicles.Count; i++)
					{
						LandVehicle val2 = allVehicles[i];
						if ((Object)(object)val2 != (Object)null && ((Object)((Component)val2).gameObject).name == gameObjectName)
						{
							return Wrap(val2);
						}
					}
				}
				if (DeferredMapResolver.IsMenuScene())
				{
					LandVehicle deferredVehicle = new LandVehicle(gameObjectName, isDeferred: true);
					DeferredMapResolver.RegisterDeferredLookup(new DeferredLookup(gameObjectName, delegate(object resolved)
					{
						if (resolved is LandVehicle landVehicle && landVehicle != null && (Object)(object)landVehicle.S1LandVehicle != (Object)null)
						{
							deferredVehicle.S1LandVehicle = landVehicle.S1LandVehicle;
							deferredVehicle._isDeferredByName = false;
						}
					}));
					return deferredVehicle;
				}
				return null;
			}
			catch
			{
				return null;
			}
		}

		public static LandVehicle CreateVehicle(string vehicleCode)
		{
			if (!string.IsNullOrEmpty(vehicleCode))
			{
				try
				{
					return new LandVehicle(vehicleCode);
				}
				catch
				{
					return null;
				}
			}
			return null;
		}

		private static LandVehicle Wrap(LandVehicle veh)
		{
			if ((Object)(object)veh == (Object)null)
			{
				return null;
			}
			if (_cache.TryGetValue(veh, out LandVehicle value))
			{
				return value;
			}
			LandVehicle landVehicle = new LandVehicle(veh);
			_cache[veh] = landVehicle;
			return landVehicle;
		}
	}
}
namespace S1API.Utils
{
	public static class ReflectionUtils
	{
		public static MethodInfo? GetMethod(Type? type, string methodName, BindingFlags bindingFlags)
		{
			return global::S1API.Internal.Utils.ReflectionUtils.GetMethod(type, methodName, bindingFlags);
		}

		public static bool IsValueTuple(this object obj)
		{
			return global::S1API.Internal.Utils.ReflectionUtils.IsValueTuple(obj);
		}

		public static object[]? GetValueTupleItems(this object obj)
		{
			return global::S1API.Internal.Utils.ReflectionUtils.GetValueTupleItems(obj);
		}

		public static bool TrySetFieldOrProperty(object target, string memberName, object value)
		{
			return global::S1API.Internal.Utils.ReflectionUtils.TrySetFieldOrProperty(target, memberName, value);
		}

		public static object? TryGetFieldOrProperty(object target, string memberName)
		{
			return global::S1API.Internal.Utils.ReflectionUtils.TryGetFieldOrProperty(target, memberName);
		}
	}
}
namespace S1API.UI
{
	public static class CharacterCreatorManager
	{
		[CompilerGenerated]
		private sealed class <RestoreAfterClose>d__27 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <RestoreAfterClose>d__27(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = RestoreGameState();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <RestoreGameState>d__28 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			private PlayerCamera <camera>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <RestoreGameState>d__28(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<camera>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					if (PlayerSingleton<PlayerCamera>.InstanceExists)
					{
						<camera>5__1 = PlayerSingleton<PlayerCamera>.Instance;
						PlayerCamera obj = <camera>5__1;
						CharacterCreator s1Creator = _s1Creator;
						obj.RemoveActiveUIElement(((s1Creator != null) ? ((Object)s1Creator).name : null) ?? "CharacterCreator");
						if (<camera>5__1.activeUIElementCount == 0)
						{
							<camera>5__1.StopTransformOverride(0f, true, false);
							<camera>5__1.StopFOVOverride(0f);
							<camera>5__1.SetCanLook(true);
							<camera>5__1.LockMouse();
						}
						<camera>5__1 = null;
					}
					if (PlayerSingleton<PlayerMovement>.InstanceExists)
					{
						PlayerSingleton<PlayerMovement>.Instance.CanMove = true;
					}
					if (PlayerSingleton<PlayerInventory>.InstanceExists)
					{
						PlayerSingleton<PlayerInventory>.Instance.SetInventoryEnabled(true);
					}
					if (Singleton<HUD>.InstanceExists)
					{
						((Behaviour)Singleton<HUD>.Instance.canvas).enabled = true;
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private static readonly Log Logger = new Log("CharacterCreatorManager");

		private static CharacterCreator _s1Creator;

		private static bool _isInitialized;

		private static bool _eventsRegistered;

		public static bool IsOpen
		{
			get
			{
				EnsureInitialized();
				CharacterCreator s1Creator = _s1Creator;
				return s1Creator != null && s1Creator.IsOpen;
			}
		}

		public static BasicAvatarSettings ActiveSettings
		{
			get
			{
				EnsureInitialized();
				CharacterCreator s1Creator = _s1Creator;
				if ((Object)(object)((s1Creator != null) ? s1Creator.ActiveSettings : null) == (Object)null)
				{
					return null;
				}
				return new BasicAvatarSettings(_s1Creator.ActiveSettings);
			}
		}

		public static event Action OnOpened;

		public static event Action OnClosed;

		public static event Action<BasicAvatarSettings> OnCompleted;

		public static void Open(BasicAvatarSettings initialSettings = null, bool showUI = true)
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Error("CharacterCreator singleton is not available");
				return;
			}
			if (_s1Creator.IsOpen)
			{
				Logger.Warning("CharacterCreator is already open");
				return;
			}
			RegisterEvents();
			if (initialSettings == null)
			{
				initialSettings = GetPlayerAvatarSettings();
			}
			if (showUI && PlayerSingleton<PlayerCamera>.InstanceExists)
			{
				PlayerSingleton<PlayerCamera>.Instance.AddActiveUIElement(((Object)_s1Creator).name);
			}
			BasicAvatarSettings val = initialSettings?.S1BasicAvatarSettings;
			_s1Creator.Open(val, showUI);
			try
			{
				CharacterCreatorManager.OnOpened?.Invoke();
			}
			catch (Exception value)
			{
				Logger.Error($"Error in OnOpened event handler: {value}");
			}
		}

		public static void Close()
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Error("CharacterCreator singleton is not available");
				return;
			}
			if (!_s1Creator.IsOpen)
			{
				Logger.Warning("CharacterCreator is not open");
				return;
			}
			_s1Creator.Close();
			MelonCoroutines.Start(RestoreAfterClose());
			try
			{
				CharacterCreatorManager.OnClosed?.Invoke();
			}
			catch (Exception value)
			{
				Logger.Error($"Error in OnClosed event handler: {value}");
			}
		}

		public static void Complete()
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Error("CharacterCreator singleton is not available");
			}
			else if (!_s1Creator.IsOpen)
			{
				Logger.Warning("CharacterCreator is not open");
			}
			else
			{
				_s1Creator.Done();
			}
		}

		public static void SelectPreset(string presetName)
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Error("CharacterCreator singleton is not available");
			}
			else if (!_s1Creator.IsOpen)
			{
				Logger.Warning("CharacterCreator must be open to select a preset");
			}
			else if (string.IsNullOrWhiteSpace(presetName))
			{
				Logger.Warning("Preset name cannot be null or empty");
			}
			else
			{
				_s1Creator.SelectPreset(presetName);
			}
		}

		public static string[] GetAvailablePresets()
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null || _s1Creator.Presets == null)
			{
				return Array.Empty<string>();
			}
			List<string> list = new List<string>();
			for (int i = 0; i < _s1Creator.Presets.Count; i++)
			{
				BasicAvatarSettings val = _s1Creator.Presets[i];
				if ((Object)(object)val != (Object)null && !string.IsNullOrWhiteSpace(((Object)val).name))
				{
					list.Add(((Object)val).name);
				}
			}
			return list.ToArray();
		}

		public static void SetRigRotation(float normalizedValue)
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Error("CharacterCreator singleton is not available");
			}
			else if (!_s1Creator.IsOpen)
			{
				Logger.Warning("CharacterCreator must be open to set rig rotation");
			}
			else
			{
				_s1Creator.SliderChanged(Mathf.Clamp01(normalizedValue));
			}
		}

		public static void PreRegisterAsActiveUI()
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Warning("CharacterCreator singleton is not available for pre-registration");
			}
			else if (PlayerSingleton<PlayerCamera>.InstanceExists)
			{
				PlayerSingleton<PlayerCamera>.Instance.AddActiveUIElement(((Object)_s1Creator).name);
			}
		}

		private static void EnsureInitialized()
		{
			if (_isInitialized)
			{
				return;
			}
			try
			{
				_s1Creator = Singleton<CharacterCreator>.Instance;
				if ((Object)(object)_s1Creator == (Object)null)
				{
					Logger.Warning("CharacterCreator singleton not found. Make sure you're in the correct scene.");
				}
				_isInitialized = true;
			}
			catch (Exception value)
			{
				Logger.Error($"Failed to initialize CharacterCreatorManager: {value}");
				_isInitialized = true;
			}
		}

		private static void RegisterEvents()
		{
			if (_eventsRegistered || (Object)(object)_s1Creator == (Object)null)
			{
				return;
			}
			try
			{
				if (_s1Creator.onComplete != null)
				{
					_s1Creator.onComplete.AddListener(UnityAction<BasicAvatarSettings>.op_Implicit((Action<BasicAvatarSettings>)OnCreatorCompleted));
				}
				_eventsRegistered = true;
			}
			catch (Exception value)
			{
				Logger.Error($"Failed to register CharacterCreator events: {value}");
			}
		}

		private static void OnCreatorCompleted(BasicAvatarSettings s1Settings)
		{
			try
			{
				if ((Object)(object)s1Settings == (Object)null)
				{
					Logger.Warning("CharacterCreator completed with null settings");
					return;
				}
				BasicAvatarSettings obj = new BasicAvatarSettings(s1Settings);
				MelonCoroutines.Start(RestoreGameState());
				CharacterCreatorManager.OnCompleted?.Invoke(obj);
			}
			catch (Exception value)
			{
				Logger.Error($"Error in OnCompleted event handler: {value}");
			}
		}

		[IteratorStateMachine(typeof(<RestoreAfterClose>d__27))]
		private static IEnumerator RestoreAfterClose()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RestoreAfterClose>d__27(0);
		}

		[IteratorStateMachine(typeof(<RestoreGameState>d__28))]
		private static IEnumerator RestoreGameState()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RestoreGameState>d__28(0);
		}

		private static BasicAvatarSettings GetPlayerAvatarSettings()
		{
			try
			{
				Player local = Player.Local;
				if (local == null || (Object)(object)local.S1Player == (Object)null)
				{
					Logger.Warning("Local player not available");
					return null;
				}
				BasicAvatarSettings currentAvatarSettings = local.S1Player.CurrentAvatarSettings;
				if ((Object)(object)currentAvatarSettings == (Object)null)
				{
					Logger.Msg("Player has no current avatar settings, using default");
					return null;
				}
				BasicAvatarSettings settings = Object.Instantiate<BasicAvatarSettings>(currentAvatarSettings);
				return new BasicAvatarSettings(settings);
			}
			catch (Exception value)
			{
				Logger.Error($"Failed to get player avatar settings: {value}");
				return null;
			}
		}
	}
	public sealed class MainMenuRig
	{
		internal readonly MainMenuRig S1MainMenuRig;

		public global::S1API.Avatar.Avatar? Avatar
		{
			get
			{
				if ((Object)(object)S1MainMenuRig == (Object)null || (Object)(object)S1MainMenuRig.Avatar == (Object)null)
				{
					return null;
				}
				return new global::S1API.Avatar.Avatar(S1MainMenuRig.Avatar);
			}
		}

		internal MainMenuRig(MainMenuRig mainMenuRig)
		{
			S1MainMenuRig = mainMenuRig;
		}

		public static MainMenuRig[] FindInScene(bool includeInactive = false)
		{
			Il2CppArrayBase<MainMenuRig> val = Object.FindObjectsOfType<MainMenuRig>(includeInactive);
			if (val == null || val.Length == 0)
			{
				return Array.Empty<MainMenuRig>();
			}
			return (from r in (IEnumerable<MainMenuRig>)val
				where (Object)(object)r != (Object)null
				select new MainMenuRig(r)).ToArray();
		}
	}
	public static class UIFactory
	{
		private static Sprite roundedSprite;

		public static GameObject Panel(string name, Transform parent, Color bgColor, Vector2? anchorMin = null, Vector2? anchorMax = null, bool fullAnchor = false)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			if (fullAnchor)
			{
				val2.anchorMin = Vector2.zero;
				val2.anchorMax = Vector2.one;
				val2.offsetMin = Vector2.zero;
				val2.offsetMax = Vector2.zero;
			}
			else
			{
				val2.anchorMin = (Vector2)(((??)anchorMin) ?? new Vector2(0.5f, 0.5f));
				val2.anchorMax = (Vector2)(((??)anchorMax) ?? new Vector2(0.5f, 0.5f));
			}
			Image val3 = val.AddComponent<Image>();
			((Graphic)val3).color = bgColor;
			return val;
		}

		public static Text Text(string name, string content, Transform parent, int fontSize = 14, TextAnchor anchor = 0, FontStyle style = 0)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			Text val3 = val.AddComponent<Text>();
			val3.text = content;
			val3.fontSize = fontSize;
			val3.alignment = anchor;
			val3.fontStyle = style;
			val3.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			((Graphic)val3).color = Color.white;
			val3.horizontalOverflow = (HorizontalWrapMode)0;
			val3.verticalOverflow = (VerticalWrapMode)1;
			return val3;
		}

		public static RectTransform ScrollableVerticalList(string name, Transform parent, out ScrollRect scrollRect)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			scrollRect = val.AddComponent<ScrollRect>();
			scrollRect.horizontal = false;
			GameObject val3 = new GameObject("Viewport");
			val3.transform.SetParent(val.transform, false);
			RectTransform val4 = val3.AddComponent<RectTransform>();
			val4.anchorMin = Vector2.zero;
			val4.anchorMax = Vector2.one;
			val4.offsetMin = Vector2.zero;
			val4.offsetMax = Vector2.zero;
			((Graphic)val3.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.05f);
			val3.AddComponent<Mask>().showMaskGraphic = false;
			scrollRect.viewport = val4;
			GameObject val5 = new GameObject("Content");
			val5.transform.SetParent(val3.transform, false);
			RectTransform val6 = val5.AddComponent<RectTransform>();
			val6.anchorMin = new Vector2(0f, 1f);
			val6.anchorMax = new Vector2(1f, 1f);
			val6.pivot = new Vector2(0.5f, 1f);
			VerticalLayoutGroup val7 = val5.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val7).spacing = 10f;
			((LayoutGroup)val7).padding = new RectOffset(10, 10, 10, 10);
			((HorizontalOrVerticalLayoutGroup)val7).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)val7).childForceExpandHeight = false;
			val5.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			scrollRect.content = val6;
			return val6;
		}

		public static void FitContentHeight(RectTransform content)
		{
			ContentSizeFitter val = ((Component)content).gameObject.GetComponent<ContentSizeFitter>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)content).gameObject.AddComponent<ContentSizeFitter>();
			}
			val.verticalFit = (FitMode)2;
		}

		public static (GameObject, Button, Text) RoundedButtonWithLabel(string name, string label, Transform parent, Color bgColor, float width, float height, int fontSize, Color textColor)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_002c: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Expected O, but got Unknown
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name + "_RoundedMask");
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.sizeDelta = new Vector2(width, height);
			LayoutElement val3 = val.AddComponent<LayoutElement>();
			val3.preferredWidth = width;
			val3.preferredHeight = height;
			Image val4 = val.AddComponent<Image>();
			val4.sprite = GetRoundedSprite();
			val4.type = (Type)1;
			((Graphic)val4).color = Color.white;
			Mask val5 = val.AddComponent<Mask>();
			val5.showMaskGraphic = true;
			GameObject val6 = new GameObject(name);
			val6.transform.SetParent(val.transform, false);
			RectTransform val7 = val6.AddComponent<RectTransform>();
			val7.anchorMin = Vector2.zero;
			val7.anchorMax = Vector2.one;
			val7.offsetMin = Vector2.zero;
			val7.offsetMax = Vector2.zero;
			Image val8 = val6.AddComponent<Image>();
			((Graphic)val8).color = bgColor;
			val8.sprite = GetRoundedSprite();
			val8.type = (Type)1;
			Button val9 = val6.AddComponent<Button>();
			((Selectable)val9).targetGraphic = (Graphic)(object)val8;
			GameObject val10 = new GameObject("Label");
			val10.transform.SetParent(val6.transform, false);
			RectTransform val11 = val10.AddComponent<RectTransform>();
			val11.anchorMin = Vector2.zero;
			val11.anchorMax = Vector2.one;
			val11.offsetMin = Vector2.zero;
			val11.offsetMax = Vector2.zero;
			Text val12 = val10.AddComponent<Text>();
			val12.text = label;
			val12.alignment = (TextAnchor)4;
			val12.fontSize = fontSize;
			val12.fontStyle = (FontStyle)1;
			((Graphic)val12).color = textColor;
			val12.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			return (val, val9, val12);
		}

		private static Sprite GetRoundedSprite()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: 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_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)roundedSprite != (Object)null)
			{
				return roundedSprite;
			}
			int num = 32;
			Texture2D val = new Texture2D(num, num, (TextureFormat)5, false);
			Color32 val2 = default(Color32);
			((Color32)(ref val2))..ctor((byte)0, (byte)0, (byte)0, (byte)0);
			Color32 val3 = default(Color32);
			((Color32)(ref val3))..ctor(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
			float num2 = 6f;
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					bool flag = ((float)j < num2 && (float)i < num2 && Vector2.Distance(new Vector2((float)j, (float)i), new Vector2(num2, num2)) > num2) || ((float)j > (float)num - num2 - 1f && (float)i < num2 && Vector2.Distance(new Vector2((float)j, (float)i), new Vector2((float)num - num2 - 1f, num2)) > num2) || ((float)j < num2 && (float)i > (float)num - num2 - 1f && Vector2.Distance(new Vector2((float)j, (float)i), new Vector2(num2, (float)num - num2 - 1f)) > num2) || ((float)j > (float)num - num2 - 1f && (float)i > (float)num - num2 - 1f && Vector2.Distance(new Vector2((float)j, (float)i), new Vector2((float)num - num2 - 1f, (float)num - num2 - 1f)) > num2);
					val.SetPixel(j, i, Color32.op_Implicit(flag ? val2 : val3));
				}
			}
			val.Apply();
			Vector4 val4 = default(Vector4);
			((Vector4)(ref val4))..ctor(8f, 8f, 8f, 8f);
			roundedSprite = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, val4);
			return roundedSprite;
		}

		public static GameObject ButtonRow(string name, Transform parent, float spacing = 12f, TextAnchor alignment = 4)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			HorizontalLayoutGroup val3 = val.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val3).spacing = spacing;
			((LayoutGroup)val3).childAlignment = alignment;
			((HorizontalOrVerticalLayoutGroup)val3).childControlWidth = false;
			((HorizontalOrVerticalLayoutGroup)val3).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)val3).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val3).childForceExpandHeight = false;
			return val;
		}

		public static (GameObject, Button, Text) ButtonWithLabel(string name, string label, Transform parent, Color bgColor, float Width, float Height)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.sizeDelta = new Vector2(Height, Width);
			Image val3 = val.AddComponent<Image>();
			((Graphic)val3).color = bgColor;
			val3.sprite = Resources.GetBuiltinResource<Sprite>("UI/Skin/UISprite.psd");
			val3.type = (Type)1;
			Button val4 = val.AddComponent<Button>();
			((Selectable)val4).targetGraphic = (Graphic)(object)val3;
			GameObject val5 = new GameObject("Label");
			val5.transform.SetParent(val.transform, false);
			RectTransform val6 = val5.AddComponent<RectTransform>();
			val6.anchorMin = Vector2.zero;
			val6.anchorMax = Vector2.one;
			val6.offsetMin = Vector2.zero;
			val6.offsetMax = Vector2.zero;
			Text val7 = val5.AddComponent<Text>();
			val7.text = label;
			val7.alignment = (TextAnchor)4;
			val7.fontSize = 16;
			val7.fontStyle = (FontStyle)1;
			((Graphic)val7).color = Color.white;
			val7.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			return (val, val4, val7);
		}

		public static void SetIcon(Sprite sprite, Transform parent)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0022: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Icon");
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			Image val3 = val.AddComponent<Image>();
			val3.sprite = sprite;
			val3.preserveAspect = true;
		}

		public static void CreateTextBlock(Transform parent, string title, string subtitle, bool isCompleted)
		{
			Text(((Object)parent).name + "Title", title, parent, 16, (TextAnchor)3, (FontStyle)1);
			Text(((Object)parent).name + "Subtitle", subtitle, parent, 14, (TextAnchor)0, (FontStyle)0);
			if (isCompleted)
			{
				Text("CompletedLabel", "<color=#888888><i>Already Delivered</i></color>", parent, 12, (TextAnchor)0, (FontStyle)0);
			}
		}

		public static void CreateRowButton(GameObject go, UnityAction clickHandler, bool enabled)
		{
			Button val = go.AddComponent<Button>();
			Image component = go.GetComponent<Image>();
			((Selectable)val).targetGraphic = (Graphic)(object)component;
			((Selectable)val).interactable = enabled;
			((UnityEvent)val.onClick).AddListener(clickHandler);
		}

		public static void ClearChildren(Transform parent)
		{
			for (int num = parent.childCount - 1; num >= 0; num--)
			{
				Transform child = parent.GetChild(num);
				Object.Destroy((Object)(object)((Component)child).gameObject);
			}
		}

		public static void VerticalLayoutOnGO(GameObject go, int spacing = 10, RectOffset? padding = null)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			VerticalLayoutGroup val = go.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val).spacing = spacing;
			((LayoutGroup)val).padding = (RectOffset)(((object)padding) ?? ((object)new RectOffset(10, 10, 10, 10)));
		}

		public static GameObject CreateQuestRow(string name, Transform parent, out GameObject iconPanel, out GameObject textPanel)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Row_" + name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.sizeDelta = new Vector2(0f, 90f);
			val.AddComponent<LayoutElement>().minHeight = 50f;
			((Shadow)val.AddComponent<Outline>()).effectColor = new Color(0f, 0f, 0f, 0.2f);
			GameObject val3 = Panel("Separator", val.transform, new Color(1f, 1f, 1f, 0.05f));
			val3.GetComponent<RectTransform>().sizeDelta = new Vector2(300f, 1f);
			Image val4 = val.AddComponent<Image>();
			((Graphic)val4).color = new Color(0.12f, 0.12f, 0.12f);
			Button val5 = val.AddComponent<Button>();
			((Selectable)val5).targetGraphic = (Graphic)(object)val4;
			HorizontalLayoutGroup val6 = val.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val6).spacing = 20f;
			((LayoutGroup)val6).padding = new RectOffset(75, 10, 10, 10);
			((LayoutGroup)val6).childAlignment = (TextAnchor)3;
			((HorizontalOrVerticalLayoutGroup)val6).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val6).childForceExpandHeight = false;
			LayoutElement val7 = val.AddComponent<LayoutElement>();
			val7.minHeight = 90f;
			val7.flexibleWidth = 1f;
			iconPanel = Panel("IconPanel", val.transform, new Color(0.12f, 0.12f, 0.12f));
			RectTransform component = iconPanel.GetComponent<RectTransform>();
			component.sizeDelta = new Vector2(80f, 80f);
			LayoutElement val8 = iconPanel.AddComponent<LayoutElement>();
			val8.preferredWidth = 80f;
			val8.preferredHeight = 80f;
			textPanel = Panel("TextPanel", val.transform, Color.clear);
			VerticalLayoutOnGO(textPanel, 2);
			LayoutElement val9 = textPanel.AddComponent<LayoutElement>();
			val9.minWidth = 200f;
			val9.flexibleWidth = 1f;
			return val;
		}

		public static GameObject TopBar(string name, Transform parent, string title, float topbarSize, int paddingLeft, int paddingRight, int paddingTop, int paddingBottom)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			GameObject val = Panel(name, parent, new Color(0.15f, 0.15f, 0.15f), (Vector2?)new Vector2(0f, topbarSize), (Vector2?)new Vector2(1f, 1f), fullAnchor: false);
			HorizontalLayoutGroup val2 = val.AddComponent<HorizontalLayoutGroup>();
			((LayoutGroup)val2).padding = new RectOffset(paddingLeft, paddingRight, paddingTop, paddingBottom);
			((HorizontalOrVerticalLayoutGroup)val2).spacing = 20f;
			((LayoutGroup)val2).childAlignment = (TextAnchor)4;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = true;
			Text val3 = Text("TopBarTitle", title, val.transform, 26, (TextAnchor)3, (FontStyle)1);
			LayoutElement val4 = ((Component)val3).gameObject.AddComponent<LayoutElement>();
			val4.minWidth = 300f;
			val4.flexibleWidth = 1f;
			return val;
		}

		public static void HorizontalLayoutOnGO(GameObject go, int spacing = 10, int padLeft = 0, int padRight = 0, int padTop = 0, int padBottom = 0, TextAnchor alignment = 4)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			HorizontalLayoutGroup val = go.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val).spacing = spacing;
			((LayoutGroup)val).childAlignment = alignment;
			((HorizontalOrVerticalLayoutGroup)val).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val).childForceExpandHeight = false;
			((LayoutGroup)val).padding = new RectOffset(padLeft, padRight, padTop, padBottom);
		}

		public static void SetLayoutGroupPadding(LayoutGroup layoutGroup, int left, int right, int top, int bottom)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			layoutGroup.padding = new RectOffset(left, right, top, bottom);
		}

		public static void BindAcceptButton(Button btn, Text label, string text, UnityAction callback)
		{
			label.text = text;
			((UnityEventBase)btn.onClick).RemoveAllListeners();
			((UnityEvent)btn.onClick).AddListener(callback);
		}
	}
}
namespace S1API.Storage
{
	public sealed class StorageEntity
	{
		private static readonly Log Logger = new Log("StorageEntity");

		internal readonly StorageEntity S1StorageEntity;

		internal readonly PlaceableStorageEntity S1PlaceableStorageEntity;

		public string Name
		{
			get
			{
				return S1StorageEntity.StorageEntityName;
			}
			set
			{
				S1StorageEntity.StorageEntityName = value;
			}
		}

		public int SlotCount
		{
			get
			{
				return S1StorageEntity.SlotCount;
			}
			set
			{
				if (value < 0)
				{
					Logger.Warning("Cannot set SlotCount to negative value");
					return;
				}
				if (value > MaxSlots)
				{
					Logger.Warning($"Cannot set SlotCount to {value}, maximum is {MaxSlots}");
					return;
				}
				int count = S1StorageEntity.ItemSlots.Count;
				if (value > count)
				{
					AddSlots(value - count);
				}
				else if (value < count)
				{
					RemoveSlots(count - value);
				}
			}
		}

		public int MaxSlots { get; set; } = 20;


		public int DisplayRowCount
		{
			get
			{
				return S1StorageEntity.DisplayRowCount;
			}
			set
			{
				S1StorageEntity.DisplayRowCount = value;
			}
		}

		public bool SlotsAreFilterable => S1StorageEntity.SlotsAreFilterable;

		public ItemInstance ItemInstance
		{
			get
			{
				PlaceableStorageEntity s1PlaceableStorageEntity = S1PlaceableStorageEntity;
				if (((s1PlaceableStorageEntity != null) ? ((BuildableItem)s1PlaceableStorageEntity).ItemInstance : null) == null)
				{
					return null;
				}
				return new ItemInstance(((BuildableItem)S1PlaceableStorageEntity).ItemInstance);
			}
		}

		public string ItemId
		{
			get
			{
				PlaceableStorageEntity s1PlaceableStorageEntity = S1PlaceableStorageEntity;
				object result;
				if (s1PlaceableStorageEntity == null)
				{
					result = null;
				}
				else
				{
					ItemInstance itemInstance = ((BuildableItem)s1PlaceableStorageEntity).ItemInstance;
					if (itemInstance == null)
					{
						result = null;
					}
					else
					{
						ItemDefinition definition = itemInstance.Definition;
						result = ((definition != null) ? definition.ID : null);
					}
				}
				return (string)result;
			}
		}

		public bool IsPlaceable => (Object)(object)S1PlaceableStorageEntity != (Object)null;

		internal StorageEntity(StorageEntity storageEntity, PlaceableStorageEntity placeableStorage = null)
		{
			S1StorageEntity = storageEntity ?? throw new ArgumentNullException("storageEntity");
			S1PlaceableStorageEntity = placeableStorage;
		}

		public bool AddSlots(int count)
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			if (count <= 0)
			{
				Logger.Warning("AddSlots called with non-positive count");
				return false;
			}
			int count2 = S1StorageEntity.ItemSlots.Count;
			int num = count2 + count;
			if (num > MaxSlots)
			{
				Logger.Warning($"Cannot add {count} slots, would exceed MaxSlots ({MaxSlots})");
				return false;
			}
			try
			{
				for (int i = 0; i < count; i++)
				{
					ItemSlot val = new ItemSlot(S1StorageEntity.SlotsAreFilterable);
					val.SetSlotOwner(((Il2CppObjectBase)S1StorageEntity).Cast<IItemSlotOwner>());
				}
				S1StorageEntity.SlotCount = num;
				if ((Object)(object)S1PlaceableStorageEntity != (Object)null)
				{
					int count3 = S1StorageEntity.ItemSlots.Count;
					for (int j = count2; j < count3; j++)
					{
						ItemSlot val2 = S1StorageEntity.ItemSlots[j];
						S1PlaceableStorageEntity.InputSlots.Add(val2);
						S1PlaceableStorageEntity.OutputSlots.Add(val2);
					}
				}
				if (num > 6 && DisplayRowCount < 2)
				{
					DisplayRowCount = 2;
				}
				return true;
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to add slots: " + ex.Message);
				return false;
			}
		}

		public bool RemoveSlots(int count)
		{
			if (count <= 0)
			{
				Logger.Warning("RemoveSlots called with non-positive count");
				return false;
			}
			int count2 = S1StorageEntity.ItemSlots.Count;
			if (count > count2)
			{
				Logger.Warning($"Cannot remove {count} slots, only {count2} exist");
				return false;
			}
			try
			{
				for (int i = count2 - count; i < count2; i++)
				{
					if (S1StorageEntity.ItemSlots[i].ItemInstance != null)
					{
						Logger.Warning($"Cannot remove slot {i}, it contains an item");
						return false;
					}
				}
				for (int j = 0; j < count; j++)
				{
					int num = S1StorageEntity.ItemSlots.Count - 1;
					ItemSlot val = S1StorageEntity.ItemSlots[num];
					if ((Object)(object)S1PlaceableStorageEntity != (Object)null)
					{
						S1PlaceableStorageEntity.InputSlots.Remove(val);
						S1PlaceableStorageEntity.OutputSlots.Remove(val);
					}
					S1StorageEntity.ItemSlots.RemoveAt(num);
				}
				S1StorageEntity.SlotCount = count2 - count;
				return true;
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to remove slots: " + ex.Message);
				return false;
			}
		}

		public bool SetSlotCount(int targetSlotCount)
		{
			if (targetSlotCount < 0)
			{
				Logger.Warning("Cannot set negative slot count");
				return false;
			}
			int count = S1StorageEntity.ItemSlots.Count;
			int num = targetSlotCount - count;
			if (num > 0)
			{
				return AddSlots(num);
			}
			if (num < 0)
			{
				return RemoveSlots(-num);
			}
			return true;
		}

		public int GetEmptySlotCount()
		{
			int num = 0;
			Enumerator<ItemSlot> enumerator = S1StorageEntity.ItemSlots.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ItemSlot current = enumerator.Current;
				if (current.ItemInstance == null)
				{
					num++;
				}
			}
			return num;
		}

		public int GetOccupiedSlotCount()
		{
			return S1StorageEntity.ItemSlots.Count - GetEmptySlotCount();
		}

		public bool HasItems()
		{
			Enumerator<ItemSlot> enumerator = S1StorageEntity.ItemSlots.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ItemSlot current = enumerator.Current;
				if (current.ItemInstance != null)
				{
					return true;
				}
			}
			return false;
		}

		public bool IsEmpty()
		{
			return !HasItems();
		}
	}
	public class StorageEventArgs
	{
		public StorageEntity Storage { get; internal set; }

		public string ItemId => Storage?.ItemId;

		internal StorageEventArgs(StorageEntity storage)
		{
			Storage = storage;
		}
	}
	public class StorageLoadingEventArgs : StorageEventArgs
	{
		public int ItemCountBeingLoaded { get; internal set; }

		public int CurrentSlotCount => base.Storage?.SlotCount ?? 0;

		public bool NeedsMoreSlots => ItemCountBeingLoaded > CurrentSlotCount;

		public int AdditionalSlotsNeeded => Math.Max(0, ItemCountBeingLoaded - CurrentSlotCount);

		internal StorageLoadingEventArgs(StorageEntity storage, int itemCount)
			: base(storage)
		{
			ItemCountBeingLoaded = itemCount;
		}
	}
	public static class StorageEvents
	{
		private static readonly Log Logger = new Log("StorageEvents");

		public static event Action<StorageEventArgs> OnStorageCreated;

		public static event Action<StorageLoadingEventArgs> OnStorageLoading;

		internal static void RaiseStorageCreated(StorageEventArgs args)
		{
			if (args == null)
			{
				return;
			}
			try
			{
				StorageEvents.OnStorageCreated?.Invoke(args);
			}
			catch (Exception ex)
			{
				Logger.Error($"Exception in OnStorageCreated handler for storage '{args.ItemId}': {ex.Message}\n{ex.StackTrace}");
			}
		}

		internal static void RaiseStorageLoading(StorageLoadingEventArgs args)
		{
			if (args == null)
			{
				return;
			}
			try
			{
				StorageEvents.OnStorageLoading?.Invoke(args);
			}
			catch (Exception ex)
			{
				Logger.Error($"Exception in OnStorageLoading handler for storage '{args.ItemId}': {ex.Message}\n{ex.StackTrace}");
			}
		}
	}
}
namespace S1API.Storages
{
	public enum StorageAccessSettings
	{
		Closed,
		SinglePlayerOnly,
		Full
	}
	public class StorageInstance
	{
		internal readonly StorageEntity S1Storage;

		public string Name => S1Storage.StorageEntityName;

		public string Subtitle => S1Storage.StorageEntitySubtitle;

		public int SlotCount => S1Storage.SlotCount;

		public int ItemCount => S1Storage.ItemCount;

		public StorageAccessSettings AccessSettings
		{
			get
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Expected I4, but got Unknown
				return (StorageAccessSettings)S1Storage.AccessSettings;
			}
			set
			{
				S1Storage.AccessSettings = (EAccessSettings)value;
			}
		}

		public bool IsOpened => S1Storage.IsOpened;

		public ItemSlotInstance[] Slots => ((IEnumerable<ItemSlot>)S1Storage.ItemSlots.ToArray()).Select((ItemSlot itemSlot) => new ItemSlotInstance(itemSlot)).ToArray();

		public event Action OnOpened
		{
			add
			{
				EventHelper.AddListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onOpened += Action.op_Implicit(h);
				});
			}
			remove
			{
				EventHelper.RemoveListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onOpened -= Action.op_Implicit(h);
				});
			}
		}

		public event Action OnClosed
		{
			add
			{
				EventHelper.AddListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onClosed += Action.op_Implicit(h);
				});
			}
			remove
			{
				EventHelper.RemoveListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onClosed -= Action.op_Implicit(h);
				});
			}
		}

		public event Action OnContentsChanged
		{
			add
			{
				EventHelper.AddListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onContentsChanged += Action.op_Implicit(h);
				});
			}
			remove
			{
				EventHelper.RemoveListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onContentsChanged -= Action.op_Implicit(h);
				});
			}
		}

		internal StorageInstance(StorageEntity storage)
		{
			S1Storage = storage;
		}

		public ItemInstance[] GetItems()
		{
			List<ItemInstance> allItems = S1Storage.GetAllItems();
			if (allItems == null || allItems.Count == 0)
			{
				return Array.Empty<ItemInstance>();
			}
			ItemInstance[] array = new ItemInstance[allItems.Count];
			for (int i = 0; i < allItems.Count; i++)
			{
				array[i] = new ItemInstance(allItems[i]);
			}
			return array;
		}

		public Dictionary<ItemInstance, int> GetContentsDictionary()
		{
			Dictionary<StorableItemInstance, int> contentsDictionary = S1Storage.GetContentsDictionary();
			Dictionary<ItemInstance, int> dictionary = new Dictionary<ItemInstance, int>();
			Enumerator<StorableItemInstance, int> enumerator = contentsDictionary.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<StorableItemInstance, int> current = enumerator.Current;
				if (current.Key != null)
				{
					dictionary[new ItemInstance((ItemInstance)(object)current.Key)] = current.Value;
				}
			}
			return dictionary;
		}

		public bool CanItemFit(ItemInstance itemInstance, int quantity = 1)
		{
			return S1Storage.CanItemFit(itemInstance.S1ItemInstance, quantity);
		}

		public void AddItem(ItemInstance itemInstance)
		{
			S1Storage.InsertItem(itemInstance.S1ItemInstance, true);
		}

		public int RemoveItem(ItemInstance itemInstance)
		{
			if (itemInstance == null)
			{
				return 0;
			}
			int num = 0;
			List<ItemSlot> itemSlots = S1Storage.ItemSlots;
			for (int i = 0; i < itemSlots.Count; i++)
			{
				ItemSlot val = itemSlots[i];
				if (val.ItemInstance != null && val.ItemInstance == itemInstance.S1ItemInstance)
				{
					int quantity = val.Quantity;
					val.ClearStoredInstance(false);
					num += quantity;
					break;
				}
			}
			return num;
		}

		public int TryRemoveQuantity(string itemDefinitionId, int quantity)
		{
			if (string.IsNullOrEmpty(itemDefinitionId) || quantity <= 0)
			{
				return 0;
			}
			int num = quantity;
			List<ItemSlot> itemSlots = S1Storage.ItemSlots;
			for (int i = 0; i < itemSlots.Count; i++)
			{
				if (num <= 0)
				{
					break;
				}
				ItemSlot val = itemSlots[i];
				if (val.ItemInstance != null && val.ItemInstance.ID == itemDefinitionId)
				{
					int quantity2 = val.Quantity;
					int num2 = Math.Min(num, quantity2);
					num -= num2;
					if (num2 >= quantity2)
					{
						val.ClearStoredInstance(false);
					}
					else
					{
						val.ChangeQuantity(-num2, false);
					}
				}
			}
			return quantity - num;
		}

		public int RemoveAllOfDefinition(string itemDefinitionId)
		{
			if (string.IsNullOrEmpty(itemDefinitionId))
			{
				return 0;
			}
			int num = 0;
			List<ItemSlot> itemSlots = S1Storage.ItemSlots;
			for (int i = 0; i < itemSlots.Count; i++)
			{
				ItemSlot val = itemSlots[i];
				if (val.ItemInstance != null && val.ItemInstance.ID == itemDefinitionId)
				{
					num += val.Quantity;
					val.ClearStoredInstance(false);
				}
			}
			return num;
		}
	}
	public static class StorageManager
	{
		public static StorageInstance[] GetAll()
		{
			List<StorageInstance> list = new List<StorageInstance>();
			if (WorldStorageEntity.All == null)
			{
				return list.ToArray();
			}
			Enumerator<WorldStorageEntity> enumerator = WorldStorageEntity.All.GetEnumerator();
			while (enumerator.MoveNext())
			{
				WorldStorageEntity current = enumerator.Current;
				if ((Object)(object)current != (Object)null)
				{
					list.Add(new StorageInstance((StorageEntity)(object)current));
				}
			}
			return list.ToArray();
		}

		public static StorageInstance? FindByName(string name)
		{
			if (string.IsNullOrEmpty(name) || WorldStorageEntity.All == null)
			{
				return null;
			}
			Enumerator<WorldStorageEntity> enumerator = WorldStorageEntity.All.GetEnumerator();
			while (enumerator.MoveNext())
			{
				WorldStorageEntity current = enumerator.Current;
				if ((Object)(object)current != (Object)null && ((StorageEntity)current).StorageEntityName == name)
				{
					return new StorageInstance((StorageEntity)(object)current);
				}
			}
			return null;
		}

		public static StorageInstance[] FindByPredicate(Func<StorageInstance, bool> predicate)
		{
			if (predicate == null || WorldStorageEntity.All == null)
			{
				return Array.Empty<StorageInstance>();
			}
			List<StorageInstance> list = new List<StorageInstance>();
			Enumerator<WorldStorageEntity> enumerator = WorldStorageEntity.All.GetEnumerator();
			while (enumerator.MoveNext())
			{
				WorldStorageEntity current = enumerator.Current;
				if ((Object)(object)current != (Object)null)
				{
					StorageInstance storageInstance = new StorageInstance((StorageEntity)(object)current);
					if (predicate(storageInstance))
					{
						list.Add(storageInstance);
					}
				}
			}
			return list.ToArray();
		}
	}
}
namespace S1API.Shops
{
	public sealed class Shop
	{
		internal ShopInterface S1ShopInterface { get; }

		public string Name => S1ShopInterface.ShopName;

		internal Shop(ShopInterface shopInterface)
		{
			S1ShopInterface = shopInterface;
		}

		public bool HasItem(string itemId)
		{
			if (string.IsNullOrEmpty(itemId))
			{
				return false;
			}
			Enumerator<ShopListing> enumerator = S1ShopInterface.Listings.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ShopListing current = enumerator.Current;
				object obj;
				if (current == null)
				{
					obj = null;
				}
				else
				{
					StorableItemDefinition item = current.Item;
					obj = ((item != null) ? ((ItemDefinition)item).ID : null);
				}
				if ((string?)obj == itemId)
				{
					return true;
				}
			}
			return false;
		}

		public bool SellsCategory(ItemCategory category)
		{
			//IL_0002: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			EItemCategory val = (EItemCategory)category;
			Enumerator<ShopListing> enumerator = S1ShopInterface.Listings.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ShopListing current = enumerator.Current;
				if ((Object)(object)((current != null) ? current.Item : null) != (Object)null && ((ItemDefinition)current.Item).Category == val)
				{
					return true;
				}
			}
			return false;
		}

		public string[] GetItemIds()
		{
			List<string> list = new List<string>();
			Enumerator<ShopListing> enumerator = S1ShopInterface.Listings.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ShopListing current = enumerator.Current;
				if ((Object)(object)((current != null) ? current.Item : null) != (Object)null)
				{
					list.Add(((ItemDefinition)current.Item).ID);
				}
			}
			return list.ToArray();
		}

		public bool AddItem(ItemDefinition item, float? customPrice = null)
		{
			if (item == null)
			{
				return false;
			}
			if (HasItem(item.ID))
			{
				return false;
			}
			return ShopIntegration.AddItemToShop(this, item, customPrice);
		}

		public bool RemoveItem(string itemId)
		{
			if (string.IsNullOrEmpty(itemId))
			{
				return false;
			}
			return ShopIntegration.RemoveItemFromShop(this, itemId);
		}
	}
	public static class ShopManager
	{
		private static readonly Log Logger = new Log("ShopManager");

		private static readonly List<Shop> _cachedShops = new List<Shop>();

		private static bool _cacheValid = false;

		public static Shop[] GetAllShops()
		{
			RefreshCacheIfNeeded();
			return _cachedShops.ToArray();
		}

		public static Shop GetShopByName(string shopName)
		{
			string shopName2 = shopName;
			if (string.IsNullOrEmpty(shopName2))
			{
				return null;
			}
			return GetAllShops().FirstOrDefault((Shop s) => string.Equals(s.Name, shopName2, StringComparison.OrdinalIgnoreCase));
		}

		public static Shop[] FindShopsByCategory(ItemCategory category)
		{
			return (from s in GetAllShops()
				where s.SellsCategory(category)
				select s).ToArray();
		}

		public static Shop[] FindShopsByItem(string itemId)
		{
			string itemId2 = itemId;
			if (string.IsNullOrEmpty(itemId2))
			{
				return Array.Empty<Shop>();
			}
			return (from s in GetAllShops()
				where s.HasItem(itemId2)
				select s).ToArray();
		}

		public static int AddToCompatibleShops(ItemDefinition item, float? customPrice = null)
		{
			if (item == null)
			{
				return 0;
			}
			Shop[] array = FindShopsByCategory(item.Category);
			int num = 0;
			Shop[] array2 = array;
			foreach (Shop shop in array2)
			{
				if (shop.AddItem(item, customPrice))
				{
					num++;
				}
			}
			if (num > 0)
			{
				Logger.Msg($"Added item '{item.Name}' to {num} compatible shop(s)");
			}
			return num;
		}

		public static int AddToShops(ItemDefinition item, params string[] shopNames)
		{
			return AddToShops(item, null, shopNames);
		}

		public static int AddToShops(ItemDefinition item, float? customPrice, params string[] shopNames)
		{
			if (item == null || shopNames == null || shopNames.Length == 0)
			{
				return 0;
			}
			int num = 0;
			foreach (string shopName in shopNames)
			{
				Shop shopByName = GetShopByName(shopName);
				if (shopByName != null && shopByName.AddItem(item, customPrice))
				{
					num++;
				}
			}
			return num;
		}

		internal static void InvalidateCache()
		{
			_cacheValid = false;
			_cachedShops.Clear();
		}

		private static void RefreshCacheIfNeeded()
		{
			if (_cacheValid)
			{
				return;
			}
			_cachedShops.Clear();
			try
			{
				List<ShopInterface> allShops = ShopInterface.AllShops;
				if (allShops == null)
				{
					_cacheValid = true;
					return;
				}
				Enumerator<ShopInterface> enumerator = allShops.GetEnumerator();
				while (enumerator.MoveNext())
				{
					ShopInterface current = enumerator.Current;
					if ((Object)(object)current != (Object)null)
					{
						_cachedShops.Add(new Shop(current));
					}
				}
				_cacheValid = true;
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to refresh shop cache: " + ex.Message);
				_cacheValid = false;
			}
		}
	}
}
namespace S1API.Saveables
{
	[Obsolete("Manual registration is no longer required. Classes that directly inherit from Saveable are automatically discovered. Remove calls to ModSaveableRegistry.Register() and simply inherit from Saveable.")]
	public static class ModSaveableRegistry
	{
		internal class Entry
		{
			public Saveable Saveable;

			public string? FolderName;
		}

		internal static readonly List<Entry> Registered = new List<Entry>();

		[Obsolete("Manual registration is no longer required. Classes that directly inherit from Saveable are automatically discovered.")]
		public static void Register(Saveable saveable, string? folderName = null)
		{
			if (saveable != null)
			{
				MelonLogger.Warning($"ModSaveableRegistry.Register() is deprecated! The saveable '{saveable.GetType().Name}' will be automatically discovered. Mod users can safely ignore this warning - their saves will continue to work normally. Mod developers should remove ModSaveableRegistry.Register() calls and simply inherit from Saveable.");
				Registered.Add(new Entry
				{
					Saveable = saveable,
					FolderName = folderName
				});
			}
		}
	}
	internal static class SaveableAutoRegistry
	{
		[CompilerGenerated]
		private sealed class <GetOrCreateInstances>d__7 : IEnumerable<Saveable>, IEnumerable, IEnumerator<Saveable>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private Saveable <>2__current;

			private int <>l__initialThreadId;

			private List<Type>.Enumerator <>s__1;

			private Type <saveableType>5__2;

			private Saveable <instance>5__3;

			Saveable IEnumerator<Saveable>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GetOrCreateInstances>d__7(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>s__1 = default(List<Type>.Enumerator);
				<saveableType>5__2 = null;
				<instance>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					int num = <>1__state;
					if (num != 0)
					{
						if (num != 1)
						{
							return false;
						}
						<>1__state = -3;
						goto IL_00eb;
					}
					<>1__state = -1;
					<>s__1 = _discoveredSaveableTypes.GetEnumerator();
					<>1__state = -3;
					goto IL_00fa;
					IL_00eb:
					<instance>5__3 = null;
					<saveableType>5__2 = null;
					goto IL_00fa;
					IL_00fa:
					if (<>s__1.MoveNext())
					{
						<saveableType>5__2 = <>s__1.Current;
						if (!_instances.TryGetValue(<saveableType>5__2, out <instance>5__3))
						{
							try
							{
								<instance>5__3 = (Saveable)Activator.CreateInstance(<saveableType>5__2, nonPublic: true);
								if (<instance>5__3 != null)
								{
									_instances[<saveableType>5__2] = <instance>5__3;
								}
							}
							catch
							{
							}
						}
						if (<instance>5__3 != null)
						{
							<>2__current = <instance>5__3;
							<>1__state = 1;
							return true;
						}
						goto IL_00eb;
					}
					<>m__Finally1();
					<>s__1 = default(List<Type>.Enumerator);
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				((IDisposable)<>s__1).Dispose();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<Saveable> IEnumerable<Saveable>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <GetOrCreateInstances>d__7(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<Saveable>)this).GetEnumerator();
			}
		}

		private static readonly List<Type> _discoveredSaveableTypes = new List<Type>();

		private static readonly Dictionary<Type, Saveable> _instances = new Dictionary<Type, Saveable>();

		private static bool _discoveryPerformed = false;

		private static readonly object _lock = new object();

		public static IEnumerable<Saveable> GetRegisteredSaveables()
		{
			lock (_lock)
			{
				if (!_discoveryPerformed)
				{
					DiscoverSaveableTypes();
					_discoveryPerformed = true;
				}
				return GetOrCreateInstances();
			}
		}

		private static void DiscoverSaveableTypes()
		{
			try
			{
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly in assemblies)
				{
					try
					{
						if (assembly == executingAssembly)
						{
							continue;
						}
						string? fullName = assembly.FullName;
						if (fullName != null && fullName.StartsWith("System"))
						{
							continue;
						}
						string? fullName2 = assembly.FullName;
						if (fullName2 != null && fullName2.StartsWith("Unity"))
						{
							continue;
						}
						string? fullName3 = assembly.FullName;
						if (fullName3 != null && fullName3.StartsWith("mscorlib"))
						{
							continue;
						}
						string? fullName4 = assembly.FullName;
						if (fullName4 != null && fullName4.StartsWith("netstandard"))
						{
							continue;
						}
						string? fullName5 = assembly.FullName;
						if (fullName5 != null && fullName5.StartsWith("Microsoft"))
						{
							continue;
						}
						string? fullName6 = assembly.FullName;
						if (fullName6 != null && fullName6.StartsWith("Il2Cpp"))
						{
							continue;
						}
						string? fullName7 = assembly.FullName;
						if (fullName7 != null && fullName7.StartsWith("MelonLoader"))
						{
							continue;
						}
						string? fullName8 = assembly.FullName;
						if ((fullName8 != null && fullName8.StartsWith("0Harmony")) || assembly.IsDynamic)
						{
							continue;
						}
						Type[] array;
						try
						{
							array = assembly.GetTypes();
						}
						catch (ReflectionTypeLoadException ex)
						{
							array = ex.Types.Where((Type t) => t != null).ToArray();
						}
						catch
						{
							goto end_IL_0020;
						}
						Type[] array2 = array;
						foreach (Type type in array2)
						{
							try
							{
								if (!(type == null) && !type.IsAbstract && !type.IsInterface && !type.IsGenericTypeDefinition && IsDirectSaveableInheritor(type))
								{
									_discoveredSaveableTypes.Add(type);
								}
							}
							catch
							{
							}
						}
						end_IL_0020:;
					}
					catch
					{
					}
				}
			}
			catch (Exception ex2)
			{
				try
				{
					MelonLogger.Warning("[S1API] Error during saveable type discovery: " + ex2.Message);
				}
				catch
				{
				}
			}
		}

		private static bool IsDirectSaveableInheritor(Type type)
		{
			if (!typeof(Saveable).IsAssignableFrom(type))
			{
				return false;
			}
			if (type.IsAbstract || type.IsInterface)
			{
				return false;
			}
			Type baseType = type.BaseType;
			return baseType == typeof(Saveable);
		}

		[IteratorStateMachine(typeof(<GetOrCreateInstances>d__7))]
		private static IEnumerable<Saveable> GetOrCreateInstances()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetOrCreateInstances>d__7(-2);
		}

		internal static void ClearCache()
		{
			lock (_lock)
			{
				_discoveredSaveableTypes.Clear();
				_instances.Clear();
				_discoveryPerformed = false;
			}
		}
	}
	[AttributeUsage(AttributeTargets.Field)]
	public class SaveableField : Attribute
	{
		internal string SaveName { get; }

		public SaveableField(string saveName)
		{
			SaveName = saveName;
		}
	}
}
namespace S1API.Rendering
{
	public static class MaterialHelper
	{
		private static readonly Log Logger = new Log("MaterialHelper");

		public static void ReplaceMaterials(GameObject gameObject, Func<Material, bool> predicate, Action<Material> materialModifier)
		{
			if ((Object)(object)gameObject == (Object)null)
			{
				Logger.Warning("ReplaceMaterials called with null GameObject");
				return;
			}
			if (predicate == null || materialModifier == null)
			{
				Logger.Warning("ReplaceMaterials called with null predicate or modifier");
				return;
			}
			try
			{
				foreach (Renderer componentsInChild in gameObject.GetComponentsInChildren<Renderer>(true))
				{
					if (!((Object)(object)componentsInChild == (Object)null))
					{
						ProcessRenderer(componentsInChild, predicate, materialModifier);
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Error("Error in ReplaceMaterials: " + ex.Message);
			}
		}

		public static Material CreateMetallicVariant(Material baseMaterial, Color metalColor, float metallic = 0.8f, float smoothness = 0.5f)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_0051: 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)
			if ((Object)(object)baseMaterial == (Object)null)
			{
				Logger.Error("CreateMetallicVariant called with null baseMaterial");
				return null;
			}
			try
			{
				Material val = new Material(baseMaterial)
				{
					name = ((Object)baseMaterial).name + "_metallic"
				};
				RemoveAllTextures(val);
				SetColor(val, "_BaseColor", metalColor);
				SetColor(val, "_Color", metalColor);
				SetFloat(val, "_Metallic", Mathf.Clamp01(metallic));
				SetFloat(val, "_Smoothness", Mathf.Clamp01(smoothness));
				SetFloat(val, "_Glossiness", Mathf.Clamp01(smoothness));
				return val;
			}
			catch (Exception ex)
			{
				Logger.Error("Error creating metallic variant: " + ex.Message);
				return null;
			}
		}

		public static void RemoveAllTextures(Material material)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			if ((Object)(object)material == (Object)null)
			{
				return;
			}
			try
			{
				Shader shader = material.shader;
				int propertyCount = shader.GetPropertyCount();
				for (int i = 0; i < propertyCount; i++)
				{
					if ((int)shader.GetPropertyType(i) == 4)
					{
						string propertyName = shader.GetPropertyName(i);
						material.SetTexture(propertyName, (Texture)null);
					}
				}
				material.mainTexture = null;
			}
			catch (Exception ex)
			{
				Logger.Warning("Error removing textures: " + ex.Message);
			}
		}

		public static bool SetColor(Material material, string propertyName, Color color)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)material == (Object)null || string.IsNullOrEmpty(propertyName))
			{
				return false;
			}
			try
			{
				if (material.HasProperty(propertyName))
				{
					material.SetColor(propertyName, color);
					return true;
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("Error setting color property '" + propertyName + "': " + ex.Message);
			}
			return false;
		}

		public static bool SetFloat(Material material, string propertyName, float value)
		{
			if ((Object)(object)material == (Object)null || string.IsNullOrEmpty(propertyName))
			{
				return false;
			}
			try
			{
				if (material.HasProperty(propertyName))
				{
					material.SetFloat(propertyName, value);
					return true;
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("Error setting float property '" + propertyName + "': " + ex.Message);
			}
			return false;
		}

		public static bool SetTexture(Material material, string propertyName, Texture texture)
		{
			if ((Object)(object)material == (Object)null || string.IsNullOrEmpty(propertyName))
			{
				return false;
			}
			try
			{
				if (material.HasProperty(propertyName))
				{
					material.SetTexture(propertyName, texture);
					return true;
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("Error setting texture property '" + propertyName + "': " + ex.Message);
			}
			return false;
		}

		public static void ConfigureMaterial(Material material, Action<Material> configurator)
		{
			if ((Object)(object)material == (Object)null || configurator == null)
			{
				return;
			}
			try
			{
				configurator(material);
			}
			catch (Exception ex)
			{
				Logger.Error("Error configuring material: " + ex.Message);
			}
		}

		private static void ProcessRenderer(Renderer renderer, Func<Material, bool> predicate, Action<Material> materialModifier)
		{
			//IL_0035: 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_0053: Expected O, but got Unknown
			Il2CppReferenceArray<Material> materials = renderer.materials;
			bool flag = false;
			for (int i = 0; i < ((Il2CppArrayBase<Material>)(object)materials).Length; i++)
			{
				Material val = ((Il2CppArrayBase<Material>)(object)materials)[i];
				if (!((Object)(object)val == (Object)null) && predicate(val))
				{
					Material val2 = new Material(val)
					{
						name = ((Object)val).name + "_modified"
					};
					materialModifier(val2);
					((Il2CppArrayBase<Material>)(object)materials)[i] = val2;
					flag = true;
				}
			}
			if (flag)
			{
				renderer.materials = materials;
			}
		}
	}
}
namespace S1API.Quests
{
	public abstract class Quest : Saveable
	{
		[CompilerGenerated]
		private sealed class <EnsurePOICreation>d__34 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public QuestEntry questEntry;

			private Exception <ex>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <EnsurePOICreation>d__34(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<ex>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)questEntry.PoILocation != (Object)null && questEntry.AutoCreatePoI)
					{
						try
						{
							questEntry.CreatePoI();
						}
						catch (Exception ex)
						{
							<ex>5__1 = ex;
							Debug.LogWarning(Object.op_Implicit("[S1API] Failed to create POI for quest entry: " + <ex>5__1.Message));
						}
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public readonly List<QuestEntry> QuestEntries = new List<QuestEntry>();

		[SaveableField("QuestData")]
		private readonly QuestData _questData;

		internal readonly Quest S1Quest;

		private readonly GameObject _gameObject;

		protected abstract string Title { get; }

		protected abstract string Description { get; }

		protected virtual bool AutoBegin => true;

		protected QuestState QuestState => (QuestState)S1Quest.State;

		internal string? SaveFolder => S1Quest.SaveFolderName;

		protected virtual Sprite? QuestIcon => null;

		public event Action OnComplete
		{
			add
			{
				EventHelper.AddListener(value, S1Quest.onComplete);
			}
			remove
			{
				EventHelper.RemoveListener(value, S1Quest.onComplete);
			}
		}

		public event Action? OnFail;

		public Quest()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Expected O, but got Unknown
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Expected O, but got Unknown
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Expected O, but got Unknown
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Expected O, but got Unknown
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Expected O, but got Unknown
			_questData = new QuestData(GetType().Name);
			_gameObject = new GameObject("Quest");
			S1Quest = _gameObject.AddComponent<Quest>();
			S1Quest.StaticGUID = string.Empty;
			S1Quest.title = Title;
			S1Quest.onActiveState = new UnityEvent();
			S1Quest.onComplete = new UnityEvent();
			S1Quest.onInitialComplete = new UnityEvent();
			S1Quest.onQuestBegin = new UnityEvent();
			S1Quest.onQuestEnd = new UnityEvent<EQuestState>();
			S1Quest.onTrackChange = new UnityEvent<bool>();
			S1Quest.TrackOnBegin = true;
			S1Quest.AutoCompleteOnAllEntriesComplete = true;
			S1Quest.autoInitialize = false;
			GameObject val = new GameObject("IconPrefab", (Type[])(object)new Type[3]
			{
				CrossType.Of<RectTransform>(),
				CrossType.Of<CanvasRenderer>(),
				CrossType.Of<Image>()
			});
			val.transform.SetParent(_gameObject.transform);
			Image component = val.GetComponent<Image>();
			component.sprite = QuestIcon ?? ((App<ContactsApp>)(object)PlayerSingleton<ContactsApp>.Instance).AppIcon;
			S1Quest.IconPrefab = val.GetComponent<RectTransform>();
			GameObject val2 = new GameObject("PoIUIPrefab", (Type[])(object)new Type[4]
			{
				CrossType.Of<RectTransform>(),
				CrossType.Of<CanvasRenderer>(),
				CrossType.Of<EventTrigger>(),
				CrossType.Of<Button>()
			});
			val2.transform.SetParent(_gameObject.transform);
			GameObject val3 = new GameObject("MainLabel", (Type[])(object)new Type[3]
			{
				CrossType.Of<RectTransform>(),
				CrossType.Of<CanvasRenderer>(),
				CrossType.Of<Text>()
			});
			val3.transform.SetParent(val2.transform);
			GameObject val4 = new GameObject("IconContainer", (Type[])(object)new Type[3]
			{
				CrossType.Of<RectTransform>(),
				CrossType.Of<CanvasRenderer>(),
				CrossType.Of<Image>()
			});
			val4.transform.SetParent(val2.transform);
			Image component2 = val4.GetComponent<Image>();
			component2.sprite = QuestIcon ?? ((App<ContactsApp>)(object)PlayerSingleton<ContactsApp>.Instance).AppIcon;
			RectTransform component3 = ((Component)component2).GetComponent<RectTransform>();
			component3.sizeDelta = new Vector2(20f, 20f);
			GameObject val5 = new GameObject("POIPrefab");
			val5.SetActive(false);
			val5.transform.SetParent(_gameObject.transform);
			POI val6 = val5.AddComponent<POI>();
			val6.DefaultMainText = "Did it work?";
			val6.UIPrefab = val2;
			S1Quest.PoIPrefab = val5;
			S1Quest.onQuestEnd.AddListener(UnityAction<EQuestState>.op_Implicit((Action<EQuestState>)OnQuestEnded));
		}

		internal override void CreateInternal()
		{
			base.CreateInternal();
			Quest s1Quest = S1Quest;
			string title = Title;
			string description = Description;
			Il2CppReferenceArray<QuestEntryData> obj = Il2CppReferenceArray<QuestEntryData>.op_Implicit(Array.Empty<QuestEntryData>());
			Quest s1Quest2 = S1Quest;
			s1Quest.InitializeQuest(title, description, obj, (s1Quest2 != null) ? s1Quest2.StaticGUID : null);
			if (AutoBegin)
			{
				Quest s1Quest3 = S1Quest;
				if (s1Quest3 != null)
				{
					s1Quest3.Begin(true);
				}
			}
		}

		internal override void SaveInternal(string folderPath, ref List<string> extraSaveables)
		{
			string text = Path.Combine(folderPath, S1Quest.SaveFolderName);
			if (!Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
			}
			base.SaveInternal(text, ref extraSaveables);
		}

		internal void OnQuestEnded(EQuestState questState)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			if ((int)questState == 3)
			{
				this.OnFail?.Invoke();
			}
			Quest.Quests.Remove(S1Quest);
			QuestManager.Quests.Remove(this);
		}

		protected QuestEntry AddEntry(string title, Vector3? poiPosition = null)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("QuestEntry");
			Transform transform = val.transform;
			GameObject gameObject = _gameObject;
			transform.SetParent((gameObject != null) ? gameObject.transform : null);
			QuestEntry val2 = val.AddComponent<QuestEntry>();
			if (!poiPosition.HasValue)
			{
				val2.PoILocation = null;
				val2.AutoCreatePoI = false;
			}
			else
			{
				val2.PoILocation = val.transform;
				val2.AutoCreatePoI = true;
			}
			S1Quest.Entries.Add(val2);
			QuestEntry questEntry = new QuestEntry(val2)
			{
				Title = title
			};
			if (poiPosition.HasValue)
			{
				questEntry.POIPosition = poiPosition.Value;
			}
			QuestEntries.Add(questEntry);
			return questEntry;
		}

		protected QuestEntry AddEntry(string title, NPC npc)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			if (npc == null)
			{
				throw new ArgumentNullException("npc");
			}
			GameObject val = new GameObject("QuestEntry");
			Transform transform = val.transform;
			GameObject gameObject = _gameObject;
			transform.SetParent((gameObject != null) ? gameObject.transform : null);
			val.SetActive(true);
			QuestEntry val2 = val.AddComponent<QuestEntry>();
			Transform transform2 = npc.Transform;
			if ((Object)(object)transform2 == (Object)null)
			{
				val2.PoILocation = null;
				val2.AutoCreatePoI = false;
				val2.AutoUpdatePoILocation = false;
			}
			else
			{
				val2.PoILocation = transform2;
				val2.AutoCreatePoI = true;
				val2.AutoUpdatePoILocation = true;
			}
			S1Quest.Entries.Add(val2);
			QuestEntry questEntry = new QuestEntry(val2)
			{
				Title = title
			};
			QuestEntries.Add(questEntry);
			if ((Object)(object)val2.PoILocation != (Object)null && val2.AutoCreatePoI)
			{
				MelonCoroutines.Start(EnsurePOICreation(val2));
			}
			return questEntry;
		}

		public void Begin()
		{
			Quest s1Quest = S1Quest;
			if (s1Quest != null)
			{
				s1Quest.Begin(true);
			}
		}

		public void Cancel()
		{
			Quest s1Quest = S1Quest;
			if (s1Quest != null)
			{
				s1Quest.Cancel(true);
			}
		}

		public void Expire()
		{
			Quest s1Quest = S1Quest;
			if (s1Quest != null)
			{
				s1Quest.Expire(true);
			}
		}

		public void Fail()
		{
			Quest s1Quest = S1Quest;
			if (s1Quest != null)
			{
				s1Quest.Fail(true);
			}
		}

		public void Complete()
		{
			Quest s1Quest = S1Quest;
			if (s1Quest != null)
			{
				s1Quest.Complete(true);
			}
		}

		public void End()
		{
			Quest s1Quest = S1Quest;
			if (s1Quest != null)
			{
				s1Quest.End();
			}
		}

		[IteratorStateMachine(typeof(<EnsurePOICreation>d__34))]
		private static IEnumerator EnsurePOICreation(QuestEntry questEntry)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <EnsurePOICreation>d__34(0)
			{
				questEntry = questEntry
			};
		}
	}
	public class QuestData
	{
		public readonly string ClassName;

		public QuestData(string className)
		{
			ClassName = className;
		}
	}
	public class QuestEntry
	{
		[CompilerGenerated]
		private sealed class <EnsurePOICreationForNPC>d__18 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public QuestEntry questEntry;

			private Exception <ex>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <EnsurePOICreationForNPC>d__18(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<ex>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)questEntry.PoILocation != (Object)null && questEntry.AutoCreatePoI)
					{
						try
						{
							questEntry.CreatePoI();
						}
						catch (Exception ex)
						{
							<ex>5__1 = ex;
							Debug.LogWarning(Object.op_Implicit("[S1API] Failed to create POI for quest entry: " + <ex>5__1.Message));
						}
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		internal readonly QuestEntry S1QuestEntry;

		public QuestState State => (QuestState)S1QuestEntry.State;

		public string Title
		{
			get
			{
				return S1QuestEntry.Title;
			}
			set
			{
				S1QuestEntry.SetEntryTitle(value);
			}
		}

		public Vector3 POIPosition
		{
			get
			{
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: 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)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				object obj = global::S1API.Internal.Utils.ReflectionUtils.TryGetFieldOrProperty(S1QuestEntry, "PoILocation");
				Transform val = (Transform)((obj is Transform) ? obj : null);
				if (val != null && (Object)(object)val != (Object)null)
				{
					return val.position;
				}
				return Vector3.zero;
			}
			set
			{
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				object obj = global::S1API.Internal.Utils.ReflectionUtils.TryGetFieldOrProperty(S1QuestEntry, "PoILocation");
				Transform val = (Transform)((obj is Transform) ? obj : null);
				if (val != null && (Object)(object)val != (Object)null)
				{
					val.position = value;
					return;
				}
				Transform transform = ((Component)S1QuestEntry).transform;
				S1QuestEntry.PoILocation = transform;
				transform.position = value;
				S1QuestEntry.AutoCreatePoI = true;
			}
		}

		public event Action OnComplete
		{
			add
			{
				EventHelper.AddListener(value, S1QuestEntry.onComplete);
			}
			remove
			{
				EventHelper.RemoveListener(value, S1QuestEntry.onComplete);
			}
		}

		internal QuestEntry(QuestEntry questEntry)
		{
			S1QuestEntry = questEntry;
		}

		public void Begin()
		{
			S1QuestEntry.Begin();
		}

		public void Complete()
		{
			S1QuestEntry.Complete();
		}

		public void SetState(QuestState questState)
		{
			S1QuestEntry.SetState((EQuestState)questState, true);
		}

		public bool SetPOIToNPC<T>() where T : NPC
		{
			NPC nPC = NPC.Get<T>();
			if (nPC == null)
			{
				return false;
			}
			return SetPOIToNPC(nPC);
		}

		public bool SetPOIToNPC(NPC npc)
		{
			if (npc == null || (Object)(object)npc.gameObject == (Object)null)
			{
				return false;
			}
			Transform transform = npc.Transform;
			if ((Object)(obj

Mods/S1API.Mono.MelonLoader.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using FishNet;
using FishNet.Connection;
using FishNet.Managing;
using FishNet.Managing.Client;
using FishNet.Managing.Object;
using FishNet.Managing.Scened;
using FishNet.Managing.Server;
using FishNet.Managing.Transporting;
using FishNet.Object;
using HarmonyLib;
using MelonLoader;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using S1API;
using S1API.AssetBundles;
using S1API.Avatar;
using S1API.Building;
using S1API.Conditions;
using S1API.Console;
using S1API.Economy;
using S1API.Entities;
using S1API.Entities.Appearances.AccessoryFields;
using S1API.Entities.Appearances.Base;
using S1API.Entities.Appearances.BodyLayerFields;
using S1API.Entities.Appearances.CustomizationFields;
using S1API.Entities.Appearances.FaceLayerFields;
using S1API.Entities.Behaviour;
using S1API.Entities.Customer;
using S1API.Entities.Dealer;
using S1API.Entities.Dialogue;
using S1API.Entities.Interfaces;
using S1API.Entities.Relation;
using S1API.Entities.Schedule;
using S1API.GameTime;
using S1API.Internal;
using S1API.Internal.Abstraction;
using S1API.Internal.Entities;
using S1API.Internal.Items;
using S1API.Internal.Lifecycle;
using S1API.Internal.Map;
using S1API.Internal.Patches;
using S1API.Internal.Shops;
using S1API.Internal.Utils;
using S1API.Items;
using S1API.Law;
using S1API.Lifecycle;
using S1API.Logging;
using S1API.Map;
using S1API.Map.Buildings;
using S1API.Map.DeliveryLocations;
using S1API.Messaging;
using S1API.Money;
using S1API.PhoneApp;
using S1API.PhoneCalls;
using S1API.PhoneCalls.Constants;
using S1API.Products;
using S1API.Properties;
using S1API.Properties.Interfaces;
using S1API.Properties.Internal;
using S1API.Properties.Tokens;
using S1API.Quests;
using S1API.Quests.Constants;
using S1API.Quests.Identifiers;
using S1API.Saveables;
using S1API.Shops;
using S1API.Storage;
using S1API.Storages;
using S1API.Utils;
using S1API.Vehicles;
using ScheduleOne;
using ScheduleOne.AvatarFramework;
using ScheduleOne.AvatarFramework.Animation;
using ScheduleOne.AvatarFramework.Customization;
using ScheduleOne.AvatarFramework.Equipping;
using ScheduleOne.Building;
using ScheduleOne.Calling;
using ScheduleOne.Cartel;
using ScheduleOne.Combat;
using ScheduleOne.DevUtilities;
using ScheduleOne.Dialogue;
using ScheduleOne.Economy;
using ScheduleOne.Effects;
using ScheduleOne.EntityFramework;
using ScheduleOne.Equipping;
using ScheduleOne.GameTime;
using ScheduleOne.Growing;
using ScheduleOne.Interaction;
using ScheduleOne.ItemFramework;
using ScheduleOne.Law;
using ScheduleOne.Levelling;
using ScheduleOne.Map;
using ScheduleOne.Messaging;
using ScheduleOne.Money;
using ScheduleOne.NPCs;
using ScheduleOne.NPCs.Actions;
using ScheduleOne.NPCs.Behaviour;
using ScheduleOne.NPCs.Relation;
using ScheduleOne.NPCs.Responses;
using ScheduleOne.NPCs.Schedules;
using ScheduleOne.Noise;
using ScheduleOne.ObjectScripts;
using ScheduleOne.Persistence;
using ScheduleOne.Persistence.Datas;
using ScheduleOne.Persistence.Loaders;
using ScheduleOne.PlayerScripts;
using ScheduleOne.PlayerScripts.Health;
using ScheduleOne.Police;
using ScheduleOne.Product;
using ScheduleOne.Product.Packaging;
using ScheduleOne.Property;
using ScheduleOne.Quests;
using ScheduleOne.ScriptableObjects;
using ScheduleOne.Storage;
using ScheduleOne.UI;
using ScheduleOne.UI.MainMenu;
using ScheduleOne.UI.Phone;
using ScheduleOne.UI.Phone.ContactsApp;
using ScheduleOne.UI.Phone.Messages;
using ScheduleOne.UI.Phone.ProductManagerApp;
using ScheduleOne.UI.Relations;
using ScheduleOne.UI.Shop;
using ScheduleOne.UI.WorldspacePopup;
using ScheduleOne.Variables;
using ScheduleOne.Vehicles;
using ScheduleOne.Vehicles.Modification;
using ScheduleOne.Vision;
using ScheduleOne.VoiceOver;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(global::S1API.S1API), "S1API (Forked by Bars)", "2.8.1", "KaBooMa", null)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ifBars")]
[assembly: AssemblyConfiguration("MonoMelon")]
[assembly: AssemblyDescription("A Schedule One Mono / Il2Cpp Cross Compatibility Layer (Forked from the original S1API by Kabooma)")]
[assembly: AssemblyFileVersion("2.8.1.0")]
[assembly: AssemblyInformationalVersion("2.8.1+f356ae01af1cc38d41ccb07070a54ab1e614b497")]
[assembly: AssemblyProduct("S1API")]
[assembly: AssemblyTitle("S1API")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ifBars/S1API")]
[assembly: AssemblyVersion("2.8.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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;
		}
	}
}
public class ClickHandler
{
	private readonly UnityAction _callback;

	public ClickHandler(UnityAction callback)
	{
		_callback = callback;
	}

	public void OnClick()
	{
		_callback.Invoke();
	}
}
namespace S1API
{
	public class S1API : MelonMod
	{
		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (sceneName == "Main")
			{
				GameLifecycle.Initialize();
			}
		}

		public override void OnSceneWasUnloaded(int buildIndex, string sceneName)
		{
			SceneStateCleaner.ResetForSceneChange(sceneName, afterUnload: true);
			if (sceneName == "Main")
			{
				GameLifecycle.Reset();
			}
		}

		public override void OnSceneWasInitialized(int buildIndex, string sceneName)
		{
			NPCNetworkBootstrap.EnsurePrefabsWarmup();
			SceneStateCleaner.ResetForSceneChange(sceneName, afterUnload: false);
		}
	}
}
namespace S1API.Vehicles
{
	public class LandVehicle
	{
		internal LandVehicle S1LandVehicle = null;

		internal bool _isDeferredByName = false;

		internal StorageInstance _storage;

		private static readonly Log _logger = new Log("S1API.LandVehicle");

		private static readonly FieldInfo? VehiclePriceField = typeof(LandVehicle).GetField("vehiclePrice", BindingFlags.NonPublic);

		private NetworkConnection? _conn;

		private string _guid = string.Empty;

		public float VehiclePrice
		{
			get
			{
				return S1LandVehicle.VehiclePrice;
			}
			set
			{
				VehiclePriceField?.SetValue(S1LandVehicle, value);
			}
		}

		public float TopSpeed
		{
			get
			{
				return S1LandVehicle.TopSpeed;
			}
			set
			{
				S1LandVehicle.TopSpeed = value;
			}
		}

		public bool IsPlayerOwned
		{
			get
			{
				return S1LandVehicle.IsPlayerOwned;
			}
			set
			{
				SetIsPlayerOwned(value);
			}
		}

		public VehicleColor Color
		{
			get
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Expected I4, but got Unknown
				return (VehicleColor)S1LandVehicle.OwnedColor;
			}
			set
			{
				SetColor(value);
			}
		}

		public string GUID => _guid;

		public StorageInstance Storage => _storage;

		public LandVehicle(string vehicleCode)
		{
			LandVehicle vehiclePrefab = NetworkSingleton<VehicleManager>.Instance.GetVehiclePrefab(vehicleCode);
			if ((Object)(object)vehiclePrefab == (Object)null)
			{
				_logger.Error("SpawnVehicle: '" + vehicleCode + "' is not a valid vehicle code!");
				return;
			}
			LandVehicle component = Object.Instantiate<GameObject>(((Component)vehiclePrefab).gameObject).GetComponent<LandVehicle>();
			component.SetGUID(GUIDManager.GenerateUniqueGUID());
			NetworkSingleton<VehicleManager>.Instance.AllVehicles.Add(component);
			S1LandVehicle = component;
			SetConnection();
			UpdateGuidFromGame();
			_storage = new StorageInstance(component.Storage);
		}

		public void Spawn(Vector3 position, Quaternion rotation)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (!InstanceFinder.IsServer)
			{
				_logger.Warning("Spawn can only be called on the server!");
				return;
			}
			if ((Object)(object)S1LandVehicle == (Object)null)
			{
				throw new Exception("Unable to spawn vehicle, S1LandVehicle is null!");
			}
			((Component)S1LandVehicle).transform.position = position;
			((Component)S1LandVehicle).transform.rotation = rotation;
			((NetworkBehaviour)NetworkSingleton<VehicleManager>.Instance).Spawn(((Component)S1LandVehicle).gameObject, (NetworkConnection)null, default(Scene));
		}

		internal LandVehicle(LandVehicle landVehicle)
		{
			S1LandVehicle = landVehicle;
			SetConnection();
			UpdateGuidFromGame();
			_storage = new StorageInstance(landVehicle.Storage);
			_isDeferredByName = false;
		}

		internal LandVehicle(string vehicleName, bool isDeferred)
		{
			_isDeferredByName = isDeferred;
		}

		private void SetConnection()
		{
			NetworkManager networkManager = InstanceFinder.NetworkManager;
			if (networkManager.IsClientOnly)
			{
				NetworkConnection connection = InstanceFinder.ClientManager.Connection;
				if (connection != (NetworkConnection)null && connection.IsValid)
				{
					_conn = connection;
				}
			}
			else if (networkManager.IsServerOnly || (networkManager.IsServer && !networkManager.IsClient))
			{
				NetworkConnection owner = ((NetworkBehaviour)S1LandVehicle).Owner;
				if (owner != (NetworkConnection)null && owner.IsValid)
				{
					_conn = owner;
				}
			}
		}

		private void SetIsPlayerOwned(bool isPlayerOwned)
		{
			S1LandVehicle.SetIsPlayerOwned(_conn, isPlayerOwned);
			if (isPlayerOwned)
			{
				NetworkSingleton<VehicleManager>.Instance.PlayerOwnedVehicles.Add(S1LandVehicle);
			}
			else
			{
				NetworkSingleton<VehicleManager>.Instance.PlayerOwnedVehicles.Remove(S1LandVehicle);
			}
		}

		private void SetColor(VehicleColor color)
		{
			MethodInfo method = typeof(LandVehicle).GetMethod("SetOwnedColor", BindingFlags.Instance | BindingFlags.NonPublic);
			if (method == null)
			{
				_logger.Error("SetOwnedColor method not found!");
				return;
			}
			method.Invoke(S1LandVehicle, new object[2]
			{
				_conn,
				(object)(EVehicleColor)color
			});
		}

		private void UpdateGuidFromGame()
		{
			try
			{
				PropertyInfo property = typeof(LandVehicle).GetProperty("GUID", BindingFlags.Instance | BindingFlags.Public);
				if (!(property == null))
				{
					_guid = ((Guid)(property.GetValue(S1LandVehicle) ?? ((object)Guid.Empty))).ToString();
				}
			}
			catch
			{
			}
		}
	}
	public enum ParkingAlignment
	{
		FrontToKerb,
		RearToKerb
	}
	public enum VehicleColor
	{
		Black,
		DarkGrey,
		LightGrey,
		White,
		Yellow,
		Orange,
		Red,
		DullRed,
		Pink,
		Purple,
		Navy,
		DarkBlue,
		LightBlue,
		Cyan,
		LightGreen,
		DarkGreen,
		Custom
	}
	public static class VehicleRegistry
	{
		private static readonly Dictionary<object, LandVehicle> _cache = new Dictionary<object, LandVehicle>();

		public static LandVehicle[] GetAll()
		{
			try
			{
				List<LandVehicle> allVehicles = NetworkSingleton<VehicleManager>.Instance.AllVehicles;
				if (allVehicles == null)
				{
					return Array.Empty<LandVehicle>();
				}
				List<LandVehicle> list = new List<LandVehicle>();
				foreach (LandVehicle item in allVehicles)
				{
					if ((Object)(object)item != (Object)null)
					{
						LandVehicle landVehicle = Wrap(item);
						if (landVehicle != null)
						{
							list.Add(landVehicle);
						}
					}
				}
				return list.ToArray();
			}
			catch
			{
				return Array.Empty<LandVehicle>();
			}
		}

		public static LandVehicle GetByGUID(string guid)
		{
			if (string.IsNullOrEmpty(guid))
			{
				return null;
			}
			try
			{
				Guid guid2 = new Guid(guid);
				LandVehicle @object = GUIDManager.GetObject<LandVehicle>(guid2);
				if ((Object)(object)@object == (Object)null)
				{
					return null;
				}
				return Wrap(@object);
			}
			catch
			{
				return null;
			}
		}

		public static LandVehicle GetByName(string gameObjectName)
		{
			if (string.IsNullOrEmpty(gameObjectName))
			{
				return null;
			}
			try
			{
				GameObject val = GameObject.Find(gameObjectName);
				if ((Object)(object)val != (Object)null)
				{
					LandVehicle component = val.GetComponent<LandVehicle>();
					if ((Object)(object)component != (Object)null)
					{
						return Wrap(component);
					}
				}
				List<LandVehicle> allVehicles = NetworkSingleton<VehicleManager>.Instance.AllVehicles;
				if (allVehicles != null)
				{
					for (int i = 0; i < allVehicles.Count; i++)
					{
						LandVehicle val2 = allVehicles[i];
						if ((Object)(object)val2 != (Object)null && ((Object)((Component)val2).gameObject).name == gameObjectName)
						{
							return Wrap(val2);
						}
					}
				}
				if (DeferredMapResolver.IsMenuScene())
				{
					LandVehicle deferredVehicle = new LandVehicle(gameObjectName, isDeferred: true);
					DeferredMapResolver.RegisterDeferredLookup(new DeferredLookup(gameObjectName, delegate(object resolved)
					{
						if (resolved is LandVehicle landVehicle && landVehicle != null && (Object)(object)landVehicle.S1LandVehicle != (Object)null)
						{
							deferredVehicle.S1LandVehicle = landVehicle.S1LandVehicle;
							deferredVehicle._isDeferredByName = false;
						}
					}));
					return deferredVehicle;
				}
				return null;
			}
			catch
			{
				return null;
			}
		}

		public static LandVehicle CreateVehicle(string vehicleCode)
		{
			if (!string.IsNullOrEmpty(vehicleCode))
			{
				try
				{
					return new LandVehicle(vehicleCode);
				}
				catch
				{
					return null;
				}
			}
			return null;
		}

		private static LandVehicle Wrap(LandVehicle veh)
		{
			if ((Object)(object)veh == (Object)null)
			{
				return null;
			}
			if (_cache.TryGetValue(veh, out LandVehicle value))
			{
				return value;
			}
			LandVehicle landVehicle = new LandVehicle(veh);
			_cache[veh] = landVehicle;
			return landVehicle;
		}
	}
}
namespace S1API.Utils
{
	public static class ReflectionUtils
	{
		public static MethodInfo? GetMethod(Type? type, string methodName, BindingFlags bindingFlags)
		{
			return global::S1API.Internal.Utils.ReflectionUtils.GetMethod(type, methodName, bindingFlags);
		}

		public static bool IsValueTuple(this object obj)
		{
			return global::S1API.Internal.Utils.ReflectionUtils.IsValueTuple(obj);
		}

		public static object[]? GetValueTupleItems(this object obj)
		{
			return global::S1API.Internal.Utils.ReflectionUtils.GetValueTupleItems(obj);
		}

		public static bool TrySetFieldOrProperty(object target, string memberName, object value)
		{
			return global::S1API.Internal.Utils.ReflectionUtils.TrySetFieldOrProperty(target, memberName, value);
		}

		public static object? TryGetFieldOrProperty(object target, string memberName)
		{
			return global::S1API.Internal.Utils.ReflectionUtils.TryGetFieldOrProperty(target, memberName);
		}
	}
}
namespace S1API.UI
{
	public static class CharacterCreatorManager
	{
		[CompilerGenerated]
		private sealed class <RestoreAfterClose>d__27 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <RestoreAfterClose>d__27(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = RestoreGameState();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <RestoreGameState>d__28 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			private PlayerCamera <camera>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <RestoreGameState>d__28(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<camera>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					if (PlayerSingleton<PlayerCamera>.InstanceExists)
					{
						<camera>5__1 = PlayerSingleton<PlayerCamera>.Instance;
						PlayerCamera obj = <camera>5__1;
						CharacterCreator s1Creator = _s1Creator;
						obj.RemoveActiveUIElement(((s1Creator != null) ? ((Object)s1Creator).name : null) ?? "CharacterCreator");
						if (<camera>5__1.activeUIElementCount == 0)
						{
							<camera>5__1.StopTransformOverride(0f, true, false);
							<camera>5__1.StopFOVOverride(0f);
							<camera>5__1.SetCanLook(true);
							<camera>5__1.LockMouse();
						}
						<camera>5__1 = null;
					}
					if (PlayerSingleton<PlayerMovement>.InstanceExists)
					{
						PlayerSingleton<PlayerMovement>.Instance.CanMove = true;
					}
					if (PlayerSingleton<PlayerInventory>.InstanceExists)
					{
						PlayerSingleton<PlayerInventory>.Instance.SetInventoryEnabled(true);
					}
					if (Singleton<HUD>.InstanceExists)
					{
						((Behaviour)Singleton<HUD>.Instance.canvas).enabled = true;
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private static readonly Log Logger = new Log("CharacterCreatorManager");

		private static CharacterCreator _s1Creator;

		private static bool _isInitialized;

		private static bool _eventsRegistered;

		public static bool IsOpen
		{
			get
			{
				EnsureInitialized();
				CharacterCreator s1Creator = _s1Creator;
				return s1Creator != null && s1Creator.IsOpen;
			}
		}

		public static BasicAvatarSettings ActiveSettings
		{
			get
			{
				EnsureInitialized();
				CharacterCreator s1Creator = _s1Creator;
				if ((Object)(object)((s1Creator != null) ? s1Creator.ActiveSettings : null) == (Object)null)
				{
					return null;
				}
				return new BasicAvatarSettings(_s1Creator.ActiveSettings);
			}
		}

		public static event Action OnOpened;

		public static event Action OnClosed;

		public static event Action<BasicAvatarSettings> OnCompleted;

		public static void Open(BasicAvatarSettings initialSettings = null, bool showUI = true)
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Error("CharacterCreator singleton is not available");
				return;
			}
			if (_s1Creator.IsOpen)
			{
				Logger.Warning("CharacterCreator is already open");
				return;
			}
			RegisterEvents();
			if (initialSettings == null)
			{
				initialSettings = GetPlayerAvatarSettings();
			}
			if (showUI && PlayerSingleton<PlayerCamera>.InstanceExists)
			{
				PlayerSingleton<PlayerCamera>.Instance.AddActiveUIElement(((Object)_s1Creator).name);
			}
			BasicAvatarSettings val = initialSettings?.S1BasicAvatarSettings;
			_s1Creator.Open(val, showUI);
			try
			{
				CharacterCreatorManager.OnOpened?.Invoke();
			}
			catch (Exception arg)
			{
				Logger.Error($"Error in OnOpened event handler: {arg}");
			}
		}

		public static void Close()
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Error("CharacterCreator singleton is not available");
				return;
			}
			if (!_s1Creator.IsOpen)
			{
				Logger.Warning("CharacterCreator is not open");
				return;
			}
			_s1Creator.Close();
			MelonCoroutines.Start(RestoreAfterClose());
			try
			{
				CharacterCreatorManager.OnClosed?.Invoke();
			}
			catch (Exception arg)
			{
				Logger.Error($"Error in OnClosed event handler: {arg}");
			}
		}

		public static void Complete()
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Error("CharacterCreator singleton is not available");
			}
			else if (!_s1Creator.IsOpen)
			{
				Logger.Warning("CharacterCreator is not open");
			}
			else
			{
				_s1Creator.Done();
			}
		}

		public static void SelectPreset(string presetName)
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Error("CharacterCreator singleton is not available");
			}
			else if (!_s1Creator.IsOpen)
			{
				Logger.Warning("CharacterCreator must be open to select a preset");
			}
			else if (string.IsNullOrWhiteSpace(presetName))
			{
				Logger.Warning("Preset name cannot be null or empty");
			}
			else
			{
				_s1Creator.SelectPreset(presetName);
			}
		}

		public static string[] GetAvailablePresets()
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null || _s1Creator.Presets == null)
			{
				return Array.Empty<string>();
			}
			List<string> list = new List<string>();
			for (int i = 0; i < _s1Creator.Presets.Count; i++)
			{
				BasicAvatarSettings val = _s1Creator.Presets[i];
				if ((Object)(object)val != (Object)null && !string.IsNullOrWhiteSpace(((Object)val).name))
				{
					list.Add(((Object)val).name);
				}
			}
			return list.ToArray();
		}

		public static void SetRigRotation(float normalizedValue)
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Error("CharacterCreator singleton is not available");
			}
			else if (!_s1Creator.IsOpen)
			{
				Logger.Warning("CharacterCreator must be open to set rig rotation");
			}
			else
			{
				_s1Creator.SliderChanged(Mathf.Clamp01(normalizedValue));
			}
		}

		public static void PreRegisterAsActiveUI()
		{
			EnsureInitialized();
			if ((Object)(object)_s1Creator == (Object)null)
			{
				Logger.Warning("CharacterCreator singleton is not available for pre-registration");
			}
			else if (PlayerSingleton<PlayerCamera>.InstanceExists)
			{
				PlayerSingleton<PlayerCamera>.Instance.AddActiveUIElement(((Object)_s1Creator).name);
			}
		}

		private static void EnsureInitialized()
		{
			if (_isInitialized)
			{
				return;
			}
			try
			{
				_s1Creator = Singleton<CharacterCreator>.Instance;
				if ((Object)(object)_s1Creator == (Object)null)
				{
					Logger.Warning("CharacterCreator singleton not found. Make sure you're in the correct scene.");
				}
				_isInitialized = true;
			}
			catch (Exception arg)
			{
				Logger.Error($"Failed to initialize CharacterCreatorManager: {arg}");
				_isInitialized = true;
			}
		}

		private static void RegisterEvents()
		{
			if (_eventsRegistered || (Object)(object)_s1Creator == (Object)null)
			{
				return;
			}
			try
			{
				if (_s1Creator.onComplete != null)
				{
					_s1Creator.onComplete.AddListener((UnityAction<BasicAvatarSettings>)OnCreatorCompleted);
				}
				_eventsRegistered = true;
			}
			catch (Exception arg)
			{
				Logger.Error($"Failed to register CharacterCreator events: {arg}");
			}
		}

		private static void OnCreatorCompleted(BasicAvatarSettings s1Settings)
		{
			try
			{
				if ((Object)(object)s1Settings == (Object)null)
				{
					Logger.Warning("CharacterCreator completed with null settings");
					return;
				}
				BasicAvatarSettings obj = new BasicAvatarSettings(s1Settings);
				MelonCoroutines.Start(RestoreGameState());
				CharacterCreatorManager.OnCompleted?.Invoke(obj);
			}
			catch (Exception arg)
			{
				Logger.Error($"Error in OnCompleted event handler: {arg}");
			}
		}

		[IteratorStateMachine(typeof(<RestoreAfterClose>d__27))]
		private static IEnumerator RestoreAfterClose()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RestoreAfterClose>d__27(0);
		}

		[IteratorStateMachine(typeof(<RestoreGameState>d__28))]
		private static IEnumerator RestoreGameState()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RestoreGameState>d__28(0);
		}

		private static BasicAvatarSettings GetPlayerAvatarSettings()
		{
			try
			{
				Player local = Player.Local;
				if (local == null || (Object)(object)local.S1Player == (Object)null)
				{
					Logger.Warning("Local player not available");
					return null;
				}
				BasicAvatarSettings currentAvatarSettings = local.S1Player.CurrentAvatarSettings;
				if ((Object)(object)currentAvatarSettings == (Object)null)
				{
					Logger.Msg("Player has no current avatar settings, using default");
					return null;
				}
				BasicAvatarSettings settings = Object.Instantiate<BasicAvatarSettings>(currentAvatarSettings);
				return new BasicAvatarSettings(settings);
			}
			catch (Exception arg)
			{
				Logger.Error($"Failed to get player avatar settings: {arg}");
				return null;
			}
		}
	}
	public sealed class MainMenuRig
	{
		internal readonly MainMenuRig S1MainMenuRig;

		public global::S1API.Avatar.Avatar? Avatar
		{
			get
			{
				if ((Object)(object)S1MainMenuRig == (Object)null || (Object)(object)S1MainMenuRig.Avatar == (Object)null)
				{
					return null;
				}
				return new global::S1API.Avatar.Avatar(S1MainMenuRig.Avatar);
			}
		}

		internal MainMenuRig(MainMenuRig mainMenuRig)
		{
			S1MainMenuRig = mainMenuRig;
		}

		public static MainMenuRig[] FindInScene(bool includeInactive = false)
		{
			MainMenuRig[] array = Object.FindObjectsOfType<MainMenuRig>(includeInactive);
			if (array == null || array.Length == 0)
			{
				return Array.Empty<MainMenuRig>();
			}
			return (from r in array
				where (Object)(object)r != (Object)null
				select new MainMenuRig(r)).ToArray();
		}
	}
	public static class UIFactory
	{
		private static Sprite roundedSprite;

		public static GameObject Panel(string name, Transform parent, Color bgColor, Vector2? anchorMin = null, Vector2? anchorMax = null, bool fullAnchor = false)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			if (fullAnchor)
			{
				val2.anchorMin = Vector2.zero;
				val2.anchorMax = Vector2.one;
				val2.offsetMin = Vector2.zero;
				val2.offsetMax = Vector2.zero;
			}
			else
			{
				val2.anchorMin = (Vector2)(((??)anchorMin) ?? new Vector2(0.5f, 0.5f));
				val2.anchorMax = (Vector2)(((??)anchorMax) ?? new Vector2(0.5f, 0.5f));
			}
			Image val3 = val.AddComponent<Image>();
			((Graphic)val3).color = bgColor;
			return val;
		}

		public static Text Text(string name, string content, Transform parent, int fontSize = 14, TextAnchor anchor = 0, FontStyle style = 0)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			Text val3 = val.AddComponent<Text>();
			val3.text = content;
			val3.fontSize = fontSize;
			val3.alignment = anchor;
			val3.fontStyle = style;
			val3.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			((Graphic)val3).color = Color.white;
			val3.horizontalOverflow = (HorizontalWrapMode)0;
			val3.verticalOverflow = (VerticalWrapMode)1;
			return val3;
		}

		public static RectTransform ScrollableVerticalList(string name, Transform parent, out ScrollRect scrollRect)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			scrollRect = val.AddComponent<ScrollRect>();
			scrollRect.horizontal = false;
			GameObject val3 = new GameObject("Viewport");
			val3.transform.SetParent(val.transform, false);
			RectTransform val4 = val3.AddComponent<RectTransform>();
			val4.anchorMin = Vector2.zero;
			val4.anchorMax = Vector2.one;
			val4.offsetMin = Vector2.zero;
			val4.offsetMax = Vector2.zero;
			((Graphic)val3.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.05f);
			val3.AddComponent<Mask>().showMaskGraphic = false;
			scrollRect.viewport = val4;
			GameObject val5 = new GameObject("Content");
			val5.transform.SetParent(val3.transform, false);
			RectTransform val6 = val5.AddComponent<RectTransform>();
			val6.anchorMin = new Vector2(0f, 1f);
			val6.anchorMax = new Vector2(1f, 1f);
			val6.pivot = new Vector2(0.5f, 1f);
			VerticalLayoutGroup val7 = val5.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val7).spacing = 10f;
			((LayoutGroup)val7).padding = new RectOffset(10, 10, 10, 10);
			((HorizontalOrVerticalLayoutGroup)val7).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)val7).childForceExpandHeight = false;
			val5.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			scrollRect.content = val6;
			return val6;
		}

		public static void FitContentHeight(RectTransform content)
		{
			ContentSizeFitter val = ((Component)content).gameObject.GetComponent<ContentSizeFitter>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)content).gameObject.AddComponent<ContentSizeFitter>();
			}
			val.verticalFit = (FitMode)2;
		}

		public static (GameObject, Button, Text) RoundedButtonWithLabel(string name, string label, Transform parent, Color bgColor, float width, float height, int fontSize, Color textColor)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_002c: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Expected O, but got Unknown
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name + "_RoundedMask");
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.sizeDelta = new Vector2(width, height);
			LayoutElement val3 = val.AddComponent<LayoutElement>();
			val3.preferredWidth = width;
			val3.preferredHeight = height;
			Image val4 = val.AddComponent<Image>();
			val4.sprite = GetRoundedSprite();
			val4.type = (Type)1;
			((Graphic)val4).color = Color.white;
			Mask val5 = val.AddComponent<Mask>();
			val5.showMaskGraphic = true;
			GameObject val6 = new GameObject(name);
			val6.transform.SetParent(val.transform, false);
			RectTransform val7 = val6.AddComponent<RectTransform>();
			val7.anchorMin = Vector2.zero;
			val7.anchorMax = Vector2.one;
			val7.offsetMin = Vector2.zero;
			val7.offsetMax = Vector2.zero;
			Image val8 = val6.AddComponent<Image>();
			((Graphic)val8).color = bgColor;
			val8.sprite = GetRoundedSprite();
			val8.type = (Type)1;
			Button val9 = val6.AddComponent<Button>();
			((Selectable)val9).targetGraphic = (Graphic)(object)val8;
			GameObject val10 = new GameObject("Label");
			val10.transform.SetParent(val6.transform, false);
			RectTransform val11 = val10.AddComponent<RectTransform>();
			val11.anchorMin = Vector2.zero;
			val11.anchorMax = Vector2.one;
			val11.offsetMin = Vector2.zero;
			val11.offsetMax = Vector2.zero;
			Text val12 = val10.AddComponent<Text>();
			val12.text = label;
			val12.alignment = (TextAnchor)4;
			val12.fontSize = fontSize;
			val12.fontStyle = (FontStyle)1;
			((Graphic)val12).color = textColor;
			val12.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			return (val, val9, val12);
		}

		private static Sprite GetRoundedSprite()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: 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_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)roundedSprite != (Object)null)
			{
				return roundedSprite;
			}
			int num = 32;
			Texture2D val = new Texture2D(num, num, (TextureFormat)5, false);
			Color32 val2 = default(Color32);
			((Color32)(ref val2))..ctor((byte)0, (byte)0, (byte)0, (byte)0);
			Color32 val3 = default(Color32);
			((Color32)(ref val3))..ctor(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
			float num2 = 6f;
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					bool flag = ((float)j < num2 && (float)i < num2 && Vector2.Distance(new Vector2((float)j, (float)i), new Vector2(num2, num2)) > num2) || ((float)j > (float)num - num2 - 1f && (float)i < num2 && Vector2.Distance(new Vector2((float)j, (float)i), new Vector2((float)num - num2 - 1f, num2)) > num2) || ((float)j < num2 && (float)i > (float)num - num2 - 1f && Vector2.Distance(new Vector2((float)j, (float)i), new Vector2(num2, (float)num - num2 - 1f)) > num2) || ((float)j > (float)num - num2 - 1f && (float)i > (float)num - num2 - 1f && Vector2.Distance(new Vector2((float)j, (float)i), new Vector2((float)num - num2 - 1f, (float)num - num2 - 1f)) > num2);
					val.SetPixel(j, i, Color32.op_Implicit(flag ? val2 : val3));
				}
			}
			val.Apply();
			Vector4 val4 = default(Vector4);
			((Vector4)(ref val4))..ctor(8f, 8f, 8f, 8f);
			roundedSprite = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, val4);
			return roundedSprite;
		}

		public static GameObject ButtonRow(string name, Transform parent, float spacing = 12f, TextAnchor alignment = 4)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			HorizontalLayoutGroup val3 = val.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val3).spacing = spacing;
			((LayoutGroup)val3).childAlignment = alignment;
			((HorizontalOrVerticalLayoutGroup)val3).childControlWidth = false;
			((HorizontalOrVerticalLayoutGroup)val3).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)val3).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val3).childForceExpandHeight = false;
			return val;
		}

		public static (GameObject, Button, Text) ButtonWithLabel(string name, string label, Transform parent, Color bgColor, float Width, float Height)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.sizeDelta = new Vector2(Height, Width);
			Image val3 = val.AddComponent<Image>();
			((Graphic)val3).color = bgColor;
			val3.sprite = Resources.GetBuiltinResource<Sprite>("UI/Skin/UISprite.psd");
			val3.type = (Type)1;
			Button val4 = val.AddComponent<Button>();
			((Selectable)val4).targetGraphic = (Graphic)(object)val3;
			GameObject val5 = new GameObject("Label");
			val5.transform.SetParent(val.transform, false);
			RectTransform val6 = val5.AddComponent<RectTransform>();
			val6.anchorMin = Vector2.zero;
			val6.anchorMax = Vector2.one;
			val6.offsetMin = Vector2.zero;
			val6.offsetMax = Vector2.zero;
			Text val7 = val5.AddComponent<Text>();
			val7.text = label;
			val7.alignment = (TextAnchor)4;
			val7.fontSize = 16;
			val7.fontStyle = (FontStyle)1;
			((Graphic)val7).color = Color.white;
			val7.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			return (val, val4, val7);
		}

		public static void SetIcon(Sprite sprite, Transform parent)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0022: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Icon");
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			Image val3 = val.AddComponent<Image>();
			val3.sprite = sprite;
			val3.preserveAspect = true;
		}

		public static void CreateTextBlock(Transform parent, string title, string subtitle, bool isCompleted)
		{
			Text(((Object)parent).name + "Title", title, parent, 16, (TextAnchor)3, (FontStyle)1);
			Text(((Object)parent).name + "Subtitle", subtitle, parent, 14, (TextAnchor)0, (FontStyle)0);
			if (isCompleted)
			{
				Text("CompletedLabel", "<color=#888888><i>Already Delivered</i></color>", parent, 12, (TextAnchor)0, (FontStyle)0);
			}
		}

		public static void CreateRowButton(GameObject go, UnityAction clickHandler, bool enabled)
		{
			Button val = go.AddComponent<Button>();
			Image component = go.GetComponent<Image>();
			((Selectable)val).targetGraphic = (Graphic)(object)component;
			((Selectable)val).interactable = enabled;
			((UnityEvent)val.onClick).AddListener(clickHandler);
		}

		public static void ClearChildren(Transform parent)
		{
			for (int num = parent.childCount - 1; num >= 0; num--)
			{
				Transform child = parent.GetChild(num);
				Object.Destroy((Object)(object)((Component)child).gameObject);
			}
		}

		public static void VerticalLayoutOnGO(GameObject go, int spacing = 10, RectOffset? padding = null)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			VerticalLayoutGroup val = go.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val).spacing = spacing;
			((LayoutGroup)val).padding = (RectOffset)(((object)padding) ?? ((object)new RectOffset(10, 10, 10, 10)));
		}

		public static GameObject CreateQuestRow(string name, Transform parent, out GameObject iconPanel, out GameObject textPanel)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Row_" + name);
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.sizeDelta = new Vector2(0f, 90f);
			val.AddComponent<LayoutElement>().minHeight = 50f;
			((Shadow)val.AddComponent<Outline>()).effectColor = new Color(0f, 0f, 0f, 0.2f);
			GameObject val3 = Panel("Separator", val.transform, new Color(1f, 1f, 1f, 0.05f));
			val3.GetComponent<RectTransform>().sizeDelta = new Vector2(300f, 1f);
			Image val4 = val.AddComponent<Image>();
			((Graphic)val4).color = new Color(0.12f, 0.12f, 0.12f);
			Button val5 = val.AddComponent<Button>();
			((Selectable)val5).targetGraphic = (Graphic)(object)val4;
			HorizontalLayoutGroup val6 = val.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val6).spacing = 20f;
			((LayoutGroup)val6).padding = new RectOffset(75, 10, 10, 10);
			((LayoutGroup)val6).childAlignment = (TextAnchor)3;
			((HorizontalOrVerticalLayoutGroup)val6).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val6).childForceExpandHeight = false;
			LayoutElement val7 = val.AddComponent<LayoutElement>();
			val7.minHeight = 90f;
			val7.flexibleWidth = 1f;
			iconPanel = Panel("IconPanel", val.transform, new Color(0.12f, 0.12f, 0.12f));
			RectTransform component = iconPanel.GetComponent<RectTransform>();
			component.sizeDelta = new Vector2(80f, 80f);
			LayoutElement val8 = iconPanel.AddComponent<LayoutElement>();
			val8.preferredWidth = 80f;
			val8.preferredHeight = 80f;
			textPanel = Panel("TextPanel", val.transform, Color.clear);
			VerticalLayoutOnGO(textPanel, 2);
			LayoutElement val9 = textPanel.AddComponent<LayoutElement>();
			val9.minWidth = 200f;
			val9.flexibleWidth = 1f;
			return val;
		}

		public static GameObject TopBar(string name, Transform parent, string title, float topbarSize, int paddingLeft, int paddingRight, int paddingTop, int paddingBottom)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			GameObject val = Panel(name, parent, new Color(0.15f, 0.15f, 0.15f), (Vector2?)new Vector2(0f, topbarSize), (Vector2?)new Vector2(1f, 1f), fullAnchor: false);
			HorizontalLayoutGroup val2 = val.AddComponent<HorizontalLayoutGroup>();
			((LayoutGroup)val2).padding = new RectOffset(paddingLeft, paddingRight, paddingTop, paddingBottom);
			((HorizontalOrVerticalLayoutGroup)val2).spacing = 20f;
			((LayoutGroup)val2).childAlignment = (TextAnchor)4;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = true;
			Text val3 = Text("TopBarTitle", title, val.transform, 26, (TextAnchor)3, (FontStyle)1);
			LayoutElement val4 = ((Component)val3).gameObject.AddComponent<LayoutElement>();
			val4.minWidth = 300f;
			val4.flexibleWidth = 1f;
			return val;
		}

		public static void HorizontalLayoutOnGO(GameObject go, int spacing = 10, int padLeft = 0, int padRight = 0, int padTop = 0, int padBottom = 0, TextAnchor alignment = 4)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			HorizontalLayoutGroup val = go.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val).spacing = spacing;
			((LayoutGroup)val).childAlignment = alignment;
			((HorizontalOrVerticalLayoutGroup)val).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val).childForceExpandHeight = false;
			((LayoutGroup)val).padding = new RectOffset(padLeft, padRight, padTop, padBottom);
		}

		public static void SetLayoutGroupPadding(LayoutGroup layoutGroup, int left, int right, int top, int bottom)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			layoutGroup.padding = new RectOffset(left, right, top, bottom);
		}

		public static void BindAcceptButton(Button btn, Text label, string text, UnityAction callback)
		{
			label.text = text;
			((UnityEventBase)btn.onClick).RemoveAllListeners();
			((UnityEvent)btn.onClick).AddListener(callback);
		}
	}
}
namespace S1API.Storage
{
	public sealed class StorageEntity
	{
		private static readonly Log Logger = new Log("StorageEntity");

		internal readonly StorageEntity S1StorageEntity;

		internal readonly PlaceableStorageEntity S1PlaceableStorageEntity;

		public string Name
		{
			get
			{
				return S1StorageEntity.StorageEntityName;
			}
			set
			{
				S1StorageEntity.StorageEntityName = value;
			}
		}

		public int SlotCount
		{
			get
			{
				return S1StorageEntity.SlotCount;
			}
			set
			{
				if (value < 0)
				{
					Logger.Warning("Cannot set SlotCount to negative value");
					return;
				}
				if (value > MaxSlots)
				{
					Logger.Warning($"Cannot set SlotCount to {value}, maximum is {MaxSlots}");
					return;
				}
				int count = S1StorageEntity.ItemSlots.Count;
				if (value > count)
				{
					AddSlots(value - count);
				}
				else if (value < count)
				{
					RemoveSlots(count - value);
				}
			}
		}

		public int MaxSlots { get; set; } = 20;


		public int DisplayRowCount
		{
			get
			{
				return S1StorageEntity.DisplayRowCount;
			}
			set
			{
				S1StorageEntity.DisplayRowCount = value;
			}
		}

		public bool SlotsAreFilterable => S1StorageEntity.SlotsAreFilterable;

		public ItemInstance ItemInstance
		{
			get
			{
				PlaceableStorageEntity s1PlaceableStorageEntity = S1PlaceableStorageEntity;
				if (((s1PlaceableStorageEntity != null) ? ((BuildableItem)s1PlaceableStorageEntity).ItemInstance : null) == null)
				{
					return null;
				}
				return new ItemInstance(((BuildableItem)S1PlaceableStorageEntity).ItemInstance);
			}
		}

		public string ItemId
		{
			get
			{
				PlaceableStorageEntity s1PlaceableStorageEntity = S1PlaceableStorageEntity;
				object result;
				if (s1PlaceableStorageEntity == null)
				{
					result = null;
				}
				else
				{
					ItemInstance itemInstance = ((BuildableItem)s1PlaceableStorageEntity).ItemInstance;
					result = ((itemInstance == null) ? null : itemInstance.Definition?.ID);
				}
				return (string)result;
			}
		}

		public bool IsPlaceable => (Object)(object)S1PlaceableStorageEntity != (Object)null;

		internal StorageEntity(StorageEntity storageEntity, PlaceableStorageEntity placeableStorage = null)
		{
			S1StorageEntity = storageEntity ?? throw new ArgumentNullException("storageEntity");
			S1PlaceableStorageEntity = placeableStorage;
		}

		public bool AddSlots(int count)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			if (count <= 0)
			{
				Logger.Warning("AddSlots called with non-positive count");
				return false;
			}
			int count2 = S1StorageEntity.ItemSlots.Count;
			int num = count2 + count;
			if (num > MaxSlots)
			{
				Logger.Warning($"Cannot add {count} slots, would exceed MaxSlots ({MaxSlots})");
				return false;
			}
			try
			{
				for (int i = 0; i < count; i++)
				{
					ItemSlot val = new ItemSlot(S1StorageEntity.SlotsAreFilterable);
					val.SetSlotOwner((IItemSlotOwner)(object)S1StorageEntity);
				}
				S1StorageEntity.SlotCount = num;
				if ((Object)(object)S1PlaceableStorageEntity != (Object)null)
				{
					int count3 = S1StorageEntity.ItemSlots.Count;
					for (int j = count2; j < count3; j++)
					{
						ItemSlot item = S1StorageEntity.ItemSlots[j];
						S1PlaceableStorageEntity.InputSlots.Add(item);
						S1PlaceableStorageEntity.OutputSlots.Add(item);
					}
				}
				if (num > 6 && DisplayRowCount < 2)
				{
					DisplayRowCount = 2;
				}
				return true;
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to add slots: " + ex.Message);
				return false;
			}
		}

		public bool RemoveSlots(int count)
		{
			if (count <= 0)
			{
				Logger.Warning("RemoveSlots called with non-positive count");
				return false;
			}
			int count2 = S1StorageEntity.ItemSlots.Count;
			if (count > count2)
			{
				Logger.Warning($"Cannot remove {count} slots, only {count2} exist");
				return false;
			}
			try
			{
				for (int i = count2 - count; i < count2; i++)
				{
					if (S1StorageEntity.ItemSlots[i].ItemInstance != null)
					{
						Logger.Warning($"Cannot remove slot {i}, it contains an item");
						return false;
					}
				}
				for (int j = 0; j < count; j++)
				{
					int index = S1StorageEntity.ItemSlots.Count - 1;
					ItemSlot item = S1StorageEntity.ItemSlots[index];
					if ((Object)(object)S1PlaceableStorageEntity != (Object)null)
					{
						S1PlaceableStorageEntity.InputSlots.Remove(item);
						S1PlaceableStorageEntity.OutputSlots.Remove(item);
					}
					S1StorageEntity.ItemSlots.RemoveAt(index);
				}
				S1StorageEntity.SlotCount = count2 - count;
				return true;
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to remove slots: " + ex.Message);
				return false;
			}
		}

		public bool SetSlotCount(int targetSlotCount)
		{
			if (targetSlotCount < 0)
			{
				Logger.Warning("Cannot set negative slot count");
				return false;
			}
			int count = S1StorageEntity.ItemSlots.Count;
			int num = targetSlotCount - count;
			if (num > 0)
			{
				return AddSlots(num);
			}
			if (num < 0)
			{
				return RemoveSlots(-num);
			}
			return true;
		}

		public int GetEmptySlotCount()
		{
			int num = 0;
			foreach (ItemSlot itemSlot in S1StorageEntity.ItemSlots)
			{
				if (itemSlot.ItemInstance == null)
				{
					num++;
				}
			}
			return num;
		}

		public int GetOccupiedSlotCount()
		{
			return S1StorageEntity.ItemSlots.Count - GetEmptySlotCount();
		}

		public bool HasItems()
		{
			foreach (ItemSlot itemSlot in S1StorageEntity.ItemSlots)
			{
				if (itemSlot.ItemInstance != null)
				{
					return true;
				}
			}
			return false;
		}

		public bool IsEmpty()
		{
			return !HasItems();
		}
	}
	public class StorageEventArgs
	{
		public StorageEntity Storage { get; internal set; }

		public string ItemId => Storage?.ItemId;

		internal StorageEventArgs(StorageEntity storage)
		{
			Storage = storage;
		}
	}
	public class StorageLoadingEventArgs : StorageEventArgs
	{
		public int ItemCountBeingLoaded { get; internal set; }

		public int CurrentSlotCount => base.Storage?.SlotCount ?? 0;

		public bool NeedsMoreSlots => ItemCountBeingLoaded > CurrentSlotCount;

		public int AdditionalSlotsNeeded => Math.Max(0, ItemCountBeingLoaded - CurrentSlotCount);

		internal StorageLoadingEventArgs(StorageEntity storage, int itemCount)
			: base(storage)
		{
			ItemCountBeingLoaded = itemCount;
		}
	}
	public static class StorageEvents
	{
		private static readonly Log Logger = new Log("StorageEvents");

		public static event Action<StorageEventArgs> OnStorageCreated;

		public static event Action<StorageLoadingEventArgs> OnStorageLoading;

		internal static void RaiseStorageCreated(StorageEventArgs args)
		{
			if (args == null)
			{
				return;
			}
			try
			{
				StorageEvents.OnStorageCreated?.Invoke(args);
			}
			catch (Exception ex)
			{
				Logger.Error("Exception in OnStorageCreated handler for storage '" + args.ItemId + "': " + ex.Message + "\n" + ex.StackTrace);
			}
		}

		internal static void RaiseStorageLoading(StorageLoadingEventArgs args)
		{
			if (args == null)
			{
				return;
			}
			try
			{
				StorageEvents.OnStorageLoading?.Invoke(args);
			}
			catch (Exception ex)
			{
				Logger.Error("Exception in OnStorageLoading handler for storage '" + args.ItemId + "': " + ex.Message + "\n" + ex.StackTrace);
			}
		}
	}
}
namespace S1API.Storages
{
	public enum StorageAccessSettings
	{
		Closed,
		SinglePlayerOnly,
		Full
	}
	public class StorageInstance
	{
		internal readonly StorageEntity S1Storage;

		public string Name => S1Storage.StorageEntityName;

		public string Subtitle => S1Storage.StorageEntitySubtitle;

		public int SlotCount => S1Storage.SlotCount;

		public int ItemCount => S1Storage.ItemCount;

		public StorageAccessSettings AccessSettings
		{
			get
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Expected I4, but got Unknown
				return (StorageAccessSettings)S1Storage.AccessSettings;
			}
			set
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				S1Storage.AccessSettings = (EAccessSettings)value;
			}
		}

		public bool IsOpened => S1Storage.IsOpened;

		public ItemSlotInstance[] Slots => (from itemSlot in S1Storage.ItemSlots.ToArray()
			select new ItemSlotInstance(itemSlot)).ToArray();

		public event Action OnOpened
		{
			add
			{
				EventHelper.AddListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onOpened = (Action)Delegate.Combine(s1Storage.onOpened, h);
				});
			}
			remove
			{
				EventHelper.RemoveListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onOpened = (Action)Delegate.Remove(s1Storage.onOpened, h);
				});
			}
		}

		public event Action OnClosed
		{
			add
			{
				EventHelper.AddListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onClosed = (Action)Delegate.Combine(s1Storage.onClosed, h);
				});
			}
			remove
			{
				EventHelper.RemoveListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onClosed = (Action)Delegate.Remove(s1Storage.onClosed, h);
				});
			}
		}

		public event Action OnContentsChanged
		{
			add
			{
				EventHelper.AddListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onContentsChanged = (Action)Delegate.Combine(s1Storage.onContentsChanged, h);
				});
			}
			remove
			{
				EventHelper.RemoveListener(value, (Action<Action>)delegate(Action h)
				{
					StorageEntity s1Storage = S1Storage;
					s1Storage.onContentsChanged = (Action)Delegate.Remove(s1Storage.onContentsChanged, h);
				});
			}
		}

		internal StorageInstance(StorageEntity storage)
		{
			S1Storage = storage;
		}

		public ItemInstance[] GetItems()
		{
			List<ItemInstance> allItems = S1Storage.GetAllItems();
			if (allItems == null || allItems.Count == 0)
			{
				return Array.Empty<ItemInstance>();
			}
			ItemInstance[] array = new ItemInstance[allItems.Count];
			for (int i = 0; i < allItems.Count; i++)
			{
				array[i] = new ItemInstance(allItems[i]);
			}
			return array;
		}

		public Dictionary<ItemInstance, int> GetContentsDictionary()
		{
			Dictionary<StorableItemInstance, int> contentsDictionary = S1Storage.GetContentsDictionary();
			Dictionary<ItemInstance, int> dictionary = new Dictionary<ItemInstance, int>();
			foreach (KeyValuePair<StorableItemInstance, int> item in contentsDictionary)
			{
				if (item.Key != null)
				{
					dictionary[new ItemInstance((ItemInstance)(object)item.Key)] = item.Value;
				}
			}
			return dictionary;
		}

		public bool CanItemFit(ItemInstance itemInstance, int quantity = 1)
		{
			return S1Storage.CanItemFit(itemInstance.S1ItemInstance, quantity);
		}

		public void AddItem(ItemInstance itemInstance)
		{
			S1Storage.InsertItem(itemInstance.S1ItemInstance, true);
		}

		public int RemoveItem(ItemInstance itemInstance)
		{
			if (itemInstance == null)
			{
				return 0;
			}
			int num = 0;
			List<ItemSlot> itemSlots = S1Storage.ItemSlots;
			for (int i = 0; i < itemSlots.Count; i++)
			{
				ItemSlot val = itemSlots[i];
				if (val.ItemInstance != null && val.ItemInstance == itemInstance.S1ItemInstance)
				{
					int quantity = val.Quantity;
					val.ClearStoredInstance(false);
					num += quantity;
					break;
				}
			}
			return num;
		}

		public int TryRemoveQuantity(string itemDefinitionId, int quantity)
		{
			if (string.IsNullOrEmpty(itemDefinitionId) || quantity <= 0)
			{
				return 0;
			}
			int num = quantity;
			List<ItemSlot> itemSlots = S1Storage.ItemSlots;
			for (int i = 0; i < itemSlots.Count; i++)
			{
				if (num <= 0)
				{
					break;
				}
				ItemSlot val = itemSlots[i];
				if (val.ItemInstance != null && val.ItemInstance.ID == itemDefinitionId)
				{
					int quantity2 = val.Quantity;
					int num2 = Math.Min(num, quantity2);
					num -= num2;
					if (num2 >= quantity2)
					{
						val.ClearStoredInstance(false);
					}
					else
					{
						val.ChangeQuantity(-num2, false);
					}
				}
			}
			return quantity - num;
		}

		public int RemoveAllOfDefinition(string itemDefinitionId)
		{
			if (string.IsNullOrEmpty(itemDefinitionId))
			{
				return 0;
			}
			int num = 0;
			List<ItemSlot> itemSlots = S1Storage.ItemSlots;
			for (int i = 0; i < itemSlots.Count; i++)
			{
				ItemSlot val = itemSlots[i];
				if (val.ItemInstance != null && val.ItemInstance.ID == itemDefinitionId)
				{
					num += val.Quantity;
					val.ClearStoredInstance(false);
				}
			}
			return num;
		}
	}
	public static class StorageManager
	{
		public static StorageInstance[] GetAll()
		{
			List<StorageInstance> list = new List<StorageInstance>();
			if (WorldStorageEntity.All == null)
			{
				return list.ToArray();
			}
			foreach (WorldStorageEntity item in WorldStorageEntity.All)
			{
				if ((Object)(object)item != (Object)null)
				{
					list.Add(new StorageInstance((StorageEntity)(object)item));
				}
			}
			return list.ToArray();
		}

		public static StorageInstance? FindByName(string name)
		{
			if (string.IsNullOrEmpty(name) || WorldStorageEntity.All == null)
			{
				return null;
			}
			foreach (WorldStorageEntity item in WorldStorageEntity.All)
			{
				if ((Object)(object)item != (Object)null && ((StorageEntity)item).StorageEntityName == name)
				{
					return new StorageInstance((StorageEntity)(object)item);
				}
			}
			return null;
		}

		public static StorageInstance[] FindByPredicate(Func<StorageInstance, bool> predicate)
		{
			if (predicate == null || WorldStorageEntity.All == null)
			{
				return Array.Empty<StorageInstance>();
			}
			List<StorageInstance> list = new List<StorageInstance>();
			foreach (WorldStorageEntity item in WorldStorageEntity.All)
			{
				if ((Object)(object)item != (Object)null)
				{
					StorageInstance storageInstance = new StorageInstance((StorageEntity)(object)item);
					if (predicate(storageInstance))
					{
						list.Add(storageInstance);
					}
				}
			}
			return list.ToArray();
		}
	}
}
namespace S1API.Shops
{
	public sealed class Shop
	{
		internal ShopInterface S1ShopInterface { get; }

		public string Name => S1ShopInterface.ShopName;

		internal Shop(ShopInterface shopInterface)
		{
			S1ShopInterface = shopInterface;
		}

		public bool HasItem(string itemId)
		{
			if (string.IsNullOrEmpty(itemId))
			{
				return false;
			}
			foreach (ShopListing listing in S1ShopInterface.Listings)
			{
				if (((ItemDefinition)(listing?.Item?)).ID == itemId)
				{
					return true;
				}
			}
			return false;
		}

		public bool SellsCategory(ItemCategory category)
		{
			//IL_0002: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			EItemCategory val = (EItemCategory)category;
			foreach (ShopListing listing in S1ShopInterface.Listings)
			{
				if ((Object)(object)listing?.Item != (Object)null && ((ItemDefinition)listing.Item).Category == val)
				{
					return true;
				}
			}
			return false;
		}

		public string[] GetItemIds()
		{
			List<string> list = new List<string>();
			foreach (ShopListing listing in S1ShopInterface.Listings)
			{
				if ((Object)(object)listing?.Item != (Object)null)
				{
					list.Add(((ItemDefinition)listing.Item).ID);
				}
			}
			return list.ToArray();
		}

		public bool AddItem(ItemDefinition item, float? customPrice = null)
		{
			if (item == null)
			{
				return false;
			}
			if (HasItem(item.ID))
			{
				return false;
			}
			return ShopIntegration.AddItemToShop(this, item, customPrice);
		}

		public bool RemoveItem(string itemId)
		{
			if (string.IsNullOrEmpty(itemId))
			{
				return false;
			}
			return ShopIntegration.RemoveItemFromShop(this, itemId);
		}
	}
	public static class ShopManager
	{
		private static readonly Log Logger = new Log("ShopManager");

		private static readonly List<Shop> _cachedShops = new List<Shop>();

		private static bool _cacheValid = false;

		public static Shop[] GetAllShops()
		{
			RefreshCacheIfNeeded();
			return _cachedShops.ToArray();
		}

		public static Shop GetShopByName(string shopName)
		{
			string shopName2 = shopName;
			if (string.IsNullOrEmpty(shopName2))
			{
				return null;
			}
			return GetAllShops().FirstOrDefault((Shop s) => string.Equals(s.Name, shopName2, StringComparison.OrdinalIgnoreCase));
		}

		public static Shop[] FindShopsByCategory(ItemCategory category)
		{
			return (from s in GetAllShops()
				where s.SellsCategory(category)
				select s).ToArray();
		}

		public static Shop[] FindShopsByItem(string itemId)
		{
			string itemId2 = itemId;
			if (string.IsNullOrEmpty(itemId2))
			{
				return Array.Empty<Shop>();
			}
			return (from s in GetAllShops()
				where s.HasItem(itemId2)
				select s).ToArray();
		}

		public static int AddToCompatibleShops(ItemDefinition item, float? customPrice = null)
		{
			if (item == null)
			{
				return 0;
			}
			Shop[] array = FindShopsByCategory(item.Category);
			int num = 0;
			Shop[] array2 = array;
			foreach (Shop shop in array2)
			{
				if (shop.AddItem(item, customPrice))
				{
					num++;
				}
			}
			if (num > 0)
			{
				Logger.Msg($"Added item '{item.Name}' to {num} compatible shop(s)");
			}
			return num;
		}

		public static int AddToShops(ItemDefinition item, params string[] shopNames)
		{
			return AddToShops(item, null, shopNames);
		}

		public static int AddToShops(ItemDefinition item, float? customPrice, params string[] shopNames)
		{
			if (item == null || shopNames == null || shopNames.Length == 0)
			{
				return 0;
			}
			int num = 0;
			foreach (string shopName in shopNames)
			{
				Shop shopByName = GetShopByName(shopName);
				if (shopByName != null && shopByName.AddItem(item, customPrice))
				{
					num++;
				}
			}
			return num;
		}

		internal static void InvalidateCache()
		{
			_cacheValid = false;
			_cachedShops.Clear();
		}

		private static void RefreshCacheIfNeeded()
		{
			if (_cacheValid)
			{
				return;
			}
			_cachedShops.Clear();
			try
			{
				List<ShopInterface> allShops = ShopInterface.AllShops;
				if (allShops == null)
				{
					_cacheValid = true;
					return;
				}
				foreach (ShopInterface item in allShops)
				{
					if ((Object)(object)item != (Object)null)
					{
						_cachedShops.Add(new Shop(item));
					}
				}
				_cacheValid = true;
			}
			catch (Exception ex)
			{
				Logger.Error("Failed to refresh shop cache: " + ex.Message);
				_cacheValid = false;
			}
		}
	}
}
namespace S1API.Saveables
{
	[Obsolete("Manual registration is no longer required. Classes that directly inherit from Saveable are automatically discovered. Remove calls to ModSaveableRegistry.Register() and simply inherit from Saveable.")]
	public static class ModSaveableRegistry
	{
		internal class Entry
		{
			public Saveable Saveable;

			public string? FolderName;
		}

		internal static readonly List<Entry> Registered = new List<Entry>();

		[Obsolete("Manual registration is no longer required. Classes that directly inherit from Saveable are automatically discovered.")]
		public static void Register(Saveable saveable, string? folderName = null)
		{
			if (saveable != null)
			{
				MelonLogger.Warning("ModSaveableRegistry.Register() is deprecated! The saveable '" + saveable.GetType().Name + "' will be automatically discovered. Mod users can safely ignore this warning - their saves will continue to work normally. Mod developers should remove ModSaveableRegistry.Register() calls and simply inherit from Saveable.");
				Registered.Add(new Entry
				{
					Saveable = saveable,
					FolderName = folderName
				});
			}
		}
	}
	internal static class SaveableAutoRegistry
	{
		[CompilerGenerated]
		private sealed class <GetOrCreateInstances>d__7 : IEnumerable<Saveable>, IEnumerable, IEnumerator<Saveable>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private Saveable <>2__current;

			private int <>l__initialThreadId;

			private List<Type>.Enumerator <>s__1;

			private Type <saveableType>5__2;

			private Saveable <instance>5__3;

			Saveable IEnumerator<Saveable>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GetOrCreateInstances>d__7(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>s__1 = default(List<Type>.Enumerator);
				<saveableType>5__2 = null;
				<instance>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					int num = <>1__state;
					if (num != 0)
					{
						if (num != 1)
						{
							return false;
						}
						<>1__state = -3;
						goto IL_00eb;
					}
					<>1__state = -1;
					<>s__1 = _discoveredSaveableTypes.GetEnumerator();
					<>1__state = -3;
					goto IL_00fa;
					IL_00eb:
					<instance>5__3 = null;
					<saveableType>5__2 = null;
					goto IL_00fa;
					IL_00fa:
					if (<>s__1.MoveNext())
					{
						<saveableType>5__2 = <>s__1.Current;
						if (!_instances.TryGetValue(<saveableType>5__2, out <instance>5__3))
						{
							try
							{
								<instance>5__3 = (Saveable)Activator.CreateInstance(<saveableType>5__2, nonPublic: true);
								if (<instance>5__3 != null)
								{
									_instances[<saveableType>5__2] = <instance>5__3;
								}
							}
							catch
							{
							}
						}
						if (<instance>5__3 != null)
						{
							<>2__current = <instance>5__3;
							<>1__state = 1;
							return true;
						}
						goto IL_00eb;
					}
					<>m__Finally1();
					<>s__1 = default(List<Type>.Enumerator);
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				((IDisposable)<>s__1).Dispose();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<Saveable> IEnumerable<Saveable>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <GetOrCreateInstances>d__7(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<Saveable>)this).GetEnumerator();
			}
		}

		private static readonly List<Type> _discoveredSaveableTypes = new List<Type>();

		private static readonly Dictionary<Type, Saveable> _instances = new Dictionary<Type, Saveable>();

		private static bool _discoveryPerformed = false;

		private static readonly object _lock = new object();

		public static IEnumerable<Saveable> GetRegisteredSaveables()
		{
			lock (_lock)
			{
				if (!_discoveryPerformed)
				{
					DiscoverSaveableTypes();
					_discoveryPerformed = true;
				}
				return GetOrCreateInstances();
			}
		}

		private static void DiscoverSaveableTypes()
		{
			try
			{
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly in assemblies)
				{
					try
					{
						if (assembly == executingAssembly)
						{
							continue;
						}
						string? fullName = assembly.FullName;
						if (fullName != null && fullName.StartsWith("System"))
						{
							continue;
						}
						string? fullName2 = assembly.FullName;
						if (fullName2 != null && fullName2.StartsWith("Unity"))
						{
							continue;
						}
						string? fullName3 = assembly.FullName;
						if (fullName3 != null && fullName3.StartsWith("mscorlib"))
						{
							continue;
						}
						string? fullName4 = assembly.FullName;
						if (fullName4 != null && fullName4.StartsWith("netstandard"))
						{
							continue;
						}
						string? fullName5 = assembly.FullName;
						if (fullName5 != null && fullName5.StartsWith("Microsoft"))
						{
							continue;
						}
						string? fullName6 = assembly.FullName;
						if (fullName6 != null && fullName6.StartsWith("Il2Cpp"))
						{
							continue;
						}
						string? fullName7 = assembly.FullName;
						if (fullName7 != null && fullName7.StartsWith("MelonLoader"))
						{
							continue;
						}
						string? fullName8 = assembly.FullName;
						if ((fullName8 != null && fullName8.StartsWith("0Harmony")) || assembly.IsDynamic)
						{
							continue;
						}
						Type[] array;
						try
						{
							array = assembly.GetTypes();
						}
						catch (ReflectionTypeLoadException ex)
						{
							array = ex.Types.Where((Type t) => t != null).ToArray();
						}
						catch
						{
							goto end_IL_0020;
						}
						Type[] array2 = array;
						foreach (Type type in array2)
						{
							try
							{
								if (!(type == null) && !type.IsAbstract && !type.IsInterface && !type.IsGenericTypeDefinition && IsDirectSaveableInheritor(type))
								{
									_discoveredSaveableTypes.Add(type);
								}
							}
							catch
							{
							}
						}
						end_IL_0020:;
					}
					catch
					{
					}
				}
			}
			catch (Exception ex2)
			{
				try
				{
					MelonLogger.Warning("[S1API] Error during saveable type discovery: " + ex2.Message);
				}
				catch
				{
				}
			}
		}

		private static bool IsDirectSaveableInheritor(Type type)
		{
			if (!typeof(Saveable).IsAssignableFrom(type))
			{
				return false;
			}
			if (type.IsAbstract || type.IsInterface)
			{
				return false;
			}
			Type baseType = type.BaseType;
			return baseType == typeof(Saveable);
		}

		[IteratorStateMachine(typeof(<GetOrCreateInstances>d__7))]
		private static IEnumerable<Saveable> GetOrCreateInstances()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetOrCreateInstances>d__7(-2);
		}

		internal static void ClearCache()
		{
			lock (_lock)
			{
				_discoveredSaveableTypes.Clear();
				_instances.Clear();
				_discoveryPerformed = false;
			}
		}
	}
	[AttributeUsage(AttributeTargets.Field)]
	public class SaveableField : Attribute
	{
		internal string SaveName { get; }

		public SaveableField(string saveName)
		{
			SaveName = saveName;
		}
	}
}
namespace S1API.Rendering
{
	public static class MaterialHelper
	{
		private static readonly Log Logger = new Log("MaterialHelper");

		public static void ReplaceMaterials(GameObject gameObject, Func<Material, bool> predicate, Action<Material> materialModifier)
		{
			if ((Object)(object)gameObject == (Object)null)
			{
				Logger.Warning("ReplaceMaterials called with null GameObject");
				return;
			}
			if (predicate == null || materialModifier == null)
			{
				Logger.Warning("ReplaceMaterials called with null predicate or modifier");
				return;
			}
			try
			{
				Renderer[] componentsInChildren = gameObject.GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val in componentsInChildren)
				{
					if (!((Object)(object)val == (Object)null))
					{
						ProcessRenderer(val, predicate, materialModifier);
					}
				}
			}
			catch (Exception ex)
			{
				Logger.Error("Error in ReplaceMaterials: " + ex.Message);
			}
		}

		public static Material CreateMetallicVariant(Material baseMaterial, Color metalColor, float metallic = 0.8f, float smoothness = 0.5f)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_0051: 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)
			if ((Object)(object)baseMaterial == (Object)null)
			{
				Logger.Error("CreateMetallicVariant called with null baseMaterial");
				return null;
			}
			try
			{
				Material val = new Material(baseMaterial)
				{
					name = ((Object)baseMaterial).name + "_metallic"
				};
				RemoveAllTextures(val);
				SetColor(val, "_BaseColor", metalColor);
				SetColor(val, "_Color", metalColor);
				SetFloat(val, "_Metallic", Mathf.Clamp01(metallic));
				SetFloat(val, "_Smoothness", Mathf.Clamp01(smoothness));
				SetFloat(val, "_Glossiness", Mathf.Clamp01(smoothness));
				return val;
			}
			catch (Exception ex)
			{
				Logger.Error("Error creating metallic variant: " + ex.Message);
				return null;
			}
		}

		public static void RemoveAllTextures(Material material)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			if ((Object)(object)material == (Object)null)
			{
				return;
			}
			try
			{
				Shader shader = material.shader;
				int propertyCount = shader.GetPropertyCount();
				for (int i = 0; i < propertyCount; i++)
				{
					if ((int)shader.GetPropertyType(i) == 4)
					{
						string propertyName = shader.GetPropertyName(i);
						material.SetTexture(propertyName, (Texture)null);
					}
				}
				material.mainTexture = null;
			}
			catch (Exception ex)
			{
				Logger.Warning("Error removing textures: " + ex.Message);
			}
		}

		public static bool SetColor(Material material, string propertyName, Color color)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)material == (Object)null || string.IsNullOrEmpty(propertyName))
			{
				return false;
			}
			try
			{
				if (material.HasProperty(propertyName))
				{
					material.SetColor(propertyName, color);
					return true;
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("Error setting color property '" + propertyName + "': " + ex.Message);
			}
			return false;
		}

		public static bool SetFloat(Material material, string propertyName, float value)
		{
			if ((Object)(object)material == (Object)null || string.IsNullOrEmpty(propertyName))
			{
				return false;
			}
			try
			{
				if (material.HasProperty(propertyName))
				{
					material.SetFloat(propertyName, value);
					return true;
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("Error setting float property '" + propertyName + "': " + ex.Message);
			}
			return false;
		}

		public static bool SetTexture(Material material, string propertyName, Texture texture)
		{
			if ((Object)(object)material == (Object)null || string.IsNullOrEmpty(propertyName))
			{
				return false;
			}
			try
			{
				if (material.HasProperty(propertyName))
				{
					material.SetTexture(propertyName, texture);
					return true;
				}
			}
			catch (Exception ex)
			{
				Logger.Warning("Error setting texture property '" + propertyName + "': " + ex.Message);
			}
			return false;
		}

		public static void ConfigureMaterial(Material material, Action<Material> configurator)
		{
			if ((Object)(object)material == (Object)null || configurator == null)
			{
				return;
			}
			try
			{
				configurator(material);
			}
			catch (Exception ex)
			{
				Logger.Error("Error configuring material: " + ex.Message);
			}
		}

		private static void ProcessRenderer(Renderer renderer, Func<Material, bool> predicate, Action<Material> materialModifier)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			Material[] materials = renderer.materials;
			bool flag = false;
			for (int i = 0; i < materials.Length; i++)
			{
				Material val = materials[i];
				if (!((Object)(object)val == (Object)null) && predicate(val))
				{
					Material val2 = new Material(val)
					{
						name = ((Object)val).name + "_modified"
					};
					materialModifier(val2);
					materials[i] = val2;
					flag = true;
				}
			}
			if (flag)
			{
				renderer.materials = materials;
			}
		}
	}
}
namespace S1API.Quests
{
	public abstract class Quest : Saveable
	{
		[CompilerGenerated]
		private sealed class <EnsurePOICreation>d__34 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public QuestEntry questEntry;

			private Exception <ex>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <EnsurePOICreation>d__34(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<ex>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)questEntry.PoILocation != (Object)null && questEntry.AutoCreatePoI)
					{
						try
						{
							questEntry.CreatePoI();
						}
						catch (Exception ex)
						{
							<ex>5__1 = ex;
							Debug.LogWarning((object)("[S1API] Failed to create POI for quest entry: " + <ex>5__1.Message));
						}
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public readonly List<QuestEntry> QuestEntries = new List<QuestEntry>();

		[SaveableField("QuestData")]
		private readonly QuestData _questData;

		internal readonly Quest S1Quest;

		private readonly GameObject _gameObject;

		protected abstract string Title { get; }

		protected abstract string Description { get; }

		protected virtual bool AutoBegin => true;

		protected QuestState QuestState => (QuestState)S1Quest.State;

		internal string? SaveFolder => S1Quest.SaveFolderName;

		protected virtual Sprite? QuestIcon => null;

		public event Action OnComplete
		{
			add
			{
				EventHelper.AddListener(value, S1Quest.onComplete);
			}
			remove
			{
				EventHelper.RemoveListener(value, S1Quest.onComplete);
			}
		}

		public event Action? OnFail;

		public Quest()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Expected O, but got Unknown
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Expected O, but got Unknown
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Expected O, but got Unknown
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Expected O, but got Unknown
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Expected O, but got Unknown
			_questData = new QuestData(GetType().Name);
			_gameObject = new GameObject("Quest");
			S1Quest = _gameObject.AddComponent<Quest>();
			S1Quest.StaticGUID = string.Empty;
			FieldInfo fieldInfo = AccessTools.Field(typeof(Quest), "title");
			fieldInfo.SetValue(S1Quest, Title);
			S1Quest.onActiveState = new UnityEvent();
			S1Quest.onComplete = new UnityEvent();
			S1Quest.onInitialComplete = new UnityEvent();
			S1Quest.onQuestBegin = new UnityEvent();
			S1Quest.onQuestEnd = new UnityEvent<EQuestState>();
			S1Quest.onTrackChange = new UnityEvent<bool>();
			S1Quest.TrackOnBegin = true;
			S1Quest.AutoCompleteOnAllEntriesComplete = true;
			FieldInfo fieldInfo2 = AccessTools.Field(typeof(Quest), "autoInitialize");
			fieldInfo2.SetValue(S1Quest, false);
			GameObject val = new GameObject("IconPrefab", new Type[3]
			{
				CrossType.Of<RectTransform>(),
				CrossType.Of<CanvasRenderer>(),
				CrossType.Of<Image>()
			});
			val.transform.SetParent(_gameObject.transform);
			Image component = val.GetComponent<Image>();
			component.sprite = QuestIcon ?? ((App<ContactsApp>)(object)PlayerSingleton<ContactsApp>.Instance).AppIcon;
			S1Quest.IconPrefab = val.GetComponent<RectTransform>();
			GameObject val2 = new GameObject("PoIUIPrefab", new Type[4]
			{
				CrossType.Of<RectTransform>(),
				CrossType.Of<CanvasRenderer>(),
				CrossType.Of<EventTrigger>(),
				CrossType.Of<Button>()
			});
			val2.transform.SetParent(_gameObject.transform);
			GameObject val3 = new GameObject("MainLabel", new Type[3]
			{
				CrossType.Of<RectTransform>(),
				CrossType.Of<CanvasRenderer>(),
				CrossType.Of<Text>()
			});
			val3.transform.SetParent(val2.transform);
			GameObject val4 = new GameObject("IconContainer", new Type[3]
			{
				CrossType.Of<RectTransform>(),
				CrossType.Of<CanvasRenderer>(),
				CrossType.Of<Image>()
			});
			val4.transform.SetParent(val2.transform);
			Image component2 = val4.GetComponent<Image>();
			component2.sprite = QuestIcon ?? ((App<ContactsApp>)(object)PlayerSingleton<ContactsApp>.Instance).AppIcon;
			RectTransform component3 = ((Component)component2).GetComponent<RectTransform>();
			component3.sizeDelta = new Vector2(20f, 20f);
			GameObject val5 = new GameObject("POIPrefab");
			val5.SetActive(false);
			val5.transform.SetParent(_gameObject.transform);
			POI val6 = val5.AddComponent<POI>();
			val6.DefaultMainText = "Did it work?";
			FieldInfo fieldInfo3 = AccessTools.Field(typeof(POI), "UIPrefab");
			fieldInfo3.SetValue(val6, val2);
			S1Quest.PoIPrefab = val5;
			S1Quest.onQuestEnd.AddListener((UnityAction<EQuestState>)OnQuestEnded);
		}

		internal override void CreateInternal()
		{
			base.CreateInternal();
			S1Quest.InitializeQuest(Title, Description, Array.Empty<QuestEntryData>(), S1Quest?.StaticGUID);
			if (AutoBegin)
			{
				Quest s1Quest = S1Quest;
				if (s1Quest != null)
				{
					s1Quest.Begin(true);
				}
			}
		}

		internal override void SaveInternal(string folderPath, ref List<string> extraSaveables)
		{
			string text = Path.Combine(folderPath, S1Quest.SaveFolderName);
			if (!Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
			}
			base.SaveInternal(text, ref extraSaveables);
		}

		internal void OnQuestEnded(EQuestState questState)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			if ((int)questState == 3)
			{
				this.OnFail?.Invoke();
			}
			Quest.Quests.Remove(S1Quest);
			QuestManager.Quests.Remove(this);
		}

		protected QuestEntry AddEntry(string title, Vector3? poiPosition = null)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("QuestEntry");
			Transform transform = val.transform;
			GameObject gameObject = _gameObject;
			transform.SetParent((gameObject != null) ? gameObject.transform : null);
			QuestEntry val2 = val.AddComponent<QuestEntry>();
			if (!poiPosition.HasValue)
			{
				val2.PoILocation = null;
				val2.AutoCreatePoI = false;
			}
			else
			{
				val2.PoILocation = val.transform;
				val2.AutoCreatePoI = true;
			}
			S1Quest.Entries.Add(val2);
			QuestEntry questEntry = new QuestEntry(val2)
			{
				Title = title
			};
			if (poiPosition.HasValue)
			{
				questEntry.POIPosition = poiPosition.Value;
			}
			QuestEntries.Add(questEntry);
			return questEntry;
		}

		protected QuestEntry AddEntry(string title, NPC npc)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			if (npc == null)
			{
				throw new ArgumentNullException("npc");
			}
			GameObject val = new GameObject("QuestEntry");
			Transform transform = val.transform;
			GameObject gameObject = _gameObject;
			transform.SetParent((gameObject != null) ? gameObject.transform : null);
			val.SetActive(true);
			QuestEntry val2 = val.AddComponent<QuestEntry>();
			Transform transform2 = npc.Transform;
			if ((Object)(object)transform2 == (Object)null)
			{
				val2.PoILocation = null;
				val2.AutoCreatePoI = false;
				val2.AutoUpdatePoILocation = false;
			}
			else
			{
				val2.PoILocation = transform2;
				val2.AutoCreatePoI = true;
				val2.AutoUpdatePoILocation = true;
			}
			S1Quest.Entries.Add(val2);
			QuestEntry questEntry = new QuestEntry(val2)
			{
				Title = title
			};
			QuestEntries.Add(questEntry);
			if ((Object)(object)val2.PoILocation != (Object)null && val2.AutoCreatePoI)
			{
				MelonCoroutines.Start(EnsurePOICreation(val2));
			}
			return questEntry;
		}

		public void Begin()
		{
			Quest s1Quest = S1Quest;
			if (s1Quest != null)
			{
				s1Quest.Begin(true);
			}
		}

		public void Cancel()
		{
			Quest s1Quest = S1Quest;
			if (s1Quest != null)
			{
				s1Quest.Cancel(true);
			}
		}

		public void Expire()
		{
			Quest s1Quest = S1Quest;
			if (s1Quest != null)
			{
				s1Quest.Expire(true);
			}
		}

		public void Fail()
		{
			Quest s1Quest = S1Quest;
			if (s1Quest != null)
			{
				s1Quest.Fail(true);
			}
		}

		public void Complete()
		{
			Quest s1Quest = S1Quest;
			if (s1Quest != null)
			{
				s1Quest.Complete(true);
			}
		}

		public void End()
		{
			Quest s1Quest = S1Quest;
			if (s1Quest != null)
			{
				s1Quest.End();
			}
		}

		[IteratorStateMachine(typeof(<EnsurePOICreation>d__34))]
		private static IEnumerator EnsurePOICreation(QuestEntry questEntry)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <EnsurePOICreation>d__34(0)
			{
				questEntry = questEntry
			};
		}
	}
	public class QuestData
	{
		public readonly string ClassName;

		public QuestData(string className)
		{
			ClassName = className;
		}
	}
	public class QuestEntry
	{
		[CompilerGenerated]
		private sealed class <EnsurePOICreationForNPC>d__18 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public QuestEntry questEntry;

			private Exception <ex>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <EnsurePOICreationForNPC>d__18(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<ex>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)questEntry.PoILocation != (Object)null && questEntry.AutoCreatePoI)
					{
						try
						{
							questEntry.CreatePoI();
						}
						catch (Exception ex)
						{
							<ex>5__1 = ex;
							Debug.LogWarning((object)("[S1API] Failed to create POI for quest entry: " + <ex>5__1.Message));
						}
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		internal readonly QuestEntry S1QuestEntry;

		public QuestState State => (QuestState)S1QuestEntry.State;

		public string Title
		{
			get
			{
				return S1QuestEntry.Title;
			}
			set
			{
				S1QuestEntry.SetEntryTitle(value);
			}
		}

		public Vector3 POIPosition
		{
			get
			{
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: 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)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				object obj = global::S1API.Internal.Utils.ReflectionUtils.TryGetFieldOrProperty(S1QuestEntry, "PoILocation");
				Transform val = (Transform)((obj is Transform) ? obj : null);
				if (val != null && (Object)(object)val != (Object)null)
				{
					return val.position;
				}
				return Vector3.zero;
			}
			set
			{
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				object obj = global::S1API.Internal.Utils.ReflectionUtils.TryGetFieldOrProperty(S1QuestEntry, "PoILocation");
				Transform val = (Transform)((obj is Transform) ? obj : null);
				if (val != null && (Object)(object)val != (Object)null)
				{
					val.position = value;
					return;
				}
				Transform transform = ((Component)S1QuestEntry).transform;
				S1QuestEntry.PoILocation = transform;
				transform.position = value;
				S1QuestEntry.AutoCreatePoI = true;
			}
		}

		public event Action OnComplete
		{
			add
			{
				EventHelper.AddListener(value, S1QuestEntry.onComplete);
			}
			remove
			{
				EventHelper.RemoveListener(value, S1QuestEntry.onComplete);
			}
		}

		internal QuestEntry(QuestEntry questEntry)
		{
			S1QuestEntry = questEntry;
		}

		public void Begin()
		{
			S1QuestEntry.Begin();
		}

		public void Complete()
		{
			S1QuestEntry.Complete();
		}

		public void SetState(QuestState questState)
		{
			S1QuestEntry.SetState((EQuestState)questState, true);
		}

		public bool SetPOIToNPC<T>() where T : NPC
		{
			NPC nPC = NPC.Get<T>();
			if (nPC == null)
			{
				return false;
			}
			return SetPOIToNPC(nPC);
		}

		public bool SetPOIToNPC(NPC npc)
		{
			if (npc == null || (Object)(object)npc.gameObject == (Object)null)
			{
				return false;
			}
			Transform transform = npc.Transform;
			if ((Object)(object)transform == (Object)null)
			{
				return false;
			}
			S1QuestEntry.PoILocation = transform;
			S1QuestEntry.AutoCreatePoI = true;
			S1QuestEntry.AutoUpdatePoILocation = true;
			MelonCoroutines.Start(EnsurePOICreationForNPC(S1QuestEntry));
			return true;
		}

		[IteratorStateMachine(typeof(<EnsurePOICreationForNPC>d__18))]
		private static IEnumerator EnsurePOICreationForNPC(QuestEntry questEntry)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <EnsurePOICreationForNPC>d__18(0)
			{
				questEntry = questEntry
			};
		}
	}
	public static class QuestManager
	{
		internal static readonly List<Quest> Quests = new List<Quest>();

		public static Quest CreateQuest<T>(string? guid = null) where T : Quest
		{
			return CreateQuest(typeof(T), guid);
		}

		public static Quest CreateQuest(Type questType, string? guid = null)
		{
			Quest quest = (Quest)Activator.CreateInstance(questType);
			if (quest == null)
			{
				throw new Exception("Unable to create quest instance of " + questType.FullName + "!");
			}
			Quests.Add(quest);
			return quest;
		}

		public static Quest? GetQuestByGuid(string guid)
		{
			string guid2 = guid;
			return Quests.FirstOrDefault((Quest x) => x.S1Quest.StaticGUID == guid2);
		}

		public static Quest? GetQuestByName(string questName)
		{
			string questName2 = questName;
			return Quests.FirstOrDefault((Quest x) => x.S1Quest.Title == questName2);
		}

		internal static object? GetBaseGameQuestByName(string questTitle)
		{
			try
			{
				List<Quest> quests = Quest.Quests;
				if (quests != null)
				{
					foreach (Quest item in quests)
					{
						if ((Object)(object)item != (Object)null && item.Title == questTitle)
						{
							return item;
						}
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("[QuestManager] Exception while searching for base game quest '" + questTitle + "': " + ex.Message);
			}
			return null;
		}

		public static QuestWrapper? Get<T>() where T : IQuestIdentifier
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			Type typeFromHandle = typeof(T);
			string text = TryGetNameFromIdentifier(typeFromHandle);
			if (string.IsNullOrEmpty(text))
			{
				return null;
			}
			Quest questByName = GetQuestByName(text);
			if (questByName != null)
			{
				return new QuestWrapper(questByName);
			}
			object baseGameQuestByName = GetBaseGameQuestByName(text);
			if (baseGameQuestByName != null)
			{
				return new QuestWrapper((Quest)baseGameQuestByName);
			}
			return null;
		}

		private static string TryGetNameFromIdentifier(Type t)
		{
			try
			{
				object obj = t.GetCustomAttributes(inherit: false).FirstOrDefault((object a) => a.GetType().FullName == typeof(QuestNameAttribute).FullName);
				if (obj != null)
				{
					return obj.GetType().GetProperty("Name", BindingFlags.Instance | BindingFlags.Public)?.GetVa

Plugins/S1APILoader.MelonLoader.dll

Decompiled 2 days ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using MelonLoader;
using Microsoft.CodeAnalysis;
using S1APILoader;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(global::S1APILoader.S1APILoader), "S1APILoader", "2.4.4", "KaBooMa", null)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("S1APILoader")]
[assembly: AssemblyConfiguration("MonoMelon")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+b99ac756c0cc4be3aad62571f3f21a58d1301be9")]
[assembly: AssemblyProduct("S1APILoader")]
[assembly: AssemblyTitle("S1APILoader")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace S1APILoader
{
	public class S1APILoader : MelonPlugin
	{
		private const string BuildFolderName = "S1API";

		public override void OnPreModsLoaded()
		{
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			if (directoryName == null)
			{
				throw new Exception("Failed to identify plugins folder.");
			}
			string fullPath = Path.GetFullPath(Path.Combine(directoryName, "../Mods"));
			string folder = Path.Combine(directoryName, "S1API");
			string text = (MelonUtils.IsGameIl2Cpp() ? "Il2Cpp" : "Mono");
			string build = ((!MelonUtils.IsGameIl2Cpp()) ? "Il2Cpp" : "Mono");
			MelonLogger.Msg("Loading S1API for " + text + "...");
			NormalizeBuild(fullPath, text, shouldBeEnabled: true, "S1API.{0}.MelonLoader.dll");
			NormalizeBuild(fullPath, build, shouldBeEnabled: false, "S1API.{0}.MelonLoader.dll");
			NormalizeBuild(folder, text, shouldBeEnabled: true, "S1API.{0}.dll");
			NormalizeBuild(folder, build, shouldBeEnabled: false, "S1API.{0}.dll");
			MelonLogger.Msg("Successfully loaded S1API for " + text + "!");
		}

		private static void NormalizeBuild(string folder, string build, bool shouldBeEnabled, string fileNamePattern)
		{
			if (!Directory.Exists(folder))
			{
				return;
			}
			string path = string.Format(fileNamePattern, build);
			string text = Path.Combine(folder, path);
			string text2 = text + ".disabled";
			bool flag = File.Exists(text);
			bool flag2 = File.Exists(text2);
			if (!flag && !flag2)
			{
				return;
			}
			if (shouldBeEnabled)
			{
				if (flag && !flag2)
				{
					return;
				}
				string text3 = null;
				if (flag2)
				{
					text3 = text2;
				}
				if (flag)
				{
					text3 = ChooseNewest(text3, text);
				}
				if (text3 != null)
				{
					if (StringComparer.OrdinalIgnoreCase.Equals(text3, text2))
					{
						SafeDelete(text);
						SafeMoveReplace(text2, text);
					}
					else if (flag2)
					{
						SafeDelete(text2);
					}
				}
			}
			else
			{
				if ((!flag && flag2) || !flag)
				{
					return;
				}
				SafeDelete(text2);
				if (!SafeMoveReplace(text, text2) || File.Exists(text))
				{
					MelonLogger.Warning("Failed to disable '" + text + "'. File may be locked or in use.");
					if (File.Exists(text))
					{
						TryCopyAndDelete(text, text2);
					}
				}
			}
		}

		private static string ChooseNewest(string? currentBestPath, string candidatePath)
		{
			if (currentBestPath == null)
			{
				return candidatePath;
			}
			Version version = TryGetAssemblyVersion(currentBestPath);
			Version version2 = TryGetAssemblyVersion(candidatePath);
			if (version != null && version2 != null)
			{
				return (version2 > version) ? candidatePath : currentBestPath;
			}
			DateTime safeWriteTimeUtc = GetSafeWriteTimeUtc(currentBestPath);
			DateTime safeWriteTimeUtc2 = GetSafeWriteTimeUtc(candidatePath);
			return (safeWriteTimeUtc2 > safeWriteTimeUtc) ? candidatePath : currentBestPath;
		}

		private static Version? TryGetAssemblyVersion(string path)
		{
			try
			{
				return AssemblyName.GetAssemblyName(path).Version;
			}
			catch
			{
				return null;
			}
		}

		private static DateTime GetSafeWriteTimeUtc(string path)
		{
			try
			{
				return File.GetLastWriteTimeUtc(path);
			}
			catch
			{
				return DateTime.MinValue;
			}
		}

		private static bool SafeMoveReplace(string sourcePath, string destinationPath)
		{
			try
			{
				if (File.Exists(destinationPath))
				{
					File.Delete(destinationPath);
				}
				File.Move(sourcePath, destinationPath);
				return true;
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("Failed to move '" + sourcePath + "' to '" + destinationPath + "': " + ex.Message);
				return false;
			}
		}

		private static void TryCopyAndDelete(string sourcePath, string destinationPath)
		{
			try
			{
				if (File.Exists(destinationPath))
				{
					File.Delete(destinationPath);
				}
				File.Copy(sourcePath, destinationPath, overwrite: true);
				try
				{
					File.Delete(sourcePath);
				}
				catch
				{
					MelonLogger.Warning("Copied '" + sourcePath + "' to '" + destinationPath + "' but could not delete source. You may need to manually delete it.");
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("Failed to copy '" + sourcePath + "' to '" + destinationPath + "': " + ex.Message);
			}
		}

		private static void SafeDelete(string path)
		{
			try
			{
				if (File.Exists(path))
				{
					File.Delete(path);
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("Failed to delete '" + path + "': " + ex.Message);
			}
		}
	}
}