Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of NPCLaunderers v1.0.3
IL2CPP/Mods/NPCLaunderers_IL2CPP.dll
Decompiled 4 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using HarmonyLib; using Il2CppFishNet.Object; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppNewtonsoft.Json.Linq; using Il2CppScheduleOne.DevUtilities; using Il2CppScheduleOne.Dialogue; using Il2CppScheduleOne.Economy; using Il2CppScheduleOne.GameTime; using Il2CppScheduleOne.ItemFramework; using Il2CppScheduleOne.Money; using Il2CppScheduleOne.NPCs; using Il2CppScheduleOne.Persistence; using Il2CppScheduleOne.PlayerScripts; using Il2CppScheduleOne.Product; using Il2CppScheduleOne.Quests; using Il2CppScheduleOne.UI; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppSystem.IO; using Il2CppTMPro; using MelonLoader; using MelonLoader.Preferences; using MelonLoader.Utils; using Microsoft.CodeAnalysis; using NPCLaunderers; using NPCLaunderers.LaundererSaveManager; using NPCLaunderers.NPCScripts; using NPCLaunderers.UI; using UnityEngine; using UnityEngine.Events; using UnityEngine.UIElements; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(Core), "NPCLaunderers", "1.0.3", "weedeej", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("NPCLaunderers_IL2CPP")] [assembly: AssemblyConfiguration("IL2CPP")] [assembly: AssemblyFileVersion("1.0.3")] [assembly: AssemblyInformationalVersion("1.0.0+61985eb8d7b4c751f4ff59154fa080438265035e")] [assembly: AssemblyProduct("NPCLaunderers_IL2CPP")] [assembly: AssemblyTitle("NPCLaunderers_IL2CPP")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.3.0")] [module: UnverifiableCode] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace NPCLaunderers { public class Core : MelonMod { [CompilerGenerated] private sealed class <DelayedStart>d__3 : 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 <DelayedStart>d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSecondsRealtime(5f); <>1__state = 1; return true; case 1: { <>1__state = -1; Action action = delegate { foreach (Launderer item in Object.FindObjectsOfType<Launderer>()) { item.laundererData.Save(); } }; Action action2 = delegate { foreach (Launderer item2 in Object.FindObjectsOfType<Launderer>()) { item2.WeekPass(); } }; Singleton<SaveManager>.Instance.onSaveStart.AddListener(UnityAction.op_Implicit(action)); TimeManager instance = NetworkSingleton<TimeManager>.Instance; instance.onWeekPass += Action.op_Implicit(action2); 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 Il2CppAssetBundle bundle; public override void OnInitializeMelon() { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown MelonPreferences.CreateCategory("NPCLaunderers", "NPCLaunderers Settings"); MelonPreferences.CreateEntry<bool>("NPCLaunderers", "EnableEnvy", true, "Enable Envy", "Allows your launderers to get envy of what you earn and request more cut.", false, false, (ValueValidator)null); MelonPreferences.CreateEntry<bool>("NPCLaunderers", "EnableCutDecreaseEvent", true, "Enable Request Product", "Allows your launderers to request a product to reduce cut", false, false, (ValueValidator)null); MelonPreferences.Save(); ClassInjector.RegisterTypeInIl2Cpp<Launderer>(); ClassInjector.RegisterTypeInIl2Cpp<LaundererData>(); try { Stream manifestResourceStream = ((MelonBase)this).MelonAssembly.Assembly.GetManifestResourceStream("NPCLaunderers.Assets.launderers.assetbundle"); if (manifestResourceStream == null) { ((MelonBase)this).Unregister("AssetBundle stream not found", false); return; } byte[] array; using (MemoryStream memoryStream = new MemoryStream()) { manifestResourceStream.CopyTo(memoryStream); array = memoryStream.ToArray(); } Stream val = (Stream)new MemoryStream(Il2CppStructArray<byte>.op_Implicit(array)); bundle = Il2CppAssetBundleManager.LoadFromStream(val); } catch (Exception value) { ((MelonBase)this).Unregister($"Failed to load AssetBundle. Please report to dev: {value}", false); return; } ((MelonBase)this).LoggerInstance.Msg("Initialized."); } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { ((MelonMod)this).OnSceneWasLoaded(buildIndex, sceneName); if (sceneName == "Main") { MelonCoroutines.Start(DelayedStart()); } } [IteratorStateMachine(typeof(<DelayedStart>d__3))] private IEnumerator DelayedStart() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedStart>d__3(0); } } } namespace NPCLaunderers.UI { public class LaundererUI { private bool isOpen; private Launderer launderer; public GameObject gameObject; private Il2CppAssetBundle bundle; public LaundererUI(Launderer launderer) { this.launderer = launderer; Il2CppAssetBundle[] array = Il2CppAssetBundleManager.GetAllLoadedAssetBundles().ToArray(); if (array.Length == 1) { bundle = array[0]; return; } Il2CppAssetBundle[] array2 = array; foreach (Il2CppAssetBundle val in array2) { if (val.Contains("assets/laundererui.prefab")) { bundle = val; break; } } } public void SetLaunderer(Launderer launderer) { this.launderer = launderer; } public void Open() { if (!isOpen) { Show(); isOpen = true; } } public void Close() { if (isOpen) { Hide(); isOpen = false; } } private void Show() { gameObject = bundle.LoadAsset<GameObject>("assets/laundererui.prefab"); gameObject = Object.Instantiate<GameObject>(gameObject); VisualElement val = UQueryExtensions.Q<VisualElement>(gameObject.GetComponent<UIDocument>().rootVisualElement, "LaundererContent", (string)null); ((TextElement)UQueryExtensions.Q<Label>(UQueryExtensions.Q<VisualElement>(val, "Header", (string)null), "Version", (string)null)).text = ((MelonBase)MelonAssembly.FindMelonInstance<Core>()).Info.Version; VisualElement obj = UQueryExtensions.Q<VisualElement>(val, "buttons", (string)null); Button val2 = UQueryExtensions.Q<Button>(obj, "btn_close", (string)null); Button obj2 = UQueryExtensions.Q<Button>(obj, "btn_submit", (string)null); IntegerField amountField = UQueryExtensions.Q<IntegerField>(val, "NumberInput", (string)null); Label obj3 = UQueryExtensions.Q<Label>((VisualElement)(object)amountField, "NpcName", (string)null); ((BaseField<int>)(object)amountField).label = ((BaseField<int>)(object)amountField).label.Replace("<MaxLaunder>", $"{launderer.laundererData.InstanceMaxLaunderAmount}"); ((TextElement)obj3).text = ((TextElement)obj3).text.Replace("<NPCNAME>", launderer.nPC.fullName); ((CallbackEventHandler)obj2).RegisterCallback<ClickEvent>(EventCallback<ClickEvent>.op_Implicit((Action<ClickEvent>)delegate { MoneyManager instance = NetworkSingleton<MoneyManager>.Instance; try { float num = ((BaseField<int>)(object)amountField).value; if (!(num < 1f)) { if (instance.cashBalance < num) { MelonLogger.Error($"Input value {num} exceeds cash balance {instance.cashBalance}"); Singleton<NotificationsManager>.Instance.SendNotification(launderer.nPC.FirstName, "<color=#f54c4c>You don't have enough money</color>", launderer.nPC.MugshotSprite, 5f, true); } else if (num > launderer.laundererData.InstanceMaxLaunderAmount) { MelonLogger.Error($"Input value {num} exceeds max launder amount {launderer.laundererData.InstanceMaxLaunderAmount}"); Singleton<NotificationsManager>.Instance.SendNotification(launderer.nPC.FirstName, $"<color=#f54c4c>Max of ${launderer.laundererData.InstanceMaxLaunderAmount}</color>", launderer.nPC.MugshotSprite, 5f, true); } else { instance.ChangeCashBalance(0f - num, true, true); launderer.laundererData.CurrentLaunderAmount = num; launderer.laundererData.CurrentTimeLeftSeconds = 720f; string text = $"Laundering <color=#16F01C>${num}</color>.I will transfer <color=#6b9cff>${launderer.laundererData.ReturnLaunderAmount}</color> to your account in 12 hours."; launderer.nPC.SendTextMessage(text); Close(); } } } catch (Exception ex) { MelonLogger.Error($"Failed to load LaundererUI: {ex}"); if (ex is FormatException) { Singleton<NotificationsManager>.Instance.SendNotification(launderer.nPC.FirstName, "<color=#f54c4c>Invalid input value</color>", launderer.nPC.MugshotSprite, 5f, true); } } }), (TrickleDown)0); ((CallbackEventHandler)val2).RegisterCallback<ClickEvent>(EventCallback<ClickEvent>.op_Implicit((Action<ClickEvent>)delegate { Close(); }), (TrickleDown)0); PlayerSingleton<PlayerCamera>.Instance.AddActiveUIElement(((Object)gameObject).name); Player.Deactivate(true); } private void Hide() { PlayerSingleton<PlayerCamera>.Instance.RemoveActiveUIElement(((Object)gameObject).name); Player.Activate(); Object.Destroy((Object)(object)gameObject); } } } namespace NPCLaunderers.LaundererSaveManager { [Serializable] public class LaundererData : Object { public NPC NPC; public float MinLaunderAmount; public float MaxLaunderAmount; public LaundererTier LaundererTier; public double CutPercentage; public bool isUnlocked; public float CurrentTimeLeftSeconds; public float CurrentLaunderAmount; public float WeekLaunderReturn; public float WeekCutAmount; public string RequiredProductID; public float InstanceMaxLaunderAmount; private string SaveFilePath; public float ReturnLaunderAmount => Mathf.Floor(CurrentLaunderAmount - CurrentLaunderAmount * (float)(CutPercentage / 100.0)); public float CutAmount => Mathf.Floor(CurrentLaunderAmount * (float)(CutPercentage / 100.0)); public LaundererData(IntPtr ptr) : base(ptr) { } public LaundererData(NPC nPC) { NPC = nPC; LaundererTier = Launderers.TierOf[nPC.FirstName]; float[] array = Launderers.LaunderAmountRanges[LaundererTier]; MinLaunderAmount = array[0]; MaxLaunderAmount = array[1]; WeekLaunderReturn = 0f; WeekCutAmount = 0f; CurrentLaunderAmount = 0f; CurrentTimeLeftSeconds = 0f; isUnlocked = false; InstanceMaxLaunderAmount = 0f; RequiredProductID = ""; CutPercentage = 10.0; string loadedGameFolderPath = Singleton<LoadManager>.Instance.LoadedGameFolderPath; int startIndex = loadedGameFolderPath.IndexOf("Saves\\") + 5; string[] array2 = loadedGameFolderPath.Substring(startIndex).Split(new char[1] { '\\' }, StringSplitOptions.RemoveEmptyEntries); SaveFilePath = Path.Combine(MelonEnvironment.UserDataDirectory, "Launderers", $"{array2[0]}_{array2[1]}_{nPC.ID}.json"); if (!Directory.Exists(Path.Combine(MelonEnvironment.UserDataDirectory, "Launderers"))) { Directory.CreateDirectory(Path.Combine(MelonEnvironment.UserDataDirectory, "Launderers")); } } public void Save() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Expected O, but got Unknown //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Expected O, but got Unknown //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Expected O, but got Unknown //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Expected O, but got Unknown JObject val = new JObject(); ((JContainer)val).Add((Object)new JProperty("FirstName", Object.op_Implicit(NPC.FirstName))); ((JContainer)val).Add((Object)new JProperty("LastName", Object.op_Implicit(NPC.LastName))); ((JContainer)val).Add((Object)new JProperty("ID", Object.op_Implicit(NPC.ID))); ((JContainer)val).Add((Object)new JProperty("Tier", Object.op_Implicit(LaundererTier.ToString()))); ((JContainer)val).Add((Object)new JProperty("MinLaunderAmount", Object.op_Implicit(MinLaunderAmount))); ((JContainer)val).Add((Object)new JProperty("MaxLaunderAmount", Object.op_Implicit(MaxLaunderAmount))); ((JContainer)val).Add((Object)new JProperty("isUnlocked", Object.op_Implicit(isUnlocked))); ((JContainer)val).Add((Object)new JProperty("CutPercentage", Object.op_Implicit(CutPercentage))); ((JContainer)val).Add((Object)new JProperty("CurrentTimeLeftSeconds", Object.op_Implicit(CurrentTimeLeftSeconds))); ((JContainer)val).Add((Object)new JProperty("CurrentLaunderAmount", Object.op_Implicit(CurrentLaunderAmount))); ((JContainer)val).Add((Object)new JProperty("WeekLaunderReturn", Object.op_Implicit(WeekLaunderReturn))); ((JContainer)val).Add((Object)new JProperty("WeekCutAmount", Object.op_Implicit(WeekCutAmount))); ((JContainer)val).Add((Object)new JProperty("RequiredProductID", Object.op_Implicit(RequiredProductID))); ((JContainer)val).Add((Object)new JProperty("InstanceMaxLaunderAmount", Object.op_Implicit(InstanceMaxLaunderAmount))); File.WriteAllText(SaveFilePath, ((Object)val).ToString()); Debug.Log(Object.op_Implicit(NPC.FirstName + " - Saved to: " + SaveFilePath)); } public LaundererData Load() { if (!File.Exists(SaveFilePath)) { return this; } JObject val = JObject.Parse(File.ReadAllText(SaveFilePath)); MinLaunderAmount = ((JToken)val).Value<float>(Object.op_Implicit("MinLaunderAmount")); MaxLaunderAmount = ((JToken)val).Value<float>(Object.op_Implicit("MaxLaunderAmount")); CutPercentage = ((JToken)val).Value<double>(Object.op_Implicit("CutPercentage")); isUnlocked = ((JToken)val).Value<bool>(Object.op_Implicit("isUnlocked")); CurrentTimeLeftSeconds = ((JToken)val).Value<float>(Object.op_Implicit("CurrentTimeLeftSeconds")); CurrentLaunderAmount = ((JToken)val).Value<float>(Object.op_Implicit("CurrentLaunderAmount")); LaundererTier = (LaundererTier)Enum.Parse(typeof(LaundererTier), ((JToken)val).Value<string>(Object.op_Implicit("Tier"))); WeekLaunderReturn = ((JToken)val).Value<float>(Object.op_Implicit("WeekLaunderReturn")); WeekCutAmount = ((JToken)val).Value<float>(Object.op_Implicit("WeekCutAmount")); InstanceMaxLaunderAmount = ((JToken)val).Value<float>(Object.op_Implicit("InstanceMaxLaunderAmount")); RequiredProductID = ((JToken)val).Value<string>(Object.op_Implicit("RequiredProductID")); return this; } } public enum LaundererTier { Low, Medium, High, Highest } public static class Launderers { public static Dictionary<string, LaundererTier> TierOf = new Dictionary<string, LaundererTier> { { "Donna", LaundererTier.Low }, { "Dean", LaundererTier.Low }, { "Jeff", LaundererTier.Medium }, { "Marco", LaundererTier.Medium }, { "Jeremy", LaundererTier.High }, { "Fiona", LaundererTier.High }, { "Ray", LaundererTier.Highest }, { "Herbert", LaundererTier.Highest } }; public static Dictionary<LaundererTier, float[]> LaunderAmountRanges = new Dictionary<LaundererTier, float[]> { { LaundererTier.Low, new float[2] { 1000f, 3500f } }, { LaundererTier.Medium, new float[2] { 5500f, 7500f } }, { LaundererTier.High, new float[2] { 9500f, 11000f } }, { LaundererTier.Highest, new float[2] { 11500f, 13500f } } }; } } namespace NPCLaunderers.Patches { [HarmonyPatch(typeof(NPC))] internal class NPCPatch { [HarmonyPostfix] [HarmonyPatch("Start")] public static void AddComponent(NPC __instance) { if (Launderers.TierOf.ContainsKey(__instance.FirstName)) { ((Component)__instance).gameObject.AddComponent<Launderer>(); } } } } namespace NPCLaunderers.NPCScripts { public class Launderer : MonoBehaviour { [CompilerGenerated] private sealed class <>c__DisplayClass21_0 { public Launderer <>4__this; public Contract contract; internal void <AddContractListener>b__0(EQuestState result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected I4, but got Unknown //IL_02fd: Unknown result type (might be due to invalid IL or missing references) switch (result - 2) { case 2: { double num2 = Mathf.Floor((float)Random.Range(1, 10)); string text; if (<>4__this.laundererData.CutPercentage >= 60.0) { text = "."; <>4__this.nPC.SendTextMessage(text); break; } while (<>4__this.laundererData.CutPercentage + num2 > 60.0) { num2 = Mathf.Floor((float)Random.Range(1, 10)); } <>4__this.laundererData.CutPercentage += num2; <>4__this.laundererData.RequiredProductID = ""; text = $"Ignoring me huh. I'm increasing my cut to <color=#ff6b6b>{<>4__this.laundererData.CutPercentage}%</color>"; <>4__this.nPC.SendTextMessage(text); break; } case 1: { double num2 = Mathf.Floor((float)Random.Range(1, 5)); string text; if (<>4__this.laundererData.CutPercentage >= 60.0) { text = "Sometimes, I don't feel like working with you at all."; <>4__this.nPC.SendTextMessage(text); break; } while (<>4__this.laundererData.CutPercentage + num2 > 60.0) { num2 = Mathf.Floor((float)Random.Range(1, 10)); } <>4__this.laundererData.CutPercentage += num2; <>4__this.laundererData.RequiredProductID = ""; text = $"I don't like the way you acted earlier. I'm increasing my cut to <color=#ff6b6b>{<>4__this.laundererData.CutPercentage}%</color>"; <>4__this.nPC.SendTextMessage(text); break; } case 0: { double num = Mathf.Floor((float)Random.Range(1, 10)); string text; if (<>4__this.laundererData.CutPercentage == 5.0) { text = "Thanks!"; <>4__this.nPC.SendTextMessage(text); break; } while (<>4__this.laundererData.CutPercentage - num < 5.0) { num = Mathf.Floor((float)Random.Range(1, 10)); } <>4__this.laundererData.CutPercentage -= num; <>4__this.laundererData.RequiredProductID = ""; text = $"Hey, I appreciate you bringing me the goods. I'll reduce my cut to <color=#ff6b6b>{<>4__this.laundererData.CutPercentage}%</color>."; <>4__this.nPC.SendTextMessage(text); break; } default: MelonLogger.Msg((object)result); break; } <>4__this.laundererData.RequiredProductID = ""; ((UnityEventBase)((Quest)contract).onQuestEnd).RemoveAllListeners(); <>4__this.withContract = false; } } [CompilerGenerated] private sealed class <AddContractListener>d__21 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Launderer <>4__this; public Contract contract; private <>c__DisplayClass21_0 <>8__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <AddContractListener>d__21(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown int num = <>1__state; Launderer launderer = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass21_0(); <>8__1.<>4__this = <>4__this; <>8__1.contract = contract; <>2__current = (object)new WaitForSecondsRealtime(3f); <>1__state = 1; return true; case 1: { <>1__state = -1; if (launderer.withContract) { return false; } _ = "Deal for " + launderer.nPC.FirstName; Action<EQuestState> action = delegate(EQuestState result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected I4, but got Unknown //IL_02fd: Unknown result type (might be due to invalid IL or missing references) switch (result - 2) { case 2: { double num3 = Mathf.Floor((float)Random.Range(1, 10)); if (<>8__1.<>4__this.laundererData.CutPercentage >= 60.0) { string text = "."; <>8__1.<>4__this.nPC.SendTextMessage(text); } else { while (<>8__1.<>4__this.laundererData.CutPercentage + num3 > 60.0) { num3 = Mathf.Floor((float)Random.Range(1, 10)); } <>8__1.<>4__this.laundererData.CutPercentage += num3; <>8__1.<>4__this.laundererData.RequiredProductID = ""; string text = $"Ignoring me huh. I'm increasing my cut to <color=#ff6b6b>{<>8__1.<>4__this.laundererData.CutPercentage}%</color>"; <>8__1.<>4__this.nPC.SendTextMessage(text); } break; } case 1: { double num3 = Mathf.Floor((float)Random.Range(1, 5)); if (<>8__1.<>4__this.laundererData.CutPercentage >= 60.0) { string text = "Sometimes, I don't feel like working with you at all."; <>8__1.<>4__this.nPC.SendTextMessage(text); } else { while (<>8__1.<>4__this.laundererData.CutPercentage + num3 > 60.0) { num3 = Mathf.Floor((float)Random.Range(1, 10)); } <>8__1.<>4__this.laundererData.CutPercentage += num3; <>8__1.<>4__this.laundererData.RequiredProductID = ""; string text = $"I don't like the way you acted earlier. I'm increasing my cut to <color=#ff6b6b>{<>8__1.<>4__this.laundererData.CutPercentage}%</color>"; <>8__1.<>4__this.nPC.SendTextMessage(text); } break; } case 0: { double num2 = Mathf.Floor((float)Random.Range(1, 10)); if (<>8__1.<>4__this.laundererData.CutPercentage == 5.0) { string text = "Thanks!"; <>8__1.<>4__this.nPC.SendTextMessage(text); } else { while (<>8__1.<>4__this.laundererData.CutPercentage - num2 < 5.0) { num2 = Mathf.Floor((float)Random.Range(1, 10)); } <>8__1.<>4__this.laundererData.CutPercentage -= num2; <>8__1.<>4__this.laundererData.RequiredProductID = ""; string text = $"Hey, I appreciate you bringing me the goods. I'll reduce my cut to <color=#ff6b6b>{<>8__1.<>4__this.laundererData.CutPercentage}%</color>."; <>8__1.<>4__this.nPC.SendTextMessage(text); } break; } default: MelonLogger.Msg((object)result); break; } <>8__1.<>4__this.laundererData.RequiredProductID = ""; ((UnityEventBase)((Quest)<>8__1.contract).onQuestEnd).RemoveAllListeners(); <>8__1.<>4__this.withContract = false; }; ((Quest)<>8__1.contract).onQuestEnd.AddListener(UnityAction<EQuestState>.op_Implicit(action)); launderer.withContract = true; QuestHUDUI hudUI = ((Quest)<>8__1.contract).hudUI; if (!((TMP_Text)hudUI.MainLabel).text.Contains("EVENT")) { ((TMP_Text)hudUI.MainLabel).text = "<color=#16F01C>[EVENT]</color> " + ((TMP_Text)hudUI.MainLabel).text; } MelonLogger.Msg(launderer.nPC.FirstName + ": Added active contract listner"); 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 <StartDialougeCheck>d__26 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Launderer <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <StartDialougeCheck>d__26(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown int num = <>1__state; Launderer launderer = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; Debug.Log(Object.op_Implicit($"{launderer.nPC.FirstName} - Unlocked: {launderer.laundererData.isUnlocked}, Init Ready: {launderer.isDialogueInitReady}, Is Friendly: {launderer.isFriendly}, Main Ready: {launderer.isMainDialogueReady}")); launderer.isCheckingDialouge = true; <>2__current = (object)new WaitForSecondsRealtime(1f); <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)launderer.dialogueController == (Object)null) { launderer.dialogueController = ((Component)launderer.nPC.dialogueHandler).GetComponent<DialogueController>(); } if (!launderer.laundererData.isUnlocked && !launderer.isDialogueInitReady && launderer.isFriendly) { launderer.nPC.SendTextMessage("Hey, Let me know if you need a partnership."); launderer.upfrontInstance = Mathf.Floor(Random.Range(launderer.laundererData.MinLaunderAmount, launderer.laundererData.MaxLaunderAmount)); launderer.AddInitChoice(); } if (launderer.laundererData.isUnlocked && !launderer.isMainDialogueReady && launderer.isFriendly) { Debug.Log(Object.op_Implicit("Setting up launder")); launderer.SetupLaunderDialog(); Debug.Log(Object.op_Implicit("DONE????")); } launderer.isCheckingDialouge = false; 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 <StartLaundryCheck>d__25 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Launderer <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <StartLaundryCheck>d__25(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown int num = <>1__state; Launderer launderer = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; launderer.isCheckingLaundry = true; <>2__current = (object)new WaitForSecondsRealtime(1f); <>1__state = 1; return true; case 1: <>1__state = -1; if (launderer.laundererData.isUnlocked && launderer.laundererData.CurrentLaunderAmount > 0f) { if (launderer.laundererData.CurrentTimeLeftSeconds > 0f) { launderer.laundererData.CurrentTimeLeftSeconds -= 1f; launderer.isCheckingLaundry = false; return false; } launderer.GiveLaunderedPay(); } launderer.isCheckingLaundry = false; 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 <StartSavedLaundryCheck>d__27 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Launderer <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <StartSavedLaundryCheck>d__27(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown int num = <>1__state; Launderer launderer = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; launderer.isCheckingSavedLaundry = true; <>2__current = (object)new WaitForSecondsRealtime(3f); <>1__state = 1; return true; case 1: { <>1__state = -1; bool entryValue = MelonPreferences.GetEntryValue<bool>("NPCLaunderers", "EnableCutDecreaseEvent"); if (launderer.laundererData.isUnlocked && launderer.laundererData.RequiredProductID != "" && !launderer.withContract && entryValue) { launderer.LoadLaundererData(); } launderer.isCheckingSavedLaundry = false; 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 <UpdateFriendlyState>d__28 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Launderer <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <UpdateFriendlyState>d__28(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown int num = <>1__state; Launderer launderer = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; launderer.isUpdatingFriendly = true; <>2__current = (object)new WaitForSecondsRealtime(5f); <>1__state = 1; return true; case 1: <>1__state = -1; launderer.isFriendly = launderer.nPC.RelationData.RelationDelta >= 4f; launderer.isUpdatingFriendly = false; 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 LaundererData laundererData; public bool isMainDialogueReady; public bool isDialogueInitReady; public NPC nPC; public DialogueController dialogueController; private LaundererUI laundererUI; private float upfrontInstance; public bool withContract; private bool isCheckingLaundry; private bool isCheckingDialouge; private bool isCheckingSavedLaundry; private bool isUpdatingFriendly; private bool isFriendly; public Launderer(IntPtr pointer) : base(pointer) { } public void Awake() { NPC component = ((Component)this).GetComponent<NPC>(); if ((Object)(object)component == (Object)null) { MelonLogger.Error("Launderer component is not attached to an NPC."); return; } laundererData = new LaundererData(component).Load(); nPC = component; } private void AddInitChoice() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown DialogueChoice newChoice = new DialogueChoice { Enabled = true, ChoiceText = "How about a partnership?" }; DialogueNodeData val = NPCUtilities.CreateDialogueInitNodeData(laundererData.MinLaunderAmount, laundererData.MaxLaunderAmount, laundererData.CutPercentage, upfrontInstance, this); List<DialogueNodeData> val2 = new List<DialogueNodeData>(); val2.Add(val); newChoice.Conversation = new DialogueContainer { DialogueNodeData = val2, name = "LAUNDER_INIT_CONTAINER" }; newChoice.onChoosen.AddListener(UnityAction.op_Implicit((Action)delegate { nPC.dialogueHandler.InitializeDialogue(newChoice.Conversation, true, "LAUNDER_INIT_NODE"); nPC.dialogueHandler.onDialogueChoiceChosen.AddListener(UnityAction<string>.op_Implicit((Action<string>)delegate(string label) { if (label == "ACCEPT_LAUNDER_TERMS") { laundererData.isUnlocked = true; dialogueController.Choices.Remove(newChoice); laundererData.CutPercentage = 10.0; SendInitialMessage(); } })); })); dialogueController.AddDialogueChoice(newChoice, 0); isDialogueInitReady = true; } private void SendInitialMessage() { if (!((Object)(object)nPC == (Object)null) && !((Object)(object)dialogueController == (Object)null) && laundererData.isUnlocked) { string text = $"I can help you launder your money. I'll take a cut of <color=#ff6b6b>{laundererData.CutPercentage}%</color> of the amount for this week."; nPC.SendTextMessage(text); SetupLaunderDialog(); } } private void SetupLaunderDialog() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown if ((Object)(object)nPC == (Object)null || (Object)(object)dialogueController == (Object)null || !laundererData.isUnlocked) { return; } if (laundererUI == null) { laundererUI = new LaundererUI(this); } DialogueChoice val = new DialogueChoice { Enabled = true, ChoiceText = "Launder Dirties" }; val.onChoosen.AddListener(UnityAction.op_Implicit((Action)delegate { if (laundererData.CurrentLaunderAmount > 0f || laundererData.CurrentTimeLeftSeconds > 0f) { Singleton<NotificationsManager>.Instance.SendNotification(nPC.fullName, $"Laundering <color=#16F01C>${laundererData.CurrentLaunderAmount}</color>", nPC.MugshotSprite, 5f, true); } else { laundererData.InstanceMaxLaunderAmount = Mathf.Floor(Random.Range(laundererData.MinLaunderAmount, laundererData.MaxLaunderAmount)); laundererUI.Open(); } })); dialogueController.AddDialogueChoice(val, 0); isMainDialogueReady = true; } public void GiveLaunderedPay() { if (!((Object)(object)nPC == (Object)null) && !((Object)(object)dialogueController == (Object)null) && laundererData.isUnlocked) { NetworkSingleton<MoneyManager>.Instance.CreateOnlineTransaction($"Launderer_${nPC.FirstName}_${laundererData.CurrentLaunderAmount}_${laundererData.CutPercentage}", laundererData.ReturnLaunderAmount, 1f, ""); string text = $"Hey, I sent <color=#2e75d9>${laundererData.ReturnLaunderAmount}</color> to your bank. \n\nMy Cut: <color=#eb4034>${laundererData.CutAmount}</color>"; nPC.SendTextMessage(text); Singleton<NotificationsManager>.Instance.SendNotification(nPC.fullName, $"<color=#16F01C>${laundererData.CurrentLaunderAmount}</color> Laundered", nPC.MugshotSprite, 5f, true); laundererData.WeekLaunderReturn += laundererData.ReturnLaunderAmount; laundererData.WeekCutAmount += laundererData.CutAmount; laundererData.CurrentLaunderAmount = 0f; laundererData.CurrentTimeLeftSeconds = 0f; laundererData.InstanceMaxLaunderAmount = 0f; } } public void RandomizeCut() { if ((Object)(object)nPC == (Object)null || (Object)(object)dialogueController == (Object)null || !laundererData.isUnlocked) { return; } double num = Random.Range(0f, 100f); if (laundererData.WeekLaunderReturn - laundererData.WeekCutAmount > Mathf.Floor(Random.Range(laundererData.MinLaunderAmount, laundererData.MaxLaunderAmount)) && num < 30.0 && laundererData.CutPercentage <= 30.0) { double num2 = Mathf.Floor((float)Random.Range(1, 10)); while (laundererData.CutPercentage + num2 > 60.0) { num2 = Mathf.Floor((float)Random.Range(1, 10)); } laundererData.CutPercentage += num2; string text = $"Hey, You seem to be doing so well. To make things fair, I'm changing my cut to <color=#ff6b6b>{laundererData.CutPercentage}%</color>."; nPC.SendTextMessage(text); } } public void RequireMix(string productId = null) { //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Invalid comparison between Unknown and I4 //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Expected O, but got Unknown //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0174: 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) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Expected O, but got Unknown //IL_01a3: Expected O, but got Unknown //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Expected O, but got Unknown //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)nPC == (Object)null || (Object)(object)dialogueController == (Object)null || !laundererData.isUnlocked) { return; } ProductDefinition val; if (productId == null) { int num = Random.Range(0, ProductManager.DiscoveredProducts.Count - 1); val = ProductManager.DiscoveredProducts[num]; } else { val = ((IEnumerable<ProductDefinition>)ProductManager.DiscoveredProducts._items).FirstOrDefault((Func<ProductDefinition, bool>)((ProductDefinition p) => ((ItemDefinition)p).ID == productId)); if ((Object)(object)val == (Object)null) { MelonLogger.Error("Product with ID " + productId + " not found."); Singleton<NotificationsManager>.Instance.SendNotification(nPC.fullName, "<color=#f54c4c>Product not found. Launderers Mod disabled</color>", nPC.MugshotSprite, 5f, true); MelonBase.FindMelon("NPCLaunderers", "weedeej").Unregister("Product not found. Launderers Mod disabled", false); return; } } laundererData.RequiredProductID = ((ItemDefinition)val).ID; List<Entry> val2 = new List<Entry>(); Entry val3 = new Entry { ProductID = ((ItemDefinition)val).ID, Quality = (EQuality)(((int)val.DrugType == 1) ? 3 : 4), Quantity = 3 }; val2.Add(val3); new ProductList().entries = val2; DeliveryLocation[] array = Il2CppArrayBase<DeliveryLocation>.op_Implicit(Object.FindObjectsOfType<DeliveryLocation>()); DeliveryLocation val4 = array[Random.Range(0, array.Length)]; ContractInfo val5 = new ContractInfo(0f, new ProductList { entries = val2 }, val4.StaticGUID, new QuestWindowConfig { WindowStartTime = 600, WindowEndTime = 1200, IsEnabled = true }, false, 1300, 0, false); NetworkSingleton<QuestManager>.Instance.CreateContract_Networked(Player.Local.Connection, Guid.NewGuid().ToString(), true, ((NetworkBehaviour)nPC).NetworkObject, val5, new GameDateTime(1300), NetworkSingleton<TimeManager>.Instance.GetDateTime(), (NetworkObject)null); string text = $"Hey, I wanna strengthen our partnership. How about we do a session.\n\nI need you to bring me <color=#6b9cff>3x {((ItemDefinition)val).Name}</color> in <b>BEST</b> quality you can get at <color=#6b9cff>6:00am to 12:00pm</color>.\nMeet me <color=#6b9cff>{val4.LocationDescription}</color>."; nPC.SendTextMessage(text); } [IteratorStateMachine(typeof(<AddContractListener>d__21))] private IEnumerator AddContractListener(Contract contract) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <AddContractListener>d__21(0) { <>4__this = this, contract = contract }; } public void WeekPass() { bool entryValue = MelonPreferences.GetEntryValue<bool>("NPCLaunderers", "EnableEnvy"); bool entryValue2 = MelonPreferences.GetEntryValue<bool>("NPCLaunderers", "EnableCutDecreaseEvent"); if (!((Object)(object)nPC == (Object)null) && !((Object)(object)dialogueController == (Object)null) && laundererData.isUnlocked) { if (entryValue) { RandomizeCut(); } if (Random.Range(0, 100) >= 60 && entryValue2) { RequireMix(); } } } public void OnDestroy() { laundererData = null; isMainDialogueReady = false; isDialogueInitReady = false; nPC = null; dialogueController = null; laundererUI = null; upfrontInstance = 0f; withContract = false; } private void Update() { if (!isCheckingLaundry) { MelonCoroutines.Start(StartLaundryCheck()); } if (!isCheckingDialouge) { MelonCoroutines.Start(StartDialougeCheck()); } if (!isCheckingSavedLaundry) { MelonCoroutines.Start(StartSavedLaundryCheck()); } if (!isUpdatingFriendly) { MelonCoroutines.Start(UpdateFriendlyState()); } } [IteratorStateMachine(typeof(<StartLaundryCheck>d__25))] private IEnumerator StartLaundryCheck() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <StartLaundryCheck>d__25(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<StartDialougeCheck>d__26))] private IEnumerator StartDialougeCheck() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <StartDialougeCheck>d__26(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<StartSavedLaundryCheck>d__27))] private IEnumerator StartSavedLaundryCheck() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <StartSavedLaundryCheck>d__27(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<UpdateFriendlyState>d__28))] private IEnumerator UpdateFriendlyState() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <UpdateFriendlyState>d__28(0) { <>4__this = this }; } private void LoadLaundererData() { if (laundererData != null && !(laundererData.RequiredProductID == "")) { Contract val = ((IEnumerable<Contract>)Object.FindObjectsOfType<Contract>()).FirstOrDefault((Contract c) => (int)((Quest)c).QuestState == 1 && ((Quest)c).GetQuestTitle().Contains(nPC.FirstName), null); if ((Object)(object)val != (Object)null && !withContract && ((IEnumerable<Entry>)val.ProductList.entries._items).Any((Entry e) => e.ProductID == laundererData.RequiredProductID)) { MelonCoroutines.Start(AddContractListener(val)); } if ((Object)(object)val == (Object)null && !withContract && laundererData.RequiredProductID != "") { RequireMix(laundererData.RequiredProductID); } } } } public static class NPCUtilities { public static DialogueNodeData CreateDialogueInitNodeData(float amount_min, float amount_max, double cut, float upfront, Launderer launderer) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown DialogueNodeData val = new DialogueNodeData(); val.DialogueNodeLabel = "LAUNDER_INIT_NODE"; val.DialogueText = $"Alright, I can wash around <color=#16F01C>${amount_min} - ${amount_max}</color> of your dirties. But there will be some cuts, of course. I'll let you know how much every week. But for now, Let us start with <color=#6b9cff>{cut}%</color> and an upfront of <color=#16F01C>${upfront}</color>"; DialogueChoiceData[] array = (DialogueChoiceData[])(object)new DialogueChoiceData[2] { new DialogueChoiceData { ChoiceLabel = "ACCEPT_LAUNDER_TERMS", ChoiceText = "Sure, Let's do it." }, new DialogueChoiceData { ChoiceLabel = "DECLINE_LAUNDER_TERMS", ChoiceText = "Nevermind" } }; val.choices = Il2CppReferenceArray<DialogueChoiceData>.op_Implicit(array); return val; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { internal IgnoresAccessChecksToAttribute(string assemblyName) { } } }
MONO/Mods/NPCLaunderers_MONO.dll
Decompiled 4 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using FishNet.Object; using HarmonyLib; using MelonLoader; using MelonLoader.Preferences; using MelonLoader.Utils; using Microsoft.CodeAnalysis; using NPCLaunderers; using NPCLaunderers.LaundererSaveManager; using NPCLaunderers.NPCScripts; using NPCLaunderers.UI; using Newtonsoft.Json.Linq; using ScheduleOne.DevUtilities; using ScheduleOne.Dialogue; using ScheduleOne.Economy; using ScheduleOne.GameTime; using ScheduleOne.ItemFramework; using ScheduleOne.Money; using ScheduleOne.NPCs; using ScheduleOne.Persistence; using ScheduleOne.PlayerScripts; using ScheduleOne.Product; using ScheduleOne.Quests; using ScheduleOne.UI; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UIElements; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(Core), "NPCLaunderers", "1.0.3", "weedeej", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("NPCLaunderers_MONO")] [assembly: AssemblyConfiguration("MONO")] [assembly: AssemblyFileVersion("1.0.3")] [assembly: AssemblyInformationalVersion("1.0.0+61985eb8d7b4c751f4ff59154fa080438265035e")] [assembly: AssemblyProduct("NPCLaunderers_MONO")] [assembly: AssemblyTitle("NPCLaunderers_MONO")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.3.0")] [module: UnverifiableCode] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace NPCLaunderers { public class Core : MelonMod { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__3_0; public static Action <>9__3_1; internal void <DelayedStart>b__3_0() { Launderer[] array = Object.FindObjectsOfType<Launderer>(); for (int i = 0; i < array.Length; i++) { array[i].laundererData.Save(); } } internal void <DelayedStart>b__3_1() { Launderer[] array = Object.FindObjectsOfType<Launderer>(); for (int i = 0; i < array.Length; i++) { array[i].WeekPass(); } } } [CompilerGenerated] private sealed class <DelayedStart>d__3 : 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 <DelayedStart>d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSecondsRealtime(5f); <>1__state = 1; return true; case 1: { <>1__state = -1; object obj = <>c.<>9__3_0; if (obj == null) { UnityAction val = delegate { Launderer[] array2 = Object.FindObjectsOfType<Launderer>(); for (int j = 0; j < array2.Length; j++) { array2[j].laundererData.Save(); } }; <>c.<>9__3_0 = val; obj = (object)val; } UnityAction val2 = (UnityAction)obj; Action b = delegate { Launderer[] array = Object.FindObjectsOfType<Launderer>(); for (int i = 0; i < array.Length; i++) { array[i].WeekPass(); } }; Singleton<SaveManager>.Instance.onSaveStart.AddListener(val2); TimeManager instance = NetworkSingleton<TimeManager>.Instance; instance.onWeekPass = (Action)Delegate.Combine(instance.onWeekPass, b); 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 AssetBundle bundle; public override void OnInitializeMelon() { MelonPreferences.CreateCategory("NPCLaunderers", "NPCLaunderers Settings"); MelonPreferences.CreateEntry<bool>("NPCLaunderers", "EnableEnvy", true, "Enable Envy", "Allows your launderers to get envy of what you earn and request more cut.", false, false, (ValueValidator)null); MelonPreferences.CreateEntry<bool>("NPCLaunderers", "EnableCutDecreaseEvent", true, "Enable Request Product", "Allows your launderers to request a product to reduce cut", false, false, (ValueValidator)null); MelonPreferences.Save(); try { Stream manifestResourceStream = ((MelonBase)this).MelonAssembly.Assembly.GetManifestResourceStream("NPCLaunderers.Assets.launderers.assetbundle"); if (manifestResourceStream == null) { ((MelonBase)this).Unregister("AssetBundle stream not found", false); return; } bundle = AssetBundle.LoadFromStream(manifestResourceStream); } catch (Exception arg) { ((MelonBase)this).Unregister($"Failed to load AssetBundle. Please report to dev: {arg}", false); return; } ((MelonBase)this).LoggerInstance.Msg("Initialized."); } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { ((MelonMod)this).OnSceneWasLoaded(buildIndex, sceneName); if (sceneName == "Main") { MelonCoroutines.Start(DelayedStart()); } } [IteratorStateMachine(typeof(<DelayedStart>d__3))] private IEnumerator DelayedStart() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedStart>d__3(0); } } } namespace NPCLaunderers.UI { public class LaundererUI { private bool isOpen; private Launderer launderer; public GameObject gameObject; private AssetBundle bundle; public LaundererUI(Launderer launderer) { this.launderer = launderer; List<AssetBundle> list = AssetBundle.GetAllLoadedAssetBundles().ToList(); if (list.Count == 1) { bundle = list[0]; return; } foreach (AssetBundle item in list) { if (((Object)item).name == "launderers.assetbundle") { bundle = item; break; } } } public void SetLaunderer(Launderer launderer) { this.launderer = launderer; } public void Open() { if (!isOpen) { Show(); isOpen = true; } } public void Close() { if (isOpen) { Hide(); isOpen = false; } } private void Show() { gameObject = bundle.LoadAsset<GameObject>("assets/laundererui.prefab"); gameObject = Object.Instantiate<GameObject>(gameObject); VisualElement val = UQueryExtensions.Q<VisualElement>(gameObject.GetComponent<UIDocument>().rootVisualElement, "LaundererContent", (string)null); ((TextElement)UQueryExtensions.Q<Label>(UQueryExtensions.Q<VisualElement>(val, "Header", (string)null), "Version", (string)null)).text = ((MelonBase)MelonAssembly.FindMelonInstance<Core>()).Info.Version; VisualElement obj = UQueryExtensions.Q<VisualElement>(val, "buttons", (string)null); Button val2 = UQueryExtensions.Q<Button>(obj, "btn_close", (string)null); Button obj2 = UQueryExtensions.Q<Button>(obj, "btn_submit", (string)null); IntegerField amountField = UQueryExtensions.Q<IntegerField>(val, "NumberInput", (string)null); Label obj3 = UQueryExtensions.Q<Label>((VisualElement)(object)amountField, "NpcName", (string)null); ((BaseField<int>)(object)amountField).label = ((BaseField<int>)(object)amountField).label.Replace("<MaxLaunder>", $"{launderer.laundererData.InstanceMaxLaunderAmount}"); ((TextElement)obj3).text = ((TextElement)obj3).text.Replace("<NPCNAME>", launderer.nPC.fullName); ((CallbackEventHandler)obj2).RegisterCallback<ClickEvent>((EventCallback<ClickEvent>)delegate { MoneyManager instance = NetworkSingleton<MoneyManager>.Instance; try { float num = ((BaseField<int>)(object)amountField).value; if (!(num < 1f)) { if (instance.cashBalance < num) { MelonLogger.Error($"Input value {num} exceeds cash balance {instance.cashBalance}"); Singleton<NotificationsManager>.Instance.SendNotification(launderer.nPC.FirstName, "<color=#f54c4c>You don't have enough money</color>", launderer.nPC.MugshotSprite, 5f, true); } else if (num > launderer.laundererData.InstanceMaxLaunderAmount) { MelonLogger.Error($"Input value {num} exceeds max launder amount {launderer.laundererData.InstanceMaxLaunderAmount}"); Singleton<NotificationsManager>.Instance.SendNotification(launderer.nPC.FirstName, $"<color=#f54c4c>Max of ${launderer.laundererData.InstanceMaxLaunderAmount}</color>", launderer.nPC.MugshotSprite, 5f, true); } else { instance.ChangeCashBalance(0f - num, true, true); launderer.laundererData.CurrentLaunderAmount = num; launderer.laundererData.CurrentTimeLeftSeconds = 720f; string text = $"Laundering <color=#16F01C>${num}</color>.I will transfer <color=#6b9cff>${launderer.laundererData.ReturnLaunderAmount}</color> to your account in 12 hours."; launderer.nPC.SendTextMessage(text); Close(); } } } catch (Exception ex) { MelonLogger.Error($"Failed to load LaundererUI: {ex}"); if (ex is FormatException) { Singleton<NotificationsManager>.Instance.SendNotification(launderer.nPC.FirstName, "<color=#f54c4c>Invalid input value</color>", launderer.nPC.MugshotSprite, 5f, true); } } }, (TrickleDown)0); ((CallbackEventHandler)val2).RegisterCallback<ClickEvent>((EventCallback<ClickEvent>)delegate { Close(); }, (TrickleDown)0); PlayerSingleton<PlayerCamera>.Instance.AddActiveUIElement(((Object)gameObject).name); Player.Deactivate(true); } private void Hide() { PlayerSingleton<PlayerCamera>.Instance.RemoveActiveUIElement(((Object)gameObject).name); Player.Activate(); Object.Destroy((Object)(object)gameObject); } } } namespace NPCLaunderers.LaundererSaveManager { [Serializable] public class LaundererData { public NPC NPC; public float MinLaunderAmount; public float MaxLaunderAmount; public LaundererTier LaundererTier; public double CutPercentage; public bool isUnlocked; public float CurrentTimeLeftSeconds; public float CurrentLaunderAmount; public float WeekLaunderReturn; public float WeekCutAmount; public string RequiredProductID; public float InstanceMaxLaunderAmount; private string SaveFilePath; public float ReturnLaunderAmount => Mathf.Floor(CurrentLaunderAmount - CurrentLaunderAmount * (float)(CutPercentage / 100.0)); public float CutAmount => Mathf.Floor(CurrentLaunderAmount * (float)(CutPercentage / 100.0)); public LaundererData(NPC nPC) { NPC = nPC; LaundererTier = Launderers.TierOf[nPC.FirstName]; float[] array = Launderers.LaunderAmountRanges[LaundererTier]; MinLaunderAmount = array[0]; MaxLaunderAmount = array[1]; WeekLaunderReturn = 0f; WeekCutAmount = 0f; CurrentLaunderAmount = 0f; CurrentTimeLeftSeconds = 0f; isUnlocked = false; InstanceMaxLaunderAmount = 0f; RequiredProductID = ""; CutPercentage = 10.0; string loadedGameFolderPath = Singleton<LoadManager>.Instance.LoadedGameFolderPath; int startIndex = loadedGameFolderPath.IndexOf("Saves\\") + 5; string[] array2 = loadedGameFolderPath.Substring(startIndex).Split(new char[1] { '\\' }, StringSplitOptions.RemoveEmptyEntries); SaveFilePath = Path.Combine(MelonEnvironment.UserDataDirectory, "Launderers", array2[0] + "_" + array2[1] + "_" + nPC.ID + ".json"); if (!Directory.Exists(Path.Combine(MelonEnvironment.UserDataDirectory, "Launderers"))) { Directory.CreateDirectory(Path.Combine(MelonEnvironment.UserDataDirectory, "Launderers")); } } public void Save() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Expected O, but got Unknown //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Expected O, but got Unknown //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Expected O, but got Unknown //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Expected O, but got Unknown //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown JObject val = new JObject(); ((JContainer)val).Add((object)new JProperty("FirstName", (object)NPC.FirstName)); ((JContainer)val).Add((object)new JProperty("LastName", (object)NPC.LastName)); ((JContainer)val).Add((object)new JProperty("ID", (object)NPC.ID)); ((JContainer)val).Add((object)new JProperty("Tier", (object)LaundererTier.ToString())); ((JContainer)val).Add((object)new JProperty("MinLaunderAmount", (object)MinLaunderAmount)); ((JContainer)val).Add((object)new JProperty("MaxLaunderAmount", (object)MaxLaunderAmount)); ((JContainer)val).Add((object)new JProperty("isUnlocked", (object)isUnlocked)); ((JContainer)val).Add((object)new JProperty("CutPercentage", (object)CutPercentage)); ((JContainer)val).Add((object)new JProperty("CurrentTimeLeftSeconds", (object)CurrentTimeLeftSeconds)); ((JContainer)val).Add((object)new JProperty("CurrentLaunderAmount", (object)CurrentLaunderAmount)); ((JContainer)val).Add((object)new JProperty("WeekLaunderReturn", (object)WeekLaunderReturn)); ((JContainer)val).Add((object)new JProperty("WeekCutAmount", (object)WeekCutAmount)); ((JContainer)val).Add((object)new JProperty("RequiredProductID", (object)RequiredProductID)); ((JContainer)val).Add((object)new JProperty("InstanceMaxLaunderAmount", (object)InstanceMaxLaunderAmount)); File.WriteAllText(SaveFilePath, ((object)val).ToString()); Debug.Log((object)(NPC.FirstName + " - Saved to: " + SaveFilePath)); } public LaundererData Load() { if (!File.Exists(SaveFilePath)) { return this; } JObject val = JObject.Parse(File.ReadAllText(SaveFilePath)); MinLaunderAmount = ((JToken)val).Value<float>((object)"MinLaunderAmount"); MaxLaunderAmount = ((JToken)val).Value<float>((object)"MaxLaunderAmount"); CutPercentage = ((JToken)val).Value<double>((object)"CutPercentage"); isUnlocked = ((JToken)val).Value<bool>((object)"isUnlocked"); CurrentTimeLeftSeconds = ((JToken)val).Value<float>((object)"CurrentTimeLeftSeconds"); CurrentLaunderAmount = ((JToken)val).Value<float>((object)"CurrentLaunderAmount"); LaundererTier = (LaundererTier)Enum.Parse(typeof(LaundererTier), ((JToken)val).Value<string>((object)"Tier")); WeekLaunderReturn = ((JToken)val).Value<float>((object)"WeekLaunderReturn"); WeekCutAmount = ((JToken)val).Value<float>((object)"WeekCutAmount"); InstanceMaxLaunderAmount = ((JToken)val).Value<float>((object)"InstanceMaxLaunderAmount"); RequiredProductID = ((JToken)val).Value<string>((object)"RequiredProductID"); return this; } } public enum LaundererTier { Low, Medium, High, Highest } public static class Launderers { public static Dictionary<string, LaundererTier> TierOf = new Dictionary<string, LaundererTier> { { "Donna", LaundererTier.Low }, { "Dean", LaundererTier.Low }, { "Jeff", LaundererTier.Medium }, { "Marco", LaundererTier.Medium }, { "Jeremy", LaundererTier.High }, { "Fiona", LaundererTier.High }, { "Ray", LaundererTier.Highest }, { "Herbert", LaundererTier.Highest } }; public static Dictionary<LaundererTier, float[]> LaunderAmountRanges = new Dictionary<LaundererTier, float[]> { { LaundererTier.Low, new float[2] { 1000f, 3500f } }, { LaundererTier.Medium, new float[2] { 5500f, 7500f } }, { LaundererTier.High, new float[2] { 9500f, 11000f } }, { LaundererTier.Highest, new float[2] { 11500f, 13500f } } }; } } namespace NPCLaunderers.Patches { [HarmonyPatch(typeof(NPC))] internal class NPCPatch { [HarmonyPostfix] [HarmonyPatch("Start")] public static void AddComponent(NPC __instance) { if (Launderers.TierOf.ContainsKey(__instance.FirstName)) { ((Component)__instance).gameObject.AddComponent<Launderer>(); } } } } namespace NPCLaunderers.NPCScripts { public class Launderer : MonoBehaviour { [CompilerGenerated] private sealed class <>c__DisplayClass20_0 { public Launderer <>4__this; public Contract contract; internal void <AddContractListener>b__0(EQuestState result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected I4, but got Unknown //IL_029a: Unknown result type (might be due to invalid IL or missing references) switch (result - 2) { case 2: { double num2 = Mathf.Floor((float)Random.Range(1, 10)); string text; if (<>4__this.laundererData.CutPercentage >= 60.0) { text = "."; <>4__this.nPC.SendTextMessage(text); break; } while (<>4__this.laundererData.CutPercentage + num2 > 60.0) { num2 = Mathf.Floor((float)Random.Range(1, 10)); } <>4__this.laundererData.CutPercentage += num2; <>4__this.laundererData.RequiredProductID = ""; text = $"Ignoring me huh. I'm increasing my cut to <color=#ff6b6b>{<>4__this.laundererData.CutPercentage}%</color>"; <>4__this.nPC.SendTextMessage(text); break; } case 1: { double num2 = Mathf.Floor((float)Random.Range(1, 5)); string text; if (<>4__this.laundererData.CutPercentage >= 60.0) { text = "Sometimes, I don't feel like working with you at all."; <>4__this.nPC.SendTextMessage(text); break; } while (<>4__this.laundererData.CutPercentage + num2 > 60.0) { num2 = Mathf.Floor((float)Random.Range(1, 10)); } <>4__this.laundererData.CutPercentage += num2; <>4__this.laundererData.RequiredProductID = ""; text = $"I don't like the way you acted earlier. I'm increasing my cut to <color=#ff6b6b>{<>4__this.laundererData.CutPercentage}%</color>"; <>4__this.nPC.SendTextMessage(text); break; } case 0: { double num = Mathf.Floor((float)Random.Range(1, 10)); string text; if (<>4__this.laundererData.CutPercentage == 5.0) { text = "Thanks!"; <>4__this.nPC.SendTextMessage(text); break; } while (<>4__this.laundererData.CutPercentage - num < 5.0) { num = Mathf.Floor((float)Random.Range(1, 10)); } <>4__this.laundererData.CutPercentage -= num; <>4__this.laundererData.RequiredProductID = ""; text = $"Hey, I appreciate you bringing me the goods. I'll reduce my cut to <color=#ff6b6b>{<>4__this.laundererData.CutPercentage}%</color>."; <>4__this.nPC.SendTextMessage(text); break; } default: MelonLogger.Msg((object)result); break; } <>4__this.laundererData.RequiredProductID = ""; ((UnityEventBase)((Quest)contract).onQuestEnd).RemoveAllListeners(); <>4__this.withContract = false; } } [CompilerGenerated] private sealed class <AddContractListener>d__20 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Launderer <>4__this; public Contract contract; private <>c__DisplayClass20_0 <>8__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <AddContractListener>d__20(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown int num = <>1__state; Launderer launderer = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass20_0(); <>8__1.<>4__this = <>4__this; <>8__1.contract = contract; <>2__current = (object)new WaitForSecondsRealtime(3f); <>1__state = 1; return true; case 1: { <>1__state = -1; if (launderer.withContract) { return false; } _ = "Deal for " + launderer.nPC.FirstName; UnityAction<EQuestState> val = delegate(EQuestState result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected I4, but got Unknown //IL_029a: Unknown result type (might be due to invalid IL or missing references) switch (result - 2) { case 2: { double num3 = Mathf.Floor((float)Random.Range(1, 10)); if (<>8__1.<>4__this.laundererData.CutPercentage >= 60.0) { string text = "."; <>8__1.<>4__this.nPC.SendTextMessage(text); } else { while (<>8__1.<>4__this.laundererData.CutPercentage + num3 > 60.0) { num3 = Mathf.Floor((float)Random.Range(1, 10)); } <>8__1.<>4__this.laundererData.CutPercentage += num3; <>8__1.<>4__this.laundererData.RequiredProductID = ""; string text = $"Ignoring me huh. I'm increasing my cut to <color=#ff6b6b>{<>8__1.<>4__this.laundererData.CutPercentage}%</color>"; <>8__1.<>4__this.nPC.SendTextMessage(text); } break; } case 1: { double num3 = Mathf.Floor((float)Random.Range(1, 5)); if (<>8__1.<>4__this.laundererData.CutPercentage >= 60.0) { string text = "Sometimes, I don't feel like working with you at all."; <>8__1.<>4__this.nPC.SendTextMessage(text); } else { while (<>8__1.<>4__this.laundererData.CutPercentage + num3 > 60.0) { num3 = Mathf.Floor((float)Random.Range(1, 10)); } <>8__1.<>4__this.laundererData.CutPercentage += num3; <>8__1.<>4__this.laundererData.RequiredProductID = ""; string text = $"I don't like the way you acted earlier. I'm increasing my cut to <color=#ff6b6b>{<>8__1.<>4__this.laundererData.CutPercentage}%</color>"; <>8__1.<>4__this.nPC.SendTextMessage(text); } break; } case 0: { double num2 = Mathf.Floor((float)Random.Range(1, 10)); if (<>8__1.<>4__this.laundererData.CutPercentage == 5.0) { string text = "Thanks!"; <>8__1.<>4__this.nPC.SendTextMessage(text); } else { while (<>8__1.<>4__this.laundererData.CutPercentage - num2 < 5.0) { num2 = Mathf.Floor((float)Random.Range(1, 10)); } <>8__1.<>4__this.laundererData.CutPercentage -= num2; <>8__1.<>4__this.laundererData.RequiredProductID = ""; string text = $"Hey, I appreciate you bringing me the goods. I'll reduce my cut to <color=#ff6b6b>{<>8__1.<>4__this.laundererData.CutPercentage}%</color>."; <>8__1.<>4__this.nPC.SendTextMessage(text); } break; } default: MelonLogger.Msg((object)result); break; } <>8__1.<>4__this.laundererData.RequiredProductID = ""; ((UnityEventBase)((Quest)<>8__1.contract).onQuestEnd).RemoveAllListeners(); <>8__1.<>4__this.withContract = false; }; ((Quest)<>8__1.contract).onQuestEnd.AddListener(val); launderer.withContract = true; QuestHUDUI hudUI = ((Quest)<>8__1.contract).hudUI; if (!((TMP_Text)hudUI.MainLabel).text.Contains("EVENT")) { ((TMP_Text)hudUI.MainLabel).text = "<color=#16F01C>[EVENT]</color> " + ((TMP_Text)hudUI.MainLabel).text; } MelonLogger.Msg(launderer.nPC.FirstName + ": Added active contract listner"); 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 <StartDialougeCheck>d__25 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Launderer <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <StartDialougeCheck>d__25(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown int num = <>1__state; Launderer launderer = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; Debug.Log((object)$"{launderer.nPC.FirstName} - Unlocked: {launderer.laundererData.isUnlocked}, Init Ready: {launderer.isDialogueInitReady}, Is Friendly: {launderer.isFriendly}, Main Ready: {launderer.isMainDialogueReady}"); launderer.isCheckingDialouge = true; <>2__current = (object)new WaitForSecondsRealtime(1f); <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)launderer.dialogueController == (Object)null) { launderer.dialogueController = ((Component)launderer.nPC.dialogueHandler).GetComponent<DialogueController>(); } if (!launderer.laundererData.isUnlocked && !launderer.isDialogueInitReady && launderer.isFriendly) { launderer.nPC.SendTextMessage("Hey, Let me know if you need a partnership."); launderer.upfrontInstance = Mathf.Floor(Random.Range(launderer.laundererData.MinLaunderAmount, launderer.laundererData.MaxLaunderAmount)); launderer.AddInitChoice(); } if (launderer.laundererData.isUnlocked && !launderer.isMainDialogueReady && launderer.isFriendly) { Debug.Log((object)"Setting up launder"); launderer.SetupLaunderDialog(); Debug.Log((object)"DONE????"); } launderer.isCheckingDialouge = false; 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 <StartLaundryCheck>d__24 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Launderer <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <StartLaundryCheck>d__24(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown int num = <>1__state; Launderer launderer = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; launderer.isCheckingLaundry = true; <>2__current = (object)new WaitForSecondsRealtime(1f); <>1__state = 1; return true; case 1: <>1__state = -1; if (launderer.laundererData.isUnlocked && launderer.laundererData.CurrentLaunderAmount > 0f) { if (launderer.laundererData.CurrentTimeLeftSeconds > 0f) { launderer.laundererData.CurrentTimeLeftSeconds -= 1f; launderer.isCheckingLaundry = false; return false; } launderer.GiveLaunderedPay(); } launderer.isCheckingLaundry = false; 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 <StartSavedLaundryCheck>d__26 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Launderer <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <StartSavedLaundryCheck>d__26(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown int num = <>1__state; Launderer launderer = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; launderer.isCheckingSavedLaundry = true; <>2__current = (object)new WaitForSecondsRealtime(3f); <>1__state = 1; return true; case 1: { <>1__state = -1; bool entryValue = MelonPreferences.GetEntryValue<bool>("NPCLaunderers", "EnableCutDecreaseEvent"); if (launderer.laundererData.isUnlocked && launderer.laundererData.RequiredProductID != "" && !launderer.withContract && entryValue) { launderer.LoadLaundererData(); } launderer.isCheckingSavedLaundry = false; 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 <UpdateFriendlyState>d__27 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Launderer <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <UpdateFriendlyState>d__27(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown int num = <>1__state; Launderer launderer = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; launderer.isUpdatingFriendly = true; <>2__current = (object)new WaitForSecondsRealtime(5f); <>1__state = 1; return true; case 1: <>1__state = -1; launderer.isFriendly = launderer.nPC.RelationData.RelationDelta >= 4f; launderer.isUpdatingFriendly = false; 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 LaundererData laundererData; public bool isMainDialogueReady; public bool isDialogueInitReady; public NPC nPC; public DialogueController dialogueController; private LaundererUI laundererUI; private float upfrontInstance; public bool withContract; private bool isCheckingLaundry; private bool isCheckingDialouge; private bool isCheckingSavedLaundry; private bool isUpdatingFriendly; private bool isFriendly; public void Awake() { NPC component = ((Component)this).GetComponent<NPC>(); if ((Object)(object)component == (Object)null) { MelonLogger.Error("Launderer component is not attached to an NPC."); return; } laundererData = new LaundererData(component).Load(); nPC = component; } private void AddInitChoice() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown DialogueChoice newChoice = new DialogueChoice { Enabled = true, ChoiceText = "How about a partnership?" }; DialogueNodeData item = NPCUtilities.CreateDialogueInitNodeData(laundererData.MinLaunderAmount, laundererData.MaxLaunderAmount, laundererData.CutPercentage, upfrontInstance, this); List<DialogueNodeData> list = new List<DialogueNodeData>(); list.Add(item); newChoice.Conversation = new DialogueContainer { DialogueNodeData = list, name = "LAUNDER_INIT_CONTAINER" }; newChoice.onChoosen.AddListener((UnityAction)delegate { nPC.dialogueHandler.InitializeDialogue(newChoice.Conversation, true, "LAUNDER_INIT_NODE"); nPC.dialogueHandler.onDialogueChoiceChosen.AddListener((UnityAction<string>)delegate(string label) { if (label == "ACCEPT_LAUNDER_TERMS") { NetworkSingleton<MoneyManager>.Instance.ChangeCashBalance(0f - upfrontInstance, true, true); laundererData.isUnlocked = true; dialogueController.Choices.Remove(newChoice); laundererData.CutPercentage = 10.0; SendInitialMessage(); } }); }); dialogueController.AddDialogueChoice(newChoice, 0); isDialogueInitReady = true; } private void SendInitialMessage() { if (!((Object)(object)nPC == (Object)null) && !((Object)(object)dialogueController == (Object)null) && laundererData.isUnlocked) { string text = $"I can help you launder your money. I'll take a cut of <color=#ff6b6b>{laundererData.CutPercentage}%</color> of the amount for this week."; nPC.SendTextMessage(text); SetupLaunderDialog(); } } private void SetupLaunderDialog() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown if ((Object)(object)nPC == (Object)null || (Object)(object)dialogueController == (Object)null || !laundererData.isUnlocked) { return; } if (laundererUI == null) { laundererUI = new LaundererUI(this); } DialogueChoice val = new DialogueChoice { Enabled = true, ChoiceText = "Launder Dirties" }; val.onChoosen.AddListener((UnityAction)delegate { if (laundererData.CurrentLaunderAmount > 0f || laundererData.CurrentTimeLeftSeconds > 0f) { Singleton<NotificationsManager>.Instance.SendNotification(nPC.fullName, $"Laundering <color=#16F01C>${laundererData.CurrentLaunderAmount}</color>", nPC.MugshotSprite, 5f, true); } else { laundererData.InstanceMaxLaunderAmount = Mathf.Floor(Random.Range(laundererData.MinLaunderAmount, laundererData.MaxLaunderAmount)); laundererUI.Open(); } }); dialogueController.AddDialogueChoice(val, 0); isMainDialogueReady = true; } public void GiveLaunderedPay() { if (!((Object)(object)nPC == (Object)null) && !((Object)(object)dialogueController == (Object)null) && laundererData.isUnlocked) { NetworkSingleton<MoneyManager>.Instance.CreateOnlineTransaction($"Launderer_${nPC.FirstName}_${laundererData.CurrentLaunderAmount}_${laundererData.CutPercentage}", laundererData.ReturnLaunderAmount, 1f, ""); string text = $"Hey, I sent <color=#2e75d9>${laundererData.ReturnLaunderAmount}</color> to your bank. \n\nMy Cut: <color=#eb4034>${laundererData.CutAmount}</color>"; nPC.SendTextMessage(text); Singleton<NotificationsManager>.Instance.SendNotification(nPC.fullName, $"<color=#16F01C>${laundererData.CurrentLaunderAmount}</color> Laundered", nPC.MugshotSprite, 5f, true); laundererData.WeekLaunderReturn += laundererData.ReturnLaunderAmount; laundererData.WeekCutAmount += laundererData.CutAmount; laundererData.CurrentLaunderAmount = 0f; laundererData.CurrentTimeLeftSeconds = 0f; laundererData.InstanceMaxLaunderAmount = 0f; } } public void RandomizeCut() { if ((Object)(object)nPC == (Object)null || (Object)(object)dialogueController == (Object)null || !laundererData.isUnlocked) { return; } double num = Random.Range(0f, 100f); if (laundererData.WeekLaunderReturn - laundererData.WeekCutAmount > Mathf.Floor(Random.Range(laundererData.MinLaunderAmount, laundererData.MaxLaunderAmount)) && num < 30.0 && laundererData.CutPercentage <= 30.0) { double num2 = Mathf.Floor((float)Random.Range(1, 10)); while (laundererData.CutPercentage + num2 > 60.0) { num2 = Mathf.Floor((float)Random.Range(1, 10)); } laundererData.CutPercentage += num2; string text = $"Hey, You seem to be doing so well. To make things fair, I'm changing my cut to <color=#ff6b6b>{laundererData.CutPercentage}%</color>."; nPC.SendTextMessage(text); } } public void RequireMix(string productId = null) { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Invalid comparison between Unknown and I4 //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_016a: 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_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Expected O, but got Unknown //IL_0199: Expected O, but got Unknown //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Expected O, but got Unknown //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)nPC == (Object)null || (Object)(object)dialogueController == (Object)null || !laundererData.isUnlocked) { return; } ProductDefinition val; if (productId == null) { int index = Random.Range(0, ProductManager.DiscoveredProducts.Count - 1); val = ProductManager.DiscoveredProducts[index]; } else { val = ProductManager.DiscoveredProducts.Find((ProductDefinition p) => ((ItemDefinition)p).ID == productId); if ((Object)(object)val == (Object)null) { MelonLogger.Error("Product with ID " + productId + " not found."); Singleton<NotificationsManager>.Instance.SendNotification(nPC.fullName, "<color=#f54c4c>Product not found. Launderers Mod disabled</color>", nPC.MugshotSprite, 5f, true); MelonBase.FindMelon("NPCLaunderers", "weedeej").Unregister("Product not found. Launderers Mod disabled", false); return; } } laundererData.RequiredProductID = ((ItemDefinition)val).ID; List<Entry> list = new List<Entry>(); Entry item = new Entry { ProductID = ((ItemDefinition)val).ID, Quality = (EQuality)(((int)val.DrugType == 1) ? 3 : 4), Quantity = 3 }; list.Add(item); new ProductList().entries = list; DeliveryLocation[] array = Object.FindObjectsOfType<DeliveryLocation>(); DeliveryLocation val2 = array[Random.Range(0, array.Length)]; ContractInfo val3 = new ContractInfo(0f, new ProductList { entries = list }, val2.StaticGUID, new QuestWindowConfig { WindowStartTime = 600, WindowEndTime = 1200, IsEnabled = true }, false, 1300, 0, false); NetworkSingleton<QuestManager>.Instance.CreateContract_Networked(Player.Local.Connection, Guid.NewGuid().ToString(), true, ((NetworkBehaviour)nPC).NetworkObject, val3, new GameDateTime(1300), NetworkSingleton<TimeManager>.Instance.GetDateTime(), (NetworkObject)null); string text = "Hey, I wanna strengthen our partnership. How about we do a session.\n\nI need you to bring me <color=#6b9cff>3x " + ((ItemDefinition)val).Name + "</color> in <b>BEST</b> quality you can get at <color=#6b9cff>6:00am to 12:00pm</color>.\nMeet me <color=#6b9cff>" + val2.LocationDescription + "</color>."; nPC.SendTextMessage(text); } [IteratorStateMachine(typeof(<AddContractListener>d__20))] private IEnumerator AddContractListener(Contract contract) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <AddContractListener>d__20(0) { <>4__this = this, contract = contract }; } public void WeekPass() { bool entryValue = MelonPreferences.GetEntryValue<bool>("NPCLaunderers", "EnableEnvy"); bool entryValue2 = MelonPreferences.GetEntryValue<bool>("NPCLaunderers", "EnableCutDecreaseEvent"); if (!((Object)(object)nPC == (Object)null) && !((Object)(object)dialogueController == (Object)null) && laundererData.isUnlocked) { if (entryValue) { RandomizeCut(); } if (Random.Range(0, 100) >= 60 && entryValue2) { RequireMix(); } } } public void OnDestroy() { laundererData = null; isMainDialogueReady = false; isDialogueInitReady = false; nPC = null; dialogueController = null; laundererUI = null; upfrontInstance = 0f; withContract = false; } private void Update() { if (!isCheckingLaundry) { MelonCoroutines.Start(StartLaundryCheck()); } if (!isCheckingDialouge) { MelonCoroutines.Start(StartDialougeCheck()); } if (!isCheckingSavedLaundry) { MelonCoroutines.Start(StartSavedLaundryCheck()); } if (!isUpdatingFriendly) { MelonCoroutines.Start(UpdateFriendlyState()); } } [IteratorStateMachine(typeof(<StartLaundryCheck>d__24))] private IEnumerator StartLaundryCheck() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <StartLaundryCheck>d__24(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<StartDialougeCheck>d__25))] private IEnumerator StartDialougeCheck() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <StartDialougeCheck>d__25(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<StartSavedLaundryCheck>d__26))] private IEnumerator StartSavedLaundryCheck() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <StartSavedLaundryCheck>d__26(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<UpdateFriendlyState>d__27))] private IEnumerator UpdateFriendlyState() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <UpdateFriendlyState>d__27(0) { <>4__this = this }; } private void LoadLaundererData() { if (laundererData != null && !(laundererData.RequiredProductID == "")) { Contract val = ((IEnumerable<Contract>)Object.FindObjectsOfType<Contract>()).FirstOrDefault((Func<Contract, bool>)((Contract c) => (int)((Quest)c).QuestState == 1 && ((Quest)c).GetQuestTitle().Contains(nPC.FirstName))); if ((Object)(object)val != (Object)null && !withContract && val.ProductList.entries.Any((Entry e) => e.ProductID == laundererData.RequiredProductID)) { MelonCoroutines.Start(AddContractListener(val)); } if ((Object)(object)val == (Object)null && !withContract && laundererData.RequiredProductID != "") { RequireMix(laundererData.RequiredProductID); } } } } public static class NPCUtilities { public static DialogueNodeData CreateDialogueInitNodeData(float amount_min, float amount_max, double cut, float upfront, Launderer launderer) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0053: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown DialogueNodeData val = new DialogueNodeData(); val.DialogueNodeLabel = "LAUNDER_INIT_NODE"; val.DialogueText = $"Alright, I can wash around <color=#16F01C>${amount_min} - ${amount_max}</color> of your dirties. But there will be some cuts, of course. I'll let you know how much every week. But for now, Let us start with <color=#6b9cff>{cut}%</color> and an upfront of <color=#16F01C>${upfront}</color>"; DialogueChoiceData[] choices = (DialogueChoiceData[])(object)new DialogueChoiceData[2] { new DialogueChoiceData { ChoiceLabel = "ACCEPT_LAUNDER_TERMS", ChoiceText = "Sure, Let's do it." }, new DialogueChoiceData { ChoiceLabel = "DECLINE_LAUNDER_TERMS", ChoiceText = "Nevermind" } }; val.choices = choices; return val; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { internal IgnoresAccessChecksToAttribute(string assemblyName) { } } }