Beispiel #1
0
        private void UpdateGrid()
        {
            if (Recipe.numRecipes != recipeSlots.Count)
            {
                recipeSlots.Clear();
                for (int i = 0; i < Recipe.numRecipes; i++)
                {
                    recipeSlots.Add(new UIRecipeSlot(i));
                }

                tileChooserGrid.Clear();
                var tileUsageCounts = new Dictionary <int, int>();
                int currentCount;
                for (int i = 0; i < Recipe.numRecipes; i++)
                {
                    for (int j = 0; j < 15; j++)
                    {
                        if (Main.recipe[i].requiredTile[j] == -1)
                        {
                            break;
                        }
                        tileUsageCounts.TryGetValue(Main.recipe[i].requiredTile[j], out currentCount);
                        tileUsageCounts[Main.recipe[i].requiredTile[j]] = currentCount + 1;
                    }
                }
                // sort
                var sorted = tileUsageCounts.OrderBy(kvp => kvp.Value);
                foreach (var tileUsage in sorted)
                {
                    var tileSlot = new UITileSlot(tileUsage.Key, tileUsage.Value);
                    tileChooserGrid.Add(tileSlot);
                    tileSlots.Add(tileSlot);
                }
                craftingTiles = tileUsageCounts.Select(x => x.Key).ToList();

                RecipeBrowserUI.instance.UpdateFavoritedPanel();
            }

            if (!RecipeBrowserUI.instance.ShowRecipeBrowser || RecipeBrowserUI.instance.CurrentPanel != RecipeBrowserUI.RecipeCatalogue)
            {
                return;
            }

            if (slowUpdateNeeded > 0)
            {
                slowUpdateNeeded--;
                if (slowUpdateNeeded == 0)
                {
                    updateNeeded = true;
                }
            }

            if (!updateNeeded)
            {
                return;
            }
            updateNeeded     = false;
            slowUpdateNeeded = 0;

            List <int> groups = new List <int>();

            if (queryItem.item.stack > 0)
            {
                int type = queryItem.item.type;

                foreach (var group in RecipeGroup.recipeGroups)
                {
                    if (group.Value.ValidItems.Contains(type))
                    {
                        groups.Add(group.Key);
                    }
                }
            }

            lootSourceGrid.Clear();
            if (queryLootItem != null)
            {
                //var jsonitem = new JSONItem(queryLootItem.modItem?.mod.Name ?? "Terraria", Lang.GetItemNameValue(queryLootItem.type), queryLootItem.modItem != null ? 0 : queryLootItem.type);
                var jsonitem = new JSONItem(queryLootItem.modItem?.mod.Name ?? "Terraria",
                                            queryLootItem.modItem?.Name ?? Lang.GetItemNameValue(queryLootItem.type),
                                            queryLootItem.modItem != null ? 0 : queryLootItem.type);
                List <JSONNPC> npcsthatdropme;
                if (LootCache.instance.lootInfos.TryGetValue(jsonitem, out npcsthatdropme))
                {
                    foreach (var dropper in npcsthatdropme)
                    {
                        int id = dropper.GetID();
                        if (id == 0)
                        {
                            continue;
                        }

                        /*int id = dropper.id;
                         * if (id == 0)
                         * {
                         *      //it's a
                         *      Mod m = ModLoader.GetMod(dropper.mod);
                         *      if (m == null) continue;
                         *      id = m.NPCType(dropper.name);
                         * }*/
                        NPC npc = new NPC();
                        npc.SetDefaults(id);
                        var slot = new UINPCSlot(npc);
                        //lootSourceGrid.Add(slot);
                        lootSourceGrid._items.Add(slot);
                        lootSourceGrid._innerList.Append(slot);
                    }
                }
            }
            lootSourceGrid.UpdateOrder();
            lootSourceGrid._innerList.Recalculate();

            //if (SharedUI.instance.ObtainableFilter.button.selected)
            //{
            //	Main.NewText("Warning, Extended Craftable Filter will cause lag.");
            //}

            recipeGrid.Clear();
            //int craftPathsCalculatedCount = 0;
            for (int i = 0; i < Recipe.numRecipes; i++)
            {
                //if (recipeSlots[i].craftPathsCalculated)
                //	craftPathsCalculatedCount++;
                if (PassRecipeFilters(recipeSlots[i], Main.recipe[i], groups))
                // all the filters
                //if (Main.projName[i].ToLower().IndexOf(searchFilter.Text, StringComparison.OrdinalIgnoreCase) != -1)
                {
                    var box = recipeSlots[i];
                    //
                    if (newestItem > 0)
                    {
                        Recipe recipe = Main.recipe[i];
                        box.recentlyDiscovered = false;
                        if (recipe.requiredItem.Any(x => x.type == newestItem))
                        {
                            box.recentlyDiscovered = true;
                        }
                    }

                    recipeGrid._items.Add(box);
                    recipeGrid._innerList.Append(box);
                }
            }
            //Main.NewText($"craftPathsCalculated: {craftPathsCalculatedCount}/{Recipe.numRecipes}");

            recipeGrid.UpdateOrder();
            recipeGrid._innerList.Recalculate();
        }
Beispiel #2
0
        internal static void Setup(Mod recipeBrowserMod)
        {
            // Save format:

            /*
             * .. hmm, vanilla item drops...do I have to recalculate each time? New Set of mods => complete refresh?
             *
             * RecipeBrowserVersion // So if we add more features we can ignore this file
             * [ of Mod Info
             * -> ModName
             * -> Version
             * -> [ of npc drop info? or item info?
             * -->  Tuple<JSONNPC, LootItem[]> or
             * -->  JSONNPC<T>
             * -->
             * ---> OR
             * --> Item Info
             * ---> ["NPCInfo" with droprate]
             * -->
             * -> ]
             * ]
             *
             * hmm, instead of mod info, just a list of npc? just a list of Item?
             *
             * <Mod, Version>[] --> For knowing which have updated....for now, any update or unaccounted mod, recalculate allll
             * ItemInfo[] JSONNPC and array of JSONNPC that drop it. (forget droprates for now?)
             *
             *
             * item to npc or npc to item....
             */
            string    json;
            string    filename         = "LootCache.json";
            string    folder           = Path.Combine(Main.SavePath, "Mods", "Cache");
            string    path             = Path.Combine(folder, filename);
            LootCache li               = new LootCache();
            bool      needsRecalculate = true;

            LootCacheManagerActive = true;
            List <string> modsThatNeedRecalculate = new List <string>();

            if (File.Exists(path))
            {
                using (StreamReader r = new StreamReader(path))
                {
                    json = r.ReadToEnd();
                    li   = JsonConvert.DeserializeObject <LootCache>(json, new JsonSerializerSettings {
                        Converters = { new Newtonsoft.Json.Converters.VersionConverter() }
                    });
                    needsRecalculate = false;
                }
            }

            // New Recipe Browser version, assume total reset needed (adjust this logic next update.)
            if (li.recipeBrowserVersion != recipeBrowserMod.Version)
            {
                li.lootInfos.Clear();
                li.cachedMods.Clear();
                li.recipeBrowserVersion = recipeBrowserMod.Version;
                needsRecalculate        = true;
            }

            // If we aren't up to date on each mod...
            foreach (var mod in ModLoader.GetLoadedMods())
            {
                if (/*mod == "ModLoader" || */ mod == "RecipeBrowser")
                {
                    continue;
                }
                Mod    m       = ModLoader.GetMod(mod);
                string modName = m.Name == "ModLoader" ? "Terraria" : m.Name;
                if (!li.cachedMods.Any(x => x.Key == modName && x.Value == m.Version))                 // if this mod is either updated or doesn't exist yet
                //if (li.cachedMods.ContainsKey(modName) && li.cachedMods[modName] == m.Version)
                {
                    needsRecalculate = true;
                    // Remove mod from list
                    li.cachedMods.Remove(modName);
                    // Remove items from this mod
                    var toRemove = li.lootInfos.Where(pair => pair.Key.mod == modName)                     // Can't detect if a vanilla npc dropping a vanilla is because of mod. It's fine
                                   .Select(pair => pair.Key)
                                   .ToList();
                    foreach (var key in toRemove)
                    {
                        li.lootInfos.Remove(key);
                    }
                    // Remove npc from items.
                    foreach (var itemToNPCs in li.lootInfos)
                    {
                        itemToNPCs.Value.RemoveAll(x => x.mod == modName);
                    }
                    modsThatNeedRecalculate.Add(modName);
                    li.cachedMods[modName] = m.Version;                     // (new Tuple<string, Version>(modName, m.Version));
                }
            }
            //li.cachedMods.Add(new Tuple<string, Version>(m.Name, m.Version));

            if (needsRecalculate)
            {
                // Temp variables
                float soundVolume = Main.soundVolume;
                Main.soundVolume = 0f;
                if (!Main.dedServ)
                {
                    Reflect();
                }
                setLoadProgressText?.Invoke("Recipe Browser: Rebuilding Loot Cache");
                setLoadProgressProgress?.Invoke(0f);

                // expert drops?
                for (int playernum = 0; playernum < 256; playernum++)
                {
                    Main.player[playernum] = new Player();
                }
                //Main.player[0].active = true;
                int oldMx = Main.maxTilesX;
                Main.maxTilesX = 2100;
                int oldMy = Main.maxTilesY;
                Main.maxTilesY = 600;
                for (int x = 0; x < Main.maxTilesX; x++)
                {
                    for (int y = 0; y < Main.maxTilesY; y++)
                    {
                        Main.tile[x, y]      = new Tile();
                        Main.tile[x, y].type = 0;
                        if (y > Main.maxTilesY * 0.3f)
                        {
                            Main.tile[x, y].active(true);
                        }
                    }
                }
                Main.worldSurface = 200;
                //Main.netMode = 1; // hope this doesn't do anything weird
                NPC  npc  = new NPC();
                Item item = new Item();
                loots = new HashSet <int>();
                string lastMod = "";
                var    watch   = Stopwatch.StartNew();
                var    oldRand = Main.rand;
                if (Main.rand == null)
                {
                    Main.rand = new Terraria.Utilities.UnifiedRandom();
                }

                for (int i = 1; i < NPCLoader.NPCCount; i++)                 // for every npc...
                {
                    npc.SetDefaults(i);
                    npc.value = 0;
                    string currentMod = npc.modNPC?.mod.Name ?? "Terraria";
                    if (!modsThatNeedRecalculate.Contains(currentMod))
                    {
                        continue;
                    }
                    if (lastMod != currentMod)
                    {
                        lastMod = currentMod;
                        setLoadSubProgressText?.Invoke(lastMod);
                    }
                    setLoadProgressProgress?.Invoke((float)i / NPCLoader.NPCCount);
                    JSONNPC jsonNPC = new JSONNPC(npc.modNPC?.mod.Name ?? "Terraria", npc.modNPC?.Name ?? npc.TypeName, npc.modNPC != null ? 0 : i);

                    loots.Clear();
                    CalculateLoot(npc);                      // ...calculate drops

                    foreach (var loot in loots)
                    {
                        if (ignoreItemIDS.Contains(loot))
                        {
                            continue;
                        }

                        item.SetDefaults(loot, true);

                        //JSONItem jsonitem = new JSONItem(item.modItem?.mod.Name ?? "Terraria", Lang.GetItemNameValue(loot), item.modItem != null ? 0 : loot);
                        JSONItem       jsonitem = new JSONItem(item.modItem?.mod.Name ?? "Terraria", item.modItem?.Name ?? Lang.GetItemNameValue(loot), item.modItem != null ? 0 : loot);
                        List <JSONNPC> npcsthatdropme;
                        if (!li.lootInfos.TryGetValue(jsonitem, out npcsthatdropme))
                        {
                            li.lootInfos.Add(jsonitem, npcsthatdropme = new List <JSONNPC>());
                        }
                        npcsthatdropme.Add(jsonNPC);
                    }
                }
                loots.Clear();
                // Reset temp values
                Main.rand = oldRand;                 // value 8 seconds.  // don't value to 0 and ignore.contains: 5 seconds.
                // value to 0, contains, 4 seconds.   .6 seconds without contains.
                Main.maxTilesX   = oldMx;
                Main.maxTilesY   = oldMy;
                Main.soundVolume = soundVolume;

                // Save json:
                watch.Stop();
                var elapsedMs = watch.ElapsedMilliseconds;
                //li.iterations = MaxNumberLootExperiments;
                li.lastUpdateTime = elapsedMs;
                Directory.CreateDirectory(folder);
                json = JsonConvert.SerializeObject(li, Formatting.Indented, new JsonSerializerSettings {
                    Converters = { new Newtonsoft.Json.Converters.VersionConverter() }
                });
                File.WriteAllText(path, json);

                // Reset Load Mods Progress bar
                setLoadSubProgressText?.Invoke("");
                setLoadProgressText?.Invoke("Adding Recipes");
                setLoadProgressProgress?.Invoke(0f);
            }
            LootCacheManagerActive = false;
            LootCache.instance     = li;
        }