Exemplo n.º 1
0
        public static void Postfix(ITechData data, ref List <TooltipIcon> icons)
        {
            if (data == null)
            {
                return;
            }
            var ingredientCount = data.ingredientCount;

            for (var i = 0; i < ingredientCount; i++)
            {
                var ingredient = data.GetIngredient(i);
                var techType   = ingredient.techType;
                if (!KnownTech.Contains(techType) && PDAScanner.ContainsCompleteEntry(techType))
                {
                    KnownTech.Add(techType);
                    continue;
                }
                if (!CrafterLogic.IsCraftRecipeUnlocked(techType))
                {
                    var icon = icons.Find((TooltipIcon) => TooltipIcon.sprite == SpriteManager.Get(techType) && TooltipIcon.text.Contains(Language.main.GetOrFallback(TooltipFactory.techTypeIngredientStrings.Get(techType), techType)));
                    if (icons.Contains(icon))
                    {
                        icons.Remove(icon);
                        var tooltipIcon = new TooltipIcon()
                        {
                            sprite = SpriteManager.Get(TechType.None), text = Main.Config.UnKnownTitle
                        };
                        icons.Add(tooltipIcon);
                    }
                }
            }
        }
        private PDAScanner.Result Scan()
        {
            if (stateCurrent != ScanState.None)
            {
                return(PDAScanner.Result.None);
            }
            if (idleTimer > 0f)
            {
                return(PDAScanner.Result.None);
            }

            PDAScanner.Result     result     = PDAScanner.Result.None;
            PDAScanner.ScanTarget scanTarget = PDAScanner.scanTarget;
            PDAScanner.UpdateTarget(scanDistance, false);

            if (scanTarget.isValid && energyMixin.charge > 0f)
            {
                result = PDAScanner.Scan();

                if (result == PDAScanner.Result.Scan)
                {
                    float amount = powerConsumption * Time.deltaTime;
                    energyMixin.ConsumeEnergy(amount);
                    stateCurrent = ScanState.Scan;
                    isScanning   = true;
                }
                else if (result == PDAScanner.Result.Done || result == PDAScanner.Result.Researched)
                {
                    idleTimer = 0.5f;
                    PDASounds.queue.PlayIfFree(completeSoundAsset);
                }
            }
            return(result);
        }
Exemplo n.º 3
0
        public static void Postfix(IList <Ingredient> ingredients, ref List <TooltipIcon> icons)
        {
            if (ingredients == null)
            {
                return;
            }

            var ingredientCount = ingredients.Count;

            for (var i = 0; i < ingredientCount; i++)
            {
                var techType = ingredients[i].techType;
                if (!KnownTech.Contains(techType) && PDAScanner.ContainsCompleteEntry(techType))
                {
                    KnownTech.Add(techType);
                }

                if (KnownTech.Contains(techType) || !GameModeUtils.RequiresBlueprints())
                {
                    continue;
                }
                var icon = icons.Find((TooltipIcon) => TooltipIcon.sprite == SpriteManager.Get(techType) && TooltipIcon.text.Contains(Language.main.GetOrFallback(TooltipFactory.techTypeIngredientStrings.Get(techType), techType)));
                if (!icons.Contains(icon))
                {
                    continue;
                }
                icons.Remove(icon);
                var tooltipIcon = new TooltipIcon()
                {
                    sprite = SpriteManager.Get(TechType.None), text = Main.Config.UnKnownTitle
                };
                icons.Add(tooltipIcon);
            }
        }
        public override void Process(PDAEntryAdd packet)
        {
            using (packetSender.Suppress <PDAEntryAdd>())
                using (packetSender.Suppress <PDAEntryProgress>())
                {
                    TechType             techType  = packet.TechType.ToUnity();
                    PDAScanner.EntryData entryData = PDAScanner.GetEntryData(techType);

                    if (!PDAScanner.GetPartialEntryByKey(techType, out PDAScanner.Entry entry))
                    {
                        entry = PDAScanner.Add(techType, packet.Unlocked);
                    }

                    if (entry != null)
                    {
                        entry.unlocked++;

                        if (entry.unlocked >= entryData.totalFragments)
                        {
                            PDAScanner.partial.Remove(entry);
                            PDAScanner.complete.Add(entry.techType);
                        }
                        else
                        {
                            int totalFragments = entryData.totalFragments;
                            if (totalFragments > 1)
                            {
                                float num2 = (float)entry.unlocked / (float)totalFragments;
                                float arg  = (float)Mathf.RoundToInt(num2 * 100f);
                                ErrorMessage.AddError(Language.main.GetFormat <string, float, int, int>("ScannerInstanceScanned", Language.main.Get(entry.techType.AsString(false)), arg, entry.unlocked, totalFragments));
                            }
                        }
                    }
                }
        }
Exemplo n.º 5
0
        public override void Process(PDAEntryProgress packet)
        {
            using (packetSender.Suppress <PDAEntryAdd>())
                using (packetSender.Suppress <PDAEntryProgress>())
                {
                    TechType             techType  = packet.TechType.ToUnity();
                    PDAScanner.EntryData entryData = PDAScanner.GetEntryData(techType);

                    PDAScanner.Entry entry;
                    if (PDAScanner.GetPartialEntryByKey(techType, out entry))
                    {
                        if (packet.Unlocked > entry.unlocked)
                        {
                            Log.Info("PDAEntryProgress Upldate Old:" + entry.unlocked + " New" + packet.Unlocked);
                            entry.unlocked = packet.Unlocked;
                        }
                    }
                    else
                    {
                        Log.Info("PDAEntryProgress New TechType:" + techType + " Unlocked:" + packet.Unlocked);
                        MethodInfo methodAdd = typeof(PDAScanner).GetMethod("Add", BindingFlags.NonPublic | BindingFlags.Static, null, new Type[] { typeof(TechType), typeof(int) }, null);
                        entry = (PDAScanner.Entry)methodAdd.Invoke(null, new object[] { techType, packet.Unlocked });
                    }
                }
        }
        public override void Process(PDAEntryProgress packet)
        {
            using (packetSender.Suppress <PDAEntryAdd>())
                using (packetSender.Suppress <PDAEntryProgress>())
                {
                    TechType techType = packet.TechType.ToUnity();

                    if (PDAScanner.GetPartialEntryByKey(techType, out PDAScanner.Entry entry))
                    {
                        if (packet.Unlocked == entry.unlocked)
                        {
                            // Add the entry as a cached progress
                            if (!PDAManagerEntry.CachedEntries.TryGetValue(packet.TechType, out PDAProgressEntry pdaProgressEntry))
                            {
                                PDAManagerEntry.CachedEntries.Add(packet.TechType, pdaProgressEntry = new PDAProgressEntry(packet.TechType, new Dictionary <NitroxId, float>()));
                            }
                            pdaProgressEntry.Entries[packet.NitroxId] = packet.Progress;
                        }
                        else if (packet.Unlocked > entry.unlocked)
                        {
                            Log.Info($"PDAEntryProgress Update For TechType:{techType} Old:{entry.unlocked} New:{packet.Unlocked}");
                            entry.unlocked = packet.Unlocked;
                        }
                    }
                    else
                    {
                        Log.Info($"PDAEntryProgress New TechType:{techType} Unlocked:{packet.Unlocked}");
                        methodAdd.Invoke(null, new object[] { techType, packet.Unlocked });
                    }
                }
        }
Exemplo n.º 7
0
        private void Process(ClientScanProgress msg)
        {
            var entryData = PDAScanner.GetEntryData(msg.tech);

            if (entryData == null)
            {
                return;
            }

            using (new MessageBlocker()) {
                PDAScanner.Entry entry;
                if (!PDAScanner.GetPartialEntryByKey(msg.tech, out entry))
                {
                    var methodAdd = typeof(PDAScanner).GetMethod("Add", BindingFlags.NonPublic | BindingFlags.Static, null, new Type[] { typeof(TechType), typeof(int) }, null);
                    entry = (PDAScanner.Entry)methodAdd.Invoke(null, new object[] { msg.tech, 0 });
                }

                if (entry != null)
                {
                    entry.unlocked = msg.progress;
                    if (entry.unlocked >= entryData.totalFragments)
                    {
                        var partial  = (List <PDAScanner.Entry>)(typeof(PDAScanner).GetField("partial", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null));
                        var complete = (HashSet <TechType>)(typeof(PDAScanner).GetField("complete", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null));

                        partial.Remove(entry);
                        complete.Add(entry.techType);
                    }
                }
            }
        }
Exemplo n.º 8
0
        private void OnHover()
        {
            if (energyMixin.charge <= 0f)
            {
                return;
            }

            PDAScanner.ScanTarget scanTarget = PDAScanner.scanTarget;

            PDAScanner.UpdateTarget(scanDistance, false);

            if (!scanTarget.isValid)
            {
                return;
            }

            PDAScanner.Result result = PDAScanner.CanScan();

            if (result == PDAScanner.Result.Scan)
            {
                HandReticle main = HandReticle.main;
                main.SetInteractText(scanTarget.techType.AsString(false), true, HandReticle.Hand.Left);
                main.SetIcon(HandReticle.IconType.Scan, 1.5f);

                if (stateCurrent == ScanState.Scan)
                {
                    main.SetIcon(HandReticle.IconType.Progress, 4f);
                    main.progressText.text = Mathf.RoundToInt(PDAScanner.scanTarget.progress * 100f) + "%";
                    SetProgressColor(Colors.Green);
                    main.progressImage.fillAmount = Mathf.Clamp01(PDAScanner.scanTarget.progress);
                    main.SetProgress(PDAScanner.scanTarget.progress);
                }
            }
        }
Exemplo n.º 9
0
            public PDAScanner.Entry GetEntry()
            {
                if (PDAScanner.GetPartialEntryByKey(EntryTechType, out PDAScanner.Entry entry) && entry.unlocked > Entry.unlocked)
                {
                    Unlocked       = true;
                    Entry.unlocked = entry.unlocked;
                }

                return(Entry);
            }
        public static bool Prefix(TechType techType, bool verbose)
        {
            if (Main.Config.Hardcore)
            {
                var entryData = PDAScanner.GetEntryData(techType);
                return(!verbose || entryData == null || (entryData != null && PDAScanner.ContainsCompleteEntry(techType)));
            }

            return(true);
        }
Exemplo n.º 11
0
 public override void Process(PDAEntryRemove packet)
 {
     using (packetSender.Suppress <PDAEntryRemove>())
     {
         if (PDAScanner.GetPartialEntryByKey(packet.TechType.ToUnity(), out PDAScanner.Entry entry))
         {
             PDAScanner.partial.Remove(entry);
             PDAScanner.complete.Add(entry.techType);
         }
     }
 }
        public static void Postfix(ref StringBuilder sb, TechType techType)
        {
            PDAScanner.EntryData entryData = PDAScanner.GetEntryData(techType);
            if (entryData == null || PDAScanner.ContainsCompleteEntry(techType) || CrafterLogic.IsCraftRecipeUnlocked(techType))
            {
                return;
            }

            sb.Clear();
            TooltipFactory.WriteTitle(sb, Main.config.UnKnownTitle);
            TooltipFactory.WriteDescription(sb, Main.config.UnKnownDescription);
        }
 public override void Process(PDAEntryRemove packet)
 {
     using (packetSender.Suppress <PDAEntryRemove>())
     {
         if (PDAScanner.GetPartialEntryByKey(packet.TechType.ToUnity(), out PDAScanner.Entry entry))
         {
             List <PDAScanner.Entry> partial  = (List <PDAScanner.Entry>)(typeof(PDAScanner).GetField("partial", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null));
             HashSet <TechType>      complete = (HashSet <TechType>)(typeof(PDAScanner).GetField("complete", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null));
             partial.Remove(entry);
             complete.Add(entry.techType);
         }
     }
 }
Exemplo n.º 14
0
        public static void Prefix(PDAData data)
        {
            List <TechType> types = new List <TechType>(data.defaultTech);

            foreach (TechType techType in types)
            {
                PDAScanner.EntryData entryData = PDAScanner.GetEntryData(techType);
                if (entryData != null && entryData.locked)
                {
                    data.defaultTech.Remove(techType);
                }
            }
        }
Exemplo n.º 15
0
        public static void Postfix()
        {
            if (PDAScanner.ContainsCompleteEntry(techType) || KnownTech.Contains(techType))
            {
                if (techType == TechType.ScrapMetal && !KnownTech.Contains(TechType.Titanium))
                {
                    PDAScanner.AddByUnlockable(TechType.Titanium, 1);
                    KnownTech.Add(TechType.Titanium);
                }

                if (!KnownTech.Contains(techType))
                {
                    KnownTech.Add(techType);
                }

                var entryData = PDAScanner.GetEntryData(techType);

                if (entryData != null && entryData.locked)
                {
                    PDAScanner.Unlock(entryData, true, true);

                    if (!KnownTech.Contains(entryData.blueprint))
                    {
                        KnownTech.Add(entryData.blueprint);
                    }
                }
#if SN1
                var techType2 = CraftData.GetHarvestOutputData(techType);
#elif BZ
                var techType2 = TechData.GetHarvestOutput(techType);
#endif
                if (techType2 != TechType.None)
                {
                    if (!KnownTech.Contains(techType2))
                    {
                        KnownTech.Add(techType2);
                    }

                    var entryData2 = PDAScanner.GetEntryData(techType2);
                    if (entryData2 != null && entryData2.locked)
                    {
                        PDAScanner.Unlock(entryData, true, true);

                        if (!KnownTech.Contains(entryData2.blueprint))
                        {
                            KnownTech.Add(entryData2.blueprint);
                        }
                    }
                }
            }
        }
Exemplo n.º 16
0
        // After 2 seconds without scanning, a packet will be sent with the latest progress
        static IEnumerator ThrottleLastProgress(ThrottledEntry throttledEntry)
        {
            do
            {
                yield return(new WaitForSeconds(LAST_PACKET_SEND_DELAY / 1000));
            }while (DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() < throttledEntry.LatestProgressTime.ToUnixTimeMilliseconds() + LAST_PACKET_SEND_DELAY);

            throttledEntry.GetEntry();
            if (!throttledEntry.Unlocked && !PDAScanner.ContainsCompleteEntry(throttledEntry.EntryTechType))
            {
                PDAManagerEntry.Progress(throttledEntry.Entry, throttledEntry.Id);
            }

            // No need to keep this in memory
            ThrottlingEntries.Remove(throttledEntry.Id);
        }
        public static void Postfix()
        {
            PDAScanner.ScanTarget scanTarget = PDAScanner.scanTarget;
            PDAScanner.EntryData  entryData  = PDAScanner.GetEntryData(scanTarget.techType);
            TechType key       = entryData?.key ?? TechType.None;
            TechType blueprint = entryData?.blueprint ?? TechType.None;

            if (scanTarget.techType != TechType.None && CrafterLogic.IsCraftRecipeUnlocked(scanTarget.techType) || (entryData != null && ((blueprint != TechType.None && CrafterLogic.IsCraftRecipeUnlocked(entryData.blueprint)) || (key != TechType.None && CrafterLogic.IsCraftRecipeUnlocked(entryData.key)))) || !scanTarget.isValid || !GameModeUtils.RequiresBlueprints())
            {
                return;
            }
#if SN1
            HandReticle.main.SetInteractText(Main.config.UnKnownLabel, false, HandReticle.Hand.None);
#elif BZ
            HandReticle.main.SetText(HandReticle.TextType.Hand, Main.config.UnKnownLabel, true, GameInput.Button.None);
#endif
        }
Exemplo n.º 18
0
        public static void Callback()
        {
            // When a player scans a fragment, it will be deleted from the world. We want to send out a pickup event
            // before the object can be removed and corresponding scan data is invalidated.
            TechType techType = PDAScanner.scanTarget.techType;

            PDAScanner.EntryData entryData = PDAScanner.GetEntryData(techType);

            // Only do this for fragments and player scans or nearby fish
            if (entryData != null && entryData.destroyAfterScan && PDAScanner.scanTarget.gameObject && !PDAScanner.scanTarget.isPlayer)
            {
                // A lot of fragments are virtual entities (spawned by placeholders in the world).  Sometimes the server only knows the id
                // of the placeholder and not the virtual entity. TODO: we will need to propagate deterministic ids to children entities for
                // these virtual entities.
                NitroxServiceLocator.LocateService <Item>().PickedUp(PDAScanner.scanTarget.gameObject, techType);
            }
        }
        private void OnHover()
        {
            if (energyMixin.charge <= 0f)
            {
                return;
            }

            PDAScanner.ScanTarget scanTarget = PDAScanner.scanTarget;

            PDAScanner.UpdateTarget(scanDistance, false);

            if (!scanTarget.isValid)
            {
                return;
            }

            PDAScanner.Result result = PDAScanner.CanScan();
        }
Exemplo n.º 20
0
        public static void Postfix(Pickupable pickupable)
        {
            if (newgame && Main.config.Hardcore && !Utils.GetContinueMode() && pickupable.GetTechType() != TechType.FireExtinguisher)
            {
                CoroutineHost.StartCoroutine(GiveHardcoreScanner());
                newgame = false;
                SMLHelper.V2.Handlers.IngameMenuHandler.RegisterOnQuitEvent(() => newgame = true);
            }

            TechType techType = pickupable.GetTechType();

            PDAScanner.EntryData entryData  = PDAScanner.GetEntryData(techType);
            GameObject           gameObject = pickupable.gameObject;

            if (Main.config.ScanOnPickup && Inventory.main.container.Contains(TechType.Scanner) && entryData != null)
            {
                if (!PDAScanner.GetPartialEntryByKey(techType, out PDAScanner.Entry entry))
                {
                    entry = PDAScanner.Add(techType, 1);
                }
                if (entry != null)
                {
                    PDAScanner.partial.Remove(entry);
                    PDAScanner.complete.Add(entry.techType);
                    PDAScanner.NotifyRemove(entry);
                    PDAScanner.Unlock(entryData, true, true, true);
                    KnownTech.Add(techType, false);
                    if (gameObject != null)
                    {
                        gameObject.SendMessage("OnScanned", null, SendMessageOptions.DontRequireReceiver);
                    }
#if SN1
                    ResourceTracker.UpdateFragments();
#endif
                }
            }

            if (!Main.config.Hardcore && entryData == null)
            {
                KnownTech.Add(techType, true);
            }
        }
        static void unlockPopupsUpdate()
        {
            KnownTech.AnalysisTech _getEntry(TechType techType) =>
            KnownTech.analysisTech.FirstOrDefault(tech => tech.techType == techType);

            foreach (var popup in unlockPopups)
            {
                var tech   = _getEntry(popup.Key);
                var sprite = _getEntry(popup.Value)?.unlockPopup;

                if (sprite == null && PDAScanner.GetEntryData(popup.Value) is PDAScanner.EntryData fragData)
                {
                    sprite = _getEntry(fragData.blueprint)?.unlockPopup;                     // try popup.Value as fragment tech type
                }
                if (sprite != null)
                {
                    tech.unlockPopup = sprite;
                }
            }
        }
        public static void Postfix(ScannerTool __instance)
        {
            PDAScanner.ScanTarget scanTarget = PDAScanner.scanTarget;
#if SN1
            PDAScanner.Result result = PDAScanner.CanScan();
#elif BZ
            PDAScanner.Result result = PDAScanner.CanScan(scanTarget);
#endif
            PDAScanner.EntryData entryData = PDAScanner.GetEntryData(PDAScanner.scanTarget.techType);

            if ((entryData != null && (CrafterLogic.IsCraftRecipeUnlocked(entryData.blueprint) || CrafterLogic.IsCraftRecipeUnlocked(entryData.key))) || PDAScanner.ContainsCompleteEntry(scanTarget.techType) || __instance.energyMixin.charge <= 0f || !scanTarget.isValid || result != PDAScanner.Result.Scan || !GameModeUtils.RequiresBlueprints())
            {
                return;
            }
#if SN1
            HandReticle.main.SetInteractText(Main.config.UnKnownLabel, false, HandReticle.Hand.None);
#elif BZ
            HandReticle.main.SetText(HandReticle.TextType.Hand, Main.config.UnKnownLabel, true, GameInput.Button.None);
#endif
        }
Exemplo n.º 23
0
        public override void Process(PDAEntryAdd packet)
        {
            using (packetSender.Suppress <PDAEntryAdd>())
                using (packetSender.Suppress <PDAEntryProgress>())
                {
                    TechType             techType  = packet.TechType.Enum();
                    PDAScanner.EntryData entryData = PDAScanner.GetEntryData(techType);

                    PDAScanner.Entry entry;
                    if (!PDAScanner.GetPartialEntryByKey(techType, out entry))
                    {
                        MethodInfo methodAdd = typeof(PDAScanner).GetMethod("Add", BindingFlags.NonPublic | BindingFlags.Static, null, new Type[] { typeof(TechType), typeof(int) }, null);
                        entry = (PDAScanner.Entry)methodAdd.Invoke(null, new object[] { techType, packet.Unlocked });
                    }

                    if (entry != null)
                    {
                        entry.unlocked++;

                        if (entry.unlocked >= entryData.totalFragments)
                        {
                            List <PDAScanner.Entry> partial  = (List <PDAScanner.Entry>)(typeof(PDAScanner).GetField("partial", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null));
                            HashSet <TechType>      complete = (HashSet <TechType>)(typeof(PDAScanner).GetField("complete", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null));
                            partial.Remove(entry);
                            complete.Add(entry.techType);
                        }
                        else
                        {
                            int totalFragments = entryData.totalFragments;
                            if (totalFragments > 1)
                            {
                                float num2 = (float)entry.unlocked / (float)totalFragments;
                                float arg  = (float)Mathf.RoundToInt(num2 * 100f);
                                ErrorMessage.AddError(Language.main.GetFormat <string, float, int, int>("ScannerInstanceScanned", Language.main.Get(entry.techType.AsString(false)), arg, entry.unlocked, totalFragments));
                            }
                        }
                    }
                }
        }
        public override void Process(PDAEntryProgress packet)
        {
            using (packetSender.Suppress <PDAEntryAdd>())
                using (packetSender.Suppress <PDAEntryProgress>())
                {
                    TechType techType = packet.TechType.ToUnity();

                    if (PDAScanner.GetPartialEntryByKey(techType, out PDAScanner.Entry entry))
                    {
                        if (packet.Unlocked > entry.unlocked)
                        {
                            Log.Info($"PDAEntryProgress Update For TechType:{techType} Old:{entry.unlocked} New:{packet.Unlocked}");
                            entry.unlocked = packet.Unlocked;
                        }
                    }
                    else
                    {
                        Log.Info($"PDAEntryProgress New TechType:{techType} Unlocked:{packet.Unlocked}");
                        methodAdd.Invoke(null, new object[] { techType, packet.Unlocked });
                    }
                }
        }
Exemplo n.º 25
0
 private static void OnConsoleCommand_lock(NotificationCenter.Notification n)
 {
     if (n != null && n.data != null)
     {
         string text = (string)n.data[0];
         if (text == "all")
         {
             List <TechType> list = new List <TechType>(KnownTech.GetTech());
             for (int i = 0; i < list.Count; i++)
             {
                 KnownTech.Remove(list[i]);
             }
             return;
         }
         TechType techType;
         if (UWE.Utils.TryParseEnum <TechType>(text, out techType) && CraftData.IsAllowed(techType))
         {
             bool flag = false | KnownTech.Remove(techType);
             PDAScanner.RemoveAllEntriesWhichUnlocks(techType);
             ErrorMessage.AddDebug("Locked " + Language.main.Get(techType.AsString(false)));
         }
     }
 }
Exemplo n.º 26
0
        private PDAScanner.Result Scan()
        {
            if (stateCurrent != ScanState.None)
            {
                return(PDAScanner.Result.None);
            }
            if (idleTimer > 0f)
            {
                return(PDAScanner.Result.None);
            }

            PDAScanner.Result     result     = PDAScanner.Result.None;
            PDAScanner.ScanTarget scanTarget = PDAScanner.scanTarget;

            if (scanTarget.isValid && energyMixin.charge > 0f)
            {
                result = PDAScanner.Scan();

                if (result == PDAScanner.Result.Scan)
                {
                    float amount = powerConsumption * Time.deltaTime;
                    energyMixin.ConsumeEnergy(amount);
                    stateCurrent = ScanState.Scan;
                }
                else if (result == PDAScanner.Result.Done || result == PDAScanner.Result.Researched)
                {
                    idleTimer = 0.5f;
                    PDASounds.queue.PlayIfFree(completeSound);
                    if (fxControl != null)
                    {
                        fxControl.Play(0);
                    }
                }
            }
            return(result);
        }
Exemplo n.º 27
0
        private static bool Prefix(TechType techType, int num = 1, bool noMessage = false, bool spawnIfCantAdd = true)
        {
            if (techType == TechType.Titanium && num == 2 && !noMessage && spawnIfCantAdd)
            {
                TechType scannedFragment = PDAScanner.scanTarget.techType;
#if !RELEASE
                Logger.Log(Logger.Level.Debug, $"Intercepting scan of fragment {scannedFragment.ToString()}");
#endif

                TechData recipe; // "Variable declaration can be inlined" says Visual Studio, but I'm not sure if it would remain in-scope further down the function if it is.
                if (IngredientsFromScanning.Main.config.TryOverrideRecipe(scannedFragment, out recipe))
                {
#if !RELEASE
                    Logger.Log(Logger.Level.Debug, $"Using OverrideRecipe: {JsonConvert.SerializeObject(recipe, Oculus.Newtonsoft.Json.Formatting.Indented)}");
#endif
                }
                else if ((int)scannedFragment > 1112 && (int)scannedFragment < 1117)
                {
                    // TechTypes 1113 to 1116 are Cyclops fragments, which have no blueprint associated, so we need to process them specially.
                    recipe = new TechData();

                    /*CyclopsHullFragment = 1113,
                     * CyclopsBridgeFragment = 1114,
                     * CyclopsEngineFragment = 1115,
                     * CyclopsDockingBayFragment = 1116,*/

                    switch ((int)scannedFragment)
                    {
                    case 1113:
                        recipe.Ingredients.Add(new Ingredient(TechType.PlasteelIngot, 2));
                        recipe.Ingredients.Add(new Ingredient(TechType.Lead, 1));
                        break;

                    case 1114:
                        recipe.Ingredients.Add(new Ingredient(TechType.EnameledGlass, 3));
                        break;

                    case 1115:
                        recipe.Ingredients.Add(new Ingredient(TechType.Lubricant, 1));
                        recipe.Ingredients.Add(new Ingredient(TechType.AdvancedWiringKit, 1));
                        recipe.Ingredients.Add(new Ingredient(TechType.Lead, 1));
                        break;

                    case 1116:
                        recipe.Ingredients.Add(new Ingredient(TechType.PlasteelIngot, 2));
                        break;
                    }
                    recipe.Ingredients.Add(new Ingredient(TechType.Lead, 1));
                    recipe.Ingredients.Add(new Ingredient(TechType.PlasteelIngot, 1));
#if !RELEASE
                    Logger.Log(Logger.Level.Debug, $"Using recipe from manual override: {JsonConvert.SerializeObject(recipe, Oculus.Newtonsoft.Json.Formatting.Indented)}");
#endif
                }
                else
                {
                    PDAScanner.EntryData entryData = PDAScanner.GetEntryData(scannedFragment);
                    if (entryData == null) // Sanity check; this should always be true
                    {
#if !RELEASE
                        Logger.Log(Logger.Level.Debug, $"Failed to find EntryData for fragment");
#endif

                        /*CraftData.AddToInventory(TechType.Titanium);
                         * CraftData.AddToInventory(TechType.Titanium); // Adding them one-by-one so as to prevent it being caught by this very routine.*/
                        return(true);
                    }
                    //Logger.Log(Logger.Level.Debug, $"Found entryData {entryData.ToString()}");
#if !RELEASE
                    Logger.Log(Logger.Level.Debug, $"Found entryData {JsonConvert.SerializeObject(entryData, Oculus.Newtonsoft.Json.Formatting.Indented)}");
#endif


                    //CraftData.AddToInventory(TechType.Titanium);
                    //CraftData.AddToInventory(TechType.Copper);
                    recipe = CraftDataHandler.GetTechData(entryData.blueprint);
                    if (recipe == null)
                    {
#if !RELEASE
                        Logger.Log(Logger.Level.Debug, $"Failed to find blueprint for EntryData");
#endif

                        /*CraftData.AddToInventory(TechType.Titanium);
                         * CraftData.AddToInventory(TechType.Titanium); // One-by-one again, as above.*/
                        return(true);
                    }
                    //Logger.Log(Logger.Level.Debug, $"Found recipe {recipe.ToString()}");
#if !RELEASE
                    Logger.Log(Logger.Level.Debug, $"Using recipe from EntryData: {JsonConvert.SerializeObject(recipe, Oculus.Newtonsoft.Json.Formatting.Indented)}");
#endif
                }

                for (int i = 0; i < recipe.Ingredients.Count; i++)
                {
                    if (IngredientsFromScanning.Main.config.TrySubstituteIngredient(recipe.Ingredients[i].techType, out List <Ingredient> Substitutes))
                    {
                        foreach (Ingredient sub in Substitutes)
                        {
                            recipe.Ingredients.Add(sub);
                        }
                        recipe.Ingredients.RemoveAt(i); // Remove the current ingredient...
                        i--;                            // ...and make sure the loop continues at the item after this, not the one after that.
                    }
                }

                // I believe the easiest way to get a random item from the blueprint would be to make a list of techTypes; if an ingredient is used twice in the recipe, it will appear in the list twice.
                // That way, we can generate a random number where 0<=rnd<list.count, and select that item.
                List <TechType> bp = new List <TechType> {
                };
                for (int i = 0; i < recipe.Ingredients.Count; i++)
                {
                    for (int j = 0; j < recipe.Ingredients[i].amount; j++)
                    {
                        bp.Add(recipe.Ingredients[i].techType);
                    }
                }

                // Now build up weights
                List <WeightedItem> BlueprintPairs = new List <WeightedItem>();
                float TotalWeight = 0f;
                //Logger.Log(Logger.Level.Error, "Unidentified Vehicle Type!");
                for (int i = 0; i < bp.Count; i++)
                {
                    float thisWeight = IngredientsFromScanning.Main.config.GetWeightForTechType(bp[i]);
                    TotalWeight += thisWeight;
                    WeightedItem thisWeightedItem = new WeightedItem(TotalWeight, bp[i]);
#if !RELEASE
                    Logger.Log(Logger.Level.Debug, $"Adding item to drop list, TechType = {thisWeightedItem.tech.ToString()},   this weight = {thisWeight}, cumulative weight = {thisWeightedItem.Weight}");
#endif
                    BlueprintPairs.Add(thisWeightedItem);
                }

                // Now we should be able to pick a few random numbers between 0 and the list's total weight, and add those. We want to remove that entry afterwards, but that's not a big ask.
                System.Random rng            = new System.Random();
                int           numIngredients = Math.Min(IngredientsFromScanning.Main.config.GenerateGiftValue(), BlueprintPairs.Count);
#if !RELEASE
                Logger.Log(Logger.Level.Debug, $"Generated a value for this scan of {numIngredients} components.");
#endif

                int    awards = 0;
                double r;
                for (int i = 0; i < numIngredients && BlueprintPairs.Count > 0; i++)
                {
                    r = rng.NextDouble() * TotalWeight;
                    for (int j = 0; j < BlueprintPairs.Count; j++)
                    {
                        //                                               This part is for sanity checking
                        //                                   ___________________________|______________________________
                        //                                  /                                                          \
                        if (r < BlueprintPairs[j].Weight || ((j + 1) == BlueprintPairs.Count && awards < numIngredients))
                        {
#if !RELEASE
                            Logger.Log(Logger.Level.Debug, $"With randomised weight of {r}, adding tech {BlueprintPairs[j].tech} to player inventory");
#endif
                            AddInventory(BlueprintPairs[j].tech, 1, false, true);
                            //CraftData.AddToInventory(BlueprintPairs[j].tech, 1, false, true);
                            awards++;
                            TotalWeight -= IngredientsFromScanning.Main.config.GetWeightForTechType(BlueprintPairs[j].tech);
                            BlueprintPairs.RemoveAt(j);
                            break;
                        }
                    }
                }
                return(false);
            }
            return(true);
        }