Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of Bicky Robby Bulk Orders v1.0.1
Mods/BulkBuyer.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BulkBuyer; using MelonLoader; using Microsoft.CodeAnalysis; using S1API.DeadDrops; using S1API.Entities; using S1API.GameTime; using S1API.Items; using S1API.Leveling; using S1API.Messaging; using S1API.Money; using S1API.Products; using S1API.Quests; using S1API.Quests.Constants; using S1API.Saveables; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(BulkBuyerMod), "BulkBuyer", "1.0.1", "KaBooMa", null)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("BulkBuyer")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("BulkBuyer")] [assembly: AssemblyTitle("BulkBuyer")] [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 BulkBuyer { public class BickyRobby : NPC { private const int ProductPerLevel = 8; private const int ProductVariation = 10; private const float ProductPriceMultiplier = 1.2f; private const int MinDaysAllowed = 1; private const int MaxDaysAllowed = 3; [SaveableField("Order")] private OrderData? _orderData; [SaveableField("Intro")] private readonly IntroData _introData = new IntroData(); private static readonly (string message, string response)[] IntroTexts = new(string, string)[3] { ("Yo, your uncle said you might could help me with supply. I'm running low.", "Where you wanna meet?"), ("I can't meet up. I'm over in Belland, like 300 miles out dawg.", "What about a dead drop?"), ("That works. I'll text you when I need a drop. Peace.", "") }; private static readonly string[] RandomRequestTexts = new string[6] { "Yo, I need {amount} {product} by {day}. I've got {price} with your name on it. Can you make that happen?", "My people are fienin. Got {amount} {product}?? Need it by {day} if you can. I'll drop {price} for it.", "Ayo, can you hit me with {amount} {product} by {day} for me? You know I need it, and I'll pay {price} for that.", "{amount} {product} by {day} - you got me?? I got you {price} waiting.", "I'm runnin' low on {product}. Can you push {amount} to me by {day}? I'll pay {price} for it.", "Bro, I'm out here scrambling. Can you get {amount} {product} by {day}? I'm desperate, I'll toss {price} your way." }; private static readonly string[] RandomAcceptResponses = new string[3] { "No doubt, send me a pin.", "Say no more, I gotchu.", "Aight, let's run it." }; private static readonly string[] RandomDenyResponses = new string[3] { "Nah, ain't got it right now.", "Can't do it at the moment.", "Nah, I can't make this week." }; private static readonly string[] RandomNegativeTexts = new string[3] { "Damn, aight... guess that's it then.", "Cool, I guess... catch you later.", "Shit, no no. Ok, i'll hit you up later tho." }; private static readonly string[] RandomPositiveTexts = new string[3] { "Hell yeah bro, thanks.", "Solid, I'll drop you the cash when I pull up.", "You a real one, fam. Appreciate you." }; private bool IntroCompleted => _introData != null && _introData.Progress >= IntroTexts.Length - 1; public BickyRobby() : base("bicky_robby", "Bicky", "Robby", (Sprite)null) { } protected override void OnCreated() { TimeManager.OnDayPass = (Action)Delegate.Combine(TimeManager.OnDayPass, new Action(OnDayPass)); } protected override void OnResponseLoaded(Response response) { MelonLogger.Msg(response.Label); switch (response.Label) { case "ACCEPT": response.OnTriggered = AcceptOrder; break; case "DENY": response.OnTriggered = DenyOrder; break; case "PROGRESS_INTRO": response.OnTriggered = ProgressIntro; break; } } private void OnDayPass() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Invalid comparison between Unknown and I4 if (!IntroCompleted && (int)LevelManager.Rank >= 3) { ProgressIntro(); } else if (_orderData != null) { DenyOrder(); } else if ((int)TimeManager.CurrentDay == 1) { SendRandomText(); } } private void SendRandomText() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected I4, but got Unknown //IL_00cf: 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_00eb: 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_015c: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Expected O, but got Unknown //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Expected O, but got Unknown if (ProductManager.DiscoveredProducts.Length != 0) { ProductDefinition product = ProductManager.DiscoveredProducts[Random.Range(0, ProductManager.DiscoveredProducts.Length)]; _orderData = new OrderData { Product = product }; if (!((ItemDefinition)(object)_orderData?.Product == (ItemDefinition)null)) { int num = (int)LevelManager.Rank; int num2 = num * 8; int num3 = Mathf.RoundToInt(5f); int num4 = num2 - num3; int num5 = num2 + num3; _orderData.Amount = Random.Range(num4, num5 + 1); _orderData.Price = Mathf.RoundToInt(_orderData.Product.Price * (float)_orderData.Amount * 1.2f); int num6 = Random.Range(1, 4); Day val = (Day)((TimeManager.CurrentDay + num6) % Enum.GetValues(typeof(Day)).Length); string text = RandomRequestTexts[Random.Range(0, RandomRequestTexts.Length)]; string text2 = text.Replace("{product}", "<color=#3399FF>" + ((ItemDefinition)_orderData.Product).Name + "</color>").Replace("{amount}", $"{_orderData.Amount}x").Replace("{day}", $"<color=#FF6600>{val}</color>") .Replace("{price}", $"<color=#00CC00>${_orderData.Price:N0}</color>"); string text3 = RandomDenyResponses[Random.Range(0, RandomDenyResponses.Length)]; string text4 = RandomAcceptResponses[Random.Range(0, RandomAcceptResponses.Length)]; ((NPC)this).SendTextMessage(text2, (Response[])(object)new Response[2] { new Response { Label = "ACCEPT", Text = text4, OnTriggered = AcceptOrder }, new Response { Label = "DENY", Text = text3, OnTriggered = DenyOrder } }, 1f, true); } } } private void DenyOrder() { string text = RandomNegativeTexts[Random.Range(0, RandomNegativeTexts.Length)]; ((NPC)this).SendTextMessage(text, (Response[])null, 1f, true); ClearPendingOrder(); } private void AcceptOrder() { if (_orderData == null || (ItemDefinition)(object)_orderData.Product == (ItemDefinition)null) { throw new Exception("No pending product assigned in BulkBuyer!"); } string text = RandomPositiveTexts[Random.Range(0, RandomPositiveTexts.Length)]; ((NPC)this).SendTextMessage(text, (Response[])null, 1f, true); QuestBickyOrder questBickyOrder = (QuestBickyOrder)(object)QuestManager.CreateQuest<QuestBickyOrder>((string)null); questBickyOrder.SetupAsNew(_orderData); ClearPendingOrder(); } private void ClearPendingOrder() { _orderData = null; } private void ProgressIntro() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown if (_introData == null) { throw new Exception("No intro data assigned in BulkBuyer!"); } List<Response> list = new List<Response>(); if (!IntroCompleted) { list.Add(new Response { Label = "PROGRESS_INTRO", Text = IntroTexts[_introData.Progress].response, OnTriggered = ProgressIntro }); } ((NPC)this).SendTextMessage(IntroTexts[_introData.Progress].message, list.ToArray(), 1f, true); _introData.Progress++; } } public class BulkBuyerMod : MelonMod { } public class DeadDropData { public DeadDropInstance? DeliveryDeadDrop; public DeadDropInstance? CollectionDeadDrop; } public class IntroData { public int Progress; public IntroData(int progress = 0) { Progress = progress; } } public class OrderData { public ProductDefinition? Product; public int Amount; public int Price; } internal class QuestBickyOrder : Quest { [SaveableField("Order")] private OrderData _orderData = new OrderData(); [SaveableField("DeadDrop")] private readonly DeadDropData _deadDropData = new DeadDropData(); private QuestEntry? _deliveryQuestEntry; private QuestEntry? _collectionQuestEntry; protected override string Title => "Bicky Needs Product!"; protected override string Description => $"Deliver Bicky his product and he'll drop you <color=#00CC00>${_orderData.Price:N0}</color> off."; protected override void OnCreated() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) object arg = _orderData.Amount; ProductDefinition? product = _orderData.Product; string text = $"Drop off {arg}x <color=#3399FF>{((product != null) ? ((ItemDefinition)product).Name : null)}</color> at the dead drop."; DeadDropInstance? deliveryDeadDrop = _deadDropData.DeliveryDeadDrop; _deliveryQuestEntry = ((Quest)this).AddEntry(text, (deliveryDeadDrop != null) ? new Vector3?(deliveryDeadDrop.Position) : null); string text2 = $"Pick up <color=#00CC00>${_orderData.Price:N0}</color> at the dead drop."; DeadDropInstance? collectionDeadDrop = _deadDropData.CollectionDeadDrop; _collectionQuestEntry = ((Quest)this).AddEntry(text2, (collectionDeadDrop != null) ? new Vector3?(collectionDeadDrop.Position) : null); if (_deadDropData.DeliveryDeadDrop != null) { _deadDropData.DeliveryDeadDrop.Storage.OnClosed += TryForDelivery; } if (_deadDropData.CollectionDeadDrop != null) { _deadDropData.CollectionDeadDrop.Storage.OnOpened += TryForCollection; } } public void SetupAsNew(OrderData pendingOrderData) { _orderData = pendingOrderData; _deadDropData.DeliveryDeadDrop = DeadDropManager.All[Random.Range(0, DeadDropManager.All.Length)]; _deadDropData.CollectionDeadDrop = DeadDropManager.All[Random.Range(0, DeadDropManager.All.Length)]; } private void TryForDelivery() { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) DeadDropInstance? deliveryDeadDrop = _deadDropData.DeliveryDeadDrop; List<ItemSlotInstance> list = ((deliveryDeadDrop != null) ? deliveryDeadDrop.Storage.Slots.Where(delegate(ItemSlotInstance slot) { ItemInstance itemInstance = slot.ItemInstance; ProductInstance val = (ProductInstance)(object)((itemInstance is ProductInstance) ? itemInstance : null); return val != null && val.IsPackaged && slot.ItemInstance.Definition == (ItemDefinition)(object)_orderData.Product; }).ToList() : null); if (list == null) { return; } int num = list.Sum((ItemSlotInstance slot) => slot.Quantity * ((ProductInstance)slot.ItemInstance).AppliedPackaging.Quantity); if (num != _orderData.Amount) { return; } int num2 = _orderData.Amount; foreach (ItemSlotInstance item in list) { int quantity = ((ProductInstance)item.ItemInstance).AppliedPackaging.Quantity; int num3 = Mathf.Min(item.Quantity * quantity, num2); item.AddQuantity(-(num3 / quantity)); num2 -= num3; } QuestEntry? deliveryQuestEntry = _deliveryQuestEntry; if (deliveryQuestEntry != null) { deliveryQuestEntry.Complete(); } QuestEntry? collectionQuestEntry = _collectionQuestEntry; if (collectionQuestEntry != null) { collectionQuestEntry.SetState((QuestState)1); } if (_deadDropData.DeliveryDeadDrop != null) { _deadDropData.DeliveryDeadDrop.Storage.OnClosed -= TryForDelivery; } } private void TryForCollection() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown if (_orderData == null || _deadDropData.CollectionDeadDrop == null) { throw new Exception("No collection dead drop in QuestBulkOrder!"); } CashDefinition val = (CashDefinition)ItemManager.GetItemDefinition("cash"); CashInstance val2 = (CashInstance)((ItemDefinition)val).CreateInstance(1); val2.SetQuantity((float)_orderData.Price); if (_deadDropData.CollectionDeadDrop.Storage.CanItemFit((ItemInstance)(object)val2, 1)) { _deadDropData.CollectionDeadDrop.Storage.AddItem((ItemInstance)(object)val2); QuestEntry? collectionQuestEntry = _collectionQuestEntry; if (collectionQuestEntry != null) { collectionQuestEntry.Complete(); } if (_deadDropData.CollectionDeadDrop != null) { MelonLogger.Msg("Removing OnOpened"); _deadDropData.CollectionDeadDrop.Storage.OnOpened -= TryForCollection; } } } } }