Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of Silkroad v1.1.5
SilkRoad.dll
Decompiled 2 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using MelonLoader; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using S1API.Console; using S1API.DeadDrops; using S1API.Entities; using S1API.GameTime; using S1API.Internal.Abstraction; using S1API.Internal.Utils; using S1API.Items; using S1API.Messaging; using S1API.Money; using S1API.PhoneApp; using S1API.Products; using S1API.Quests; using S1API.Quests.Constants; using S1API.Saveables; using S1API.UI; using Silkroad; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(MyMod), "Silk Road App", "1.1.6", "Akermi", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("Omar")] [assembly: AssemblyConfiguration("Il2Cpp")] [assembly: AssemblyDescription("A Schedule One Mono / Il2Cpp Cross Compatibility Layer")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SilkRoad-S1API")] [assembly: AssemblyTitle("SilkRoad-S1API")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/KaBooMa/S1API")] [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; } } } [Serializable] public class DeliverySaveData { public string ProductID; public uint RequiredAmount; public int Reward; public string DeliveryDropGUID; public string RewardDropGUID; public bool Initialized; [JsonConstructor] public DeliverySaveData() { } } namespace Silkroad { public class DeadDropData { public DeadDropInstance? DeliveryDeadDrop; public DeadDropInstance? CollectionDeadDrop; } public class MyMod : MelonMod { } public class OrderData { public ProductDefinition? Product; public int Amount; public int Price; } } namespace SilkRoad { public class BlackmarketBuyer : NPC { private static readonly string[] DeliveryAcceptedTexts = new string[5] { "We’ve heard of your product. {amount} bricks of {product}. Impress us.", "Your name reached our ears. {amount} bricks of {product}. Discreet drop. No attention.", "Quality like yours doesn't go unnoticed. Deliver {amount} bricks of {product}. Same location.", "We're watching, and we’re interested. {amount} bricks of {product}. Clean work only.", "Consider this a test. {amount} bricks of {product}. Don’t disappoint." }; private static readonly string[] DeliverySuccessTexts = new string[5] { "The stash was verified. Your reward will be with you shortly.", "Everything checked out. Sit tight — payment's on the way.", "Impressive. Clean drop. Expect your cash soon.", "The cargo's in place. Funds are being processed.", "Solid work. Your reward is en route. Stay alert." }; private static readonly string[] InstantRewardTexts = new string[5] { "Payment’s been sent. You did good — we notice things like that.", "Cash is in your account. You pulled your weight, and that matters.", "Transfer complete. Always good doing business with someone dependable.", "Funds delivered. You handled it right — that earns respect.", "You’ve been paid. Stick with us, and there’s more where that came from." }; private static Sprite? npcSprite => ImageUtils.LoadImage("silkroad\\SilkroadIcon.png"); public bool IsInitialized { get; private set; } = false; public BlackmarketBuyer() : base("blackmarket_buyer", "Blackmarket", "Buyer", npcSprite) { } protected override void OnLoaded() { ((Saveable)this).OnLoaded(); Contacts.Buyer = this; IsInitialized = true; } protected override void OnCreated() { ((Registerable)this).OnCreated(); Contacts.Buyer = this; } public void SendDeliveryAccepted(string product, int amount) { string text = DeliveryAcceptedTexts[RandomUtils.RangeInt(0, DeliveryAcceptedTexts.Length)]; string text2 = text.Replace("{product}", "<color=#34AD33>" + product + "</color>").Replace("{amount}", $"<color=#FF0004>{amount}x</color>"); ((NPC)this).SendTextMessage(text2, (Response[])null, 1f, true); } public void SendDeliverySuccess(string product) { string text = DeliverySuccessTexts[RandomUtils.RangeInt(0, DeliverySuccessTexts.Length)]; ((NPC)this).SendTextMessage(text, (Response[])null, 1f, true); } public void SendRewardDropped() { string text = InstantRewardTexts[RandomUtils.RangeInt(0, InstantRewardTexts.Length)]; ((NPC)this).SendTextMessage(text, (Response[])null, 1f, true); } } public static class Contacts { public static BlackmarketBuyer Buyer { get; internal set; } } public class IntroData { public int Progress; public IntroData(int progress = 0) { Progress = progress; } } public class MyApp : PhoneApp { private List<QuestData> quests; private RectTransform questListContainer; private Text questTitle; private Text questTask; private Text questReward; private Text deliveryStatus; private Text acceptLabel; private Text cancelLabel; private Text refreshLabel; private Button acceptButton; private Button cancelButton; private Button refreshButton; protected override string AppName => "Silkroad"; protected override string AppTitle => "Silkroad"; protected override string IconLabel => "Silkroad"; protected override string IconFileName => "silkroad\\SilkroadIcon.png"; protected override void OnCreated() { ((PhoneApp)this).OnCreated(); } protected override void OnCreatedUI(GameObject container) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Expected O, but got Unknown //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Unknown result type (might be due to invalid IL or missing references) GameObject val = UIFactory.Panel("MainBG", container.transform, Color.black, (Vector2?)null, (Vector2?)null, true); UIFactory.TopBar("TopBar", val.transform, "Silk Road", 0.82f, 75, 75, 0, 35); GameObject val2 = UIFactory.Panel("QuestListPanel", val.transform, new Color(0.1f, 0.1f, 0.1f), (Vector2?)new Vector2(0.02f, 0.05f), (Vector2?)new Vector2(0.49f, 0.82f), false); GameObject val3 = UIFactory.Panel("Separator", val.transform, new Color(0.2f, 0.2f, 0.2f), (Vector2?)new Vector2(0.485f, 0f), (Vector2?)new Vector2(0.487f, 0.82f), false); ScrollRect val4 = default(ScrollRect); questListContainer = UIFactory.ScrollableVerticalList("QuestListScroll", val2.transform, ref val4); UIFactory.FitContentHeight(questListContainer); GameObject val5 = UIFactory.Panel("DetailPanel", val.transform, new Color(0.12f, 0.12f, 0.12f), (Vector2?)new Vector2(0.49f, 0f), (Vector2?)new Vector2(0.98f, 0.82f), false); UIFactory.VerticalLayoutOnGO(val5, 14, new RectOffset(24, 50, 15, 70)); questTitle = UIFactory.Text("Title", "Select a quest", val5.transform, 24, (TextAnchor)3, (FontStyle)1); questTask = UIFactory.Text("Task", "Task: --", val5.transform, 18, (TextAnchor)3, (FontStyle)0); questReward = UIFactory.Text("Reward", "Reward: --", val5.transform, 18, (TextAnchor)3, (FontStyle)0); deliveryStatus = UIFactory.Text("DeliveryStatus", "", val5.transform, 16, (TextAnchor)3, (FontStyle)2); ((Graphic)deliveryStatus).color = new Color(0.7f, 0.9f, 0.7f); GameObject val6 = UIFactory.Panel("TopButtonRow", val5.transform, Color.clear, (Vector2?)null, (Vector2?)null, false); UIFactory.HorizontalLayoutOnGO(val6, 12, 0, 0, 0, 0, (TextAnchor)4); UIFactory.SetLayoutGroupPadding((LayoutGroup)(object)val6.GetComponent<HorizontalLayoutGroup>(), 0, 0, 0, 0); GameObject val7 = UIFactory.ButtonRow("TopButtons", val5.transform, 14f, (TextAnchor)4); ValueTuple<GameObject, Button, Text> valueTuple = UIFactory.RoundedButtonWithLabel("RefreshBtn", "Refresh Order list", val7.transform, Color32.op_Implicit(new Color32((byte)32, (byte)130, (byte)246, byte.MaxValue)), 300f, 90f, 18, Color.white); GameObject item = valueTuple.Item1; Button item2 = valueTuple.Item2; Text item3 = valueTuple.Item3; refreshButton = item2; refreshLabel = item3; ButtonUtils.AddListener(refreshButton, (Action)delegate { RefreshButton(); }); ValueTuple<GameObject, Button, Text> valueTuple2 = UIFactory.RoundedButtonWithLabel("CancelBtn", "Cancel current Delivery", val7.transform, Color32.op_Implicit(new Color32((byte)235, (byte)53, (byte)56, byte.MaxValue)), 300f, 90f, 18, Color.black); GameObject item4 = valueTuple2.Item1; Button item5 = valueTuple2.Item2; Text item6 = valueTuple2.Item3; cancelButton = item5; cancelLabel = item6; if (!QuestDelivery.QuestActive) { ButtonUtils.Disable(cancelButton, cancelLabel, "No quest active"); } ValueTuple<GameObject, Button, Text> valueTuple3 = UIFactory.RoundedButtonWithLabel("AcceptBtn", "No quest selected", val5.transform, Color32.op_Implicit(new Color32((byte)145, byte.MaxValue, (byte)142, byte.MaxValue)), 460f, 60f, 22, Color.black); GameObject item7 = valueTuple3.Item1; Button item8 = valueTuple3.Item2; Text item9 = valueTuple3.Item3; acceptButton = item8; acceptLabel = item9; ButtonUtils.Disable(item8, acceptLabel, "No quest selected"); LoadQuests(); } private void RefreshButton() { if (Money.GetCashBalance() < 50000f) { deliveryStatus.text = "Not Enough Money"; return; } RefreshQuestList(); LoadQuests(); ConsoleHelper.RunCashCommand(-50000); } private void LoadQuests() { quests = new List<QuestData>(); List<ProductDefinition> list = ProductManager.DiscoveredProducts?.ToList(); if (list == null || list.Count == 0) { return; } HashSet<string> used = new HashSet<string>(); for (int i = 0; i < Math.Min(4, list.Count); i++) { ProductDefinition val = RandomUtils.PickUnique<ProductDefinition>((IList<ProductDefinition>)list, (Func<ProductDefinition, bool>)((ProductDefinition p) => used.Contains(((ItemDefinition)p).Name)), 10); if (!((ItemDefinition)(object)val == (ItemDefinition)null)) { used.Add(((ItemDefinition)val).Name); int num = RandomUtils.RangeInt(20, 100); int num2 = RandomUtils.RangeInt(10, 50); int reward = Mathf.RoundToInt(val.Price * 20f * (float)num + (float)(num2 * num)); quests.Add(new QuestData { Title = ((ItemDefinition)val).Name + " Delivery", Task = $"Deliver {num}x {((ItemDefinition)val).Name} bricks.", Reward = reward, ProductID = ((ItemDefinition)val).Name, AmountRequired = (uint)num }); } } RefreshQuestList(); } public static void ClearChildren(Transform parent) { if ((Object)(object)parent == (Object)null) { return; } try { int childCount = parent.childCount; for (int num = childCount - 1; num >= 0; num--) { Transform child = parent.GetChild(num); if ((Object)(object)child != (Object)null) { Object.Destroy((Object)(object)((Component)child).gameObject); } } } catch (Exception) { } } private void RefreshQuestList() { ClearChildren((Transform)(object)questListContainer); GameObject val2 = default(GameObject); GameObject val3 = default(GameObject); foreach (QuestData quest in quests) { if (quest == null) { MelonLogger.Warning("Null quest encountered in RefreshQuestList."); continue; } ProductDefinition val = ((IEnumerable<ProductDefinition>)ProductManager.DiscoveredProducts).FirstOrDefault((Func<ProductDefinition, bool>)((ProductDefinition p) => ((ItemDefinition)p).Name == quest.ProductID)); if (!((ItemDefinition)(object)val == (ItemDefinition)null)) { string text = "Client: Unknown"; if (val is WeedDefinition) { text = "Client: German Mafia"; } else if (val is MethDefinition) { text = "Client: Canadian Mafia"; } else if (val is CocaineDefinition) { text = "Client: Russian Mafia"; } Sprite icon = val.Icon; GameObject val4 = UIFactory.CreateQuestRow(quest.Title, (Transform)(object)questListContainer, ref val2, ref val3); UIFactory.SetIcon(icon, val2.transform); ButtonUtils.AddListener(val4.GetComponent<Button>(), (Action)delegate { OnSelectQuest(quest); }); UIFactory.CreateTextBlock(val3.transform, quest.Title, text, QuestDelivery.CompletedQuestKeys?.Contains($"{quest.ProductID}_{quest.AmountRequired}") ?? false); bool flag = !QuestDelivery.QuestActive && !(QuestDelivery.CompletedQuestKeys?.Contains($"{quest.ProductID}_{quest.AmountRequired}") ?? false); ButtonUtils.AddListener(val4.AddComponent<Button>(), (Action)delegate { OnSelectQuest(quest); }); } } } private void CancelCurrentQuest(QuestData quest) { QuestDelivery active = QuestDelivery.Active; if (active == null) { deliveryStatus.text = "❌ No active delivery to cancel."; return; } try { active.ForceCancel(); deliveryStatus.text = "\ud83d\udeab Delivery canceled."; ButtonUtils.Disable(cancelButton, cancelLabel, "Canceled"); ButtonUtils.Enable(acceptButton, acceptLabel, "Accept Delivery"); RefreshQuestList(); } catch (Exception) { deliveryStatus.text = "❌ Cancel failed."; } } private void OnSelectQuest(QuestData quest) { QuestData quest2 = quest; questTitle.text = quest2.Title; questTask.text = "Task: " + quest2.Task; questReward.text = $"Reward: <color=#00FF00>${quest2.Reward:N0}</color>"; deliveryStatus.text = ""; if (!QuestDelivery.QuestActive) { ButtonUtils.Enable(acceptButton, acceptLabel, "Accept Delivery"); ButtonUtils.ClearListeners(acceptButton); ButtonUtils.AddListener(acceptButton, (Action)delegate { AcceptQuest(quest2); }); } if (QuestDelivery.QuestActive) { ButtonUtils.Enable(acceptButton, acceptLabel, "In Progress"); ButtonUtils.ClearListeners(acceptButton); ButtonUtils.AddListener(acceptButton, (Action)delegate { AcceptQuest(quest2); }); ButtonUtils.Enable(cancelButton, cancelLabel, "Cancel Current Delivery"); ButtonUtils.ClearListeners(cancelButton); ButtonUtils.AddListener(cancelButton, (Action)delegate { CancelCurrentQuest(quest2); }); } ButtonUtils.ClearListeners(cancelButton); ButtonUtils.AddListener(cancelButton, (Action)delegate { CancelCurrentQuest(quest2); }); ButtonUtils.Enable(refreshButton, refreshLabel, "Refresh Order List"); ButtonUtils.ClearListeners(refreshButton); ButtonUtils.AddListener(refreshButton, (Action)delegate { RefreshButton(); }); } private void AcceptQuest(QuestData quest) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: 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) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) string item = $"{quest.ProductID}_{quest.AmountRequired}"; if (QuestDelivery.QuestActive) { ButtonUtils.SetStyle(acceptButton, acceptLabel, "In Progress", Color32.op_Implicit(new Color32((byte)145, byte.MaxValue, (byte)142, byte.MaxValue))); deliveryStatus.text = "⚠\ufe0f Finish your current job first!"; ButtonUtils.Disable(acceptButton, acceptLabel, "In Progress"); return; } if (QuestDelivery.CompletedQuestKeys.Contains(item)) { ButtonUtils.SetStyle(acceptButton, acceptLabel, "Already Delivered", Color32.op_Implicit(new Color32((byte)145, byte.MaxValue, (byte)142, byte.MaxValue))); deliveryStatus.text = "⛔ Already delivered this shipment."; ButtonUtils.Disable(acceptButton, acceptLabel, "Already Delivered"); return; } deliveryStatus.text = "\ud83d\udce6 Delivery started!"; ButtonUtils.Disable(acceptButton, acceptLabel, "In Progress"); Quest val = QuestManager.CreateQuest<QuestDelivery>((string)null); if (val is QuestDelivery questDelivery) { questDelivery.Data.ProductID = quest.ProductID; questDelivery.Data.RequiredAmount = quest.AmountRequired; questDelivery.Data.Reward = quest.Reward; Contacts.Buyer?.SendDeliveryAccepted(questDelivery.Data.ProductID, (int)questDelivery.Data.RequiredAmount); QuestDelivery.Active = questDelivery; } ButtonUtils.SetStyle(acceptButton, acceptLabel, "In Progress", Color32.op_Implicit(new Color32((byte)145, byte.MaxValue, (byte)142, byte.MaxValue))); deliveryStatus.text = "\ud83d\udce6 Delivery started!"; ((Selectable)acceptButton).interactable = false; ButtonUtils.Enable(cancelButton, cancelLabel, "Cancel Current Delivery"); } } public class QuestData { public string Title; public string Task; public int Reward; public string ProductID; public uint AmountRequired; public string TargetObjectName; } public class QuestDelivery : Quest { [SaveableField("DeliveryData")] public DeliverySaveData Data = new DeliverySaveData(); private DeadDropInstance deliveryDrop; public static HashSet<string> CompletedQuestKeys = new HashSet<string>(); private QuestEntry deliveryEntry; private QuestEntry rewardEntry; public static bool QuestActive = false; private bool rewardGiven = false; public static QuestDelivery? Active { get; internal set; } protected override Sprite? QuestIcon => ImageUtils.LoadImage("silkroad\\SilkroadIcon_quest.png"); protected override string Title => (Data?.ProductID != null) ? ("Deliver " + Data.ProductID) : "Silkroad Delivery"; protected override string Description => (Data?.ProductID != null && Data.RequiredAmount != 0) ? $"Deliver {Data.RequiredAmount}x bricks of {Data.ProductID} to the drop point." : "Deliver the assigned product to the stash location."; public static event Action OnQuestCompleted; protected override void OnLoaded() { ((Saveable)this).OnLoaded(); MelonCoroutines.Start(WaitForBuyerAndSendStatus()); } private IEnumerator WaitForBuyerAndSendStatus() { float timeout = 5f; float waited = 0f; while ((Contacts.Buyer == null || !Contacts.Buyer.IsInitialized) && waited < timeout) { waited += Time.deltaTime; yield return null; } if (Contacts.Buyer != null && Contacts.Buyer.IsInitialized) { } } public QuestEntry GetDeliveryEntry() { return deliveryEntry; } public QuestEntry GetRewardEntry() { return rewardEntry; } public void ForceCancel() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Invalid comparison between Unknown and I4 TimeManager.OnDayPass = (Action)Delegate.Remove(TimeManager.OnDayPass, new Action(TimeManager_OnDayPass)); if (deliveryEntry != null && (int)deliveryEntry.State != 2) { rewardEntry.SetState((QuestState)3); } if (rewardEntry != null && (int)rewardEntry.State != 2) { rewardEntry.SetState((QuestState)3); } QuestActive = false; Active = null; ((Quest)this).Fail(); } protected override void OnCreated() { //IL_01a6: Unknown result type (might be due to invalid IL or missing references) ((Registerable)this).OnCreated(); QuestActive = true; Active = this; if (Data == null) { Data = new DeliverySaveData(); } if (!Data.Initialized) { List<DeadDropInstance> list = DeadDropManager.All?.ToList(); if (list == null || list.Count < 6) { return; } deliveryDrop = list[RandomUtils.RangeInt(0, list.Count)]; Data.DeliveryDropGUID = deliveryDrop.GUID; Data.Initialized = true; } else { deliveryDrop = ((IEnumerable<DeadDropInstance>)DeadDropManager.All).FirstOrDefault((Func<DeadDropInstance, bool>)((DeadDropInstance d) => d.GUID == Data.DeliveryDropGUID)); if (deliveryDrop == null) { List<DeadDropInstance> list2 = DeadDropManager.All.ToList(); if (list2.Count < 2) { return; } deliveryDrop = list2[0]; Data.DeliveryDropGUID = deliveryDrop.GUID; } } deliveryEntry = ((Quest)this).AddEntry($"Deliver {Data.RequiredAmount}x bricks of {Data.ProductID} at the dead drop.", (Vector3?)null); deliveryEntry.POIPosition = deliveryDrop.Position; deliveryEntry.Begin(); rewardEntry = ((Quest)this).AddEntry("Wait for the payment to arrive.", (Vector3?)null); rewardEntry.SetState((QuestState)0); deliveryDrop.Storage.OnClosed += CheckDelivery; } private void CheckDelivery() { //IL_0040: 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) ItemSlotInstance[] slots = deliveryDrop.Storage.Slots; foreach (ItemSlotInstance val in slots) { bool flag = val.ItemInstance is ProductInstance; string text = (flag ? ((ItemInstance)(ProductInstance)val.ItemInstance).Definition.Name : "null"); string text2 = (flag ? ((ItemDefinition)((ProductInstance)val.ItemInstance).AppliedPackaging).Name : "null"); int quantity = val.Quantity; } int num = deliveryDrop.Storage.Slots.Where(delegate(ItemSlotInstance slot) { ItemInstance itemInstance2 = slot.ItemInstance; ProductInstance val4 = (ProductInstance)(object)((itemInstance2 is ProductInstance) ? itemInstance2 : null); return val4 != null && ((ItemDefinition)val4.AppliedPackaging).Name == "Brick" && ((ItemInstance)val4).Definition.Name == Data.ProductID; }).Sum((ItemSlotInstance slot) => slot.Quantity); if (num < Data.RequiredAmount) { return; } uint num2 = Data.RequiredAmount; ItemSlotInstance[] slots2 = deliveryDrop.Storage.Slots; foreach (ItemSlotInstance val2 in slots2) { ItemInstance itemInstance = val2.ItemInstance; ProductInstance val3 = (ProductInstance)(object)((itemInstance is ProductInstance) ? itemInstance : null); if (val3 != null && ((ItemDefinition)val3.AppliedPackaging).Name == "Brick" && ((ItemInstance)val3).Definition.Name == Data.ProductID) { int num3 = (int)Mathf.Min((float)val2.Quantity, (float)num2); val2.AddQuantity(-num3); num2 -= (uint)num3; if (num2 == 0) { break; } } } deliveryEntry.Complete(); rewardEntry.SetState((QuestState)1); rewardGiven = false; MelonCoroutines.Start(DelayedReward()); TimeManager.OnDayPass = (Action)Delegate.Combine(TimeManager.OnDayPass, new Action(TimeManager_OnDayPass)); Contacts.Buyer?.SendDeliverySuccess(Data.ProductID); } private void TimeManager_OnDayPass() { TryGiveReward("OnDayPass"); } private IEnumerator DelayedReward() { float delaySeconds = RandomUtils.RangeInt(120, 200); yield return (object)new WaitForSeconds(delaySeconds); TryGiveReward("Delay"); } private void TryGiveReward(string source) { if (rewardGiven) { return; } rewardGiven = true; TimeManager.OnDayPass = (Action)Delegate.Remove(TimeManager.OnDayPass, new Action(TimeManager_OnDayPass)); if (deliveryEntry != null) { int reward = Data.Reward; ConsoleHelper.RunCashCommand(reward); QuestActive = false; string item = $"{Data.ProductID}_{Data.RequiredAmount}"; CompletedQuestKeys.Add(item); Contacts.Buyer?.SendRewardDropped(); QuestEntry obj = rewardEntry; if (obj != null) { obj.Complete(); } ((Quest)this).Complete(); QuestDelivery.OnQuestCompleted?.Invoke(); } } } }