Beispiel #1
0
        void BuildEndGameEquipment(EquipmentJobRank[] scoredJobEquipment, JobData jobData, Saint.ClassJob sJob, bool isCombatJob)
        {
            // We only want endgame equipment for jobs, not starting classes.
            // Filter out DoW/M classes that don't have a parent.
            // Everything before the Heavensward classless jobs.
            if (sJob.Key < 31 && isCombatJob && sJob.ParentClassJob == sJob)
            {
                return;
            }

            // EndGame equipment is simply grouped by slot and ordered.
            var endGameJobEquipmentList = new JObject();

            _builder.Db.EndGameEquipmentByJob[sJob.Abbreviation] = endGameJobEquipmentList;

            var endGameEquipmentBySlot = scoredJobEquipment
                                         // Go back 10 levels for non-combat jobs, so Lv. 60 shows prior Lv. 50 gear for comparison.
                                         .Where(e => e.EquipmentLevel >= jobData.MaxLevel - (isCombatJob ? 0 : 10))
                                         .GroupBy(e => e.Slot);

            foreach (var endGameSlot in endGameEquipmentBySlot)
            {
                // Sort results in this slot.
                EquipmentJobRank[] orderedResults;
                if (isCombatJob)
                {
                    orderedResults = endGameSlot.OrderByDescending(e => e.Equipment.ItemLevel.Key).ThenByDescending(e => e.Equipment.Key).ToArray();
                }
                else
                {
                    orderedResults = endGameSlot.OrderByDescending(e => e.Rank.Score).ToArray();
                }

                // Skip slots that don't have a single piece at cap. (WHM wands and shields)
                if (orderedResults.Max(e => e.EquipmentLevel) < jobData.MaxLevel)
                {
                    continue;
                }

                // Add references to top results.
                var topResults = orderedResults.Take(9).ToArray();
                foreach (var result in topResults)
                {
                    _builder.Db.AddReference(endGameJobEquipmentList, "item", result.Equipment.Key, false);
                }

                // Store them in the list.
                var results = topResults
                              .Select(e => new JObject(new JProperty("id", e.Equipment.Key)))
                              .ToArray();

                endGameJobEquipmentList[endGameSlot.Key.Key.ToString()] = new JArray(results);

                // Don't predict progression on combat jobs.
                if (isCombatJob)
                {
                    continue;
                }

                // Record end-game progression on DoH/DoL jobs.
                dynamic previousItem  = null;
                double  previousScore = 0;
                foreach (var e in orderedResults.Take(9).Reverse())
                {
                    if (e.Rank.Score == previousScore)
                    {
                        continue;
                    }

                    var item = _builder.Db.ItemsById[e.Equipment.Key];
                    _builder.UpgradeItem(previousItem, item);
                    previousItem  = item;
                    previousScore = e.Rank.Score;
                }
            }
        }
Beispiel #2
0
        void BuildLevelingEquipment(EquipmentJobRank[] scoredJobEquipment, JobData jobData, Saint.ClassJob sJob)
        {
            var levelingJobEquipmentArray = new JArray();

            _builder.Db.LevelingEquipmentByJob[sJob.Abbreviation] = levelingJobEquipmentArray;
            Dictionary <Saint.EquipSlotCategory, List <EquipmentJobRank> > previousLevelingItems = null;

            // Find the best crafted equipment from 1-max that isn't a star recipe.
            for (var elvl = 1; elvl < jobData.MaxLevel; elvl++)
            {
                var currentLevelingItems = new Dictionary <Saint.EquipSlotCategory, List <EquipmentJobRank> >();

                var relevantEquipment = scoredJobEquipment
                                        .Where(e => e.HasCraftingRecipe || e.HasGcVendor || e.HasGilVendor)
                                        .Where(e => e.EquipmentLevel <= elvl)
                                        .Where(e => e.Item.achievements == null)                                           // No achievement gear.
                                        .Where(e => e.Vendors == null || !e.Vendors.Select(t => (int)t).Contains(1006004)) // No calamity salvager gear.
                                        .GroupBy(e => e.Slot);

                var equipmentLevelSlots = new JObject();
                foreach (var scoresBySlot in relevantEquipment)
                {
                    // Use the base score without melds because max overmelding on leveling equ is unrealistic.
                    var orderedEquipment = scoresBySlot
                                           .OrderByDescending(s => s.Rank.BaseScore)
                                           .ThenBy(s => s.Equipment.Key)
                                           .ToArray();

                    // Find the highest scores in 3 categories:
                    // 1. With a crafting recipe.
                    // 2. From the GC vendor.
                    // 3. From a regular vendor.
                    var currentList = new List <EquipmentJobRank>();

                    var highestCrafted = orderedEquipment.FirstOrDefault(s => s.HasCraftingRecipe);
                    if (highestCrafted != null)
                    {
                        currentList.Add(highestCrafted);
                    }

                    var highestGc  = orderedEquipment.FirstOrDefault(s => s.HasGcVendor);
                    var highestGil = orderedEquipment.FirstOrDefault(s => s.HasGilVendor);

                    // Ignore GC gear if gil shop gear is better.
                    if (highestGc != null && highestGil != null && highestGil.Rank.BaseScore > highestGc.Rank.BaseScore)
                    {
                        highestGc = null;
                    }

                    if (highestGc != null)
                    {
                        currentList.Add(highestGc);
                    }

                    if (highestGil != null)
                    {
                        currentList.Add(highestGil);
                    }

                    // No equipment - probably nothing available for this slot at this level.
                    if (currentList.Count == 0)
                    {
                        continue;
                    }

                    currentLevelingItems[scoresBySlot.Key] = currentList;

                    var records = new JArray();
                    foreach (var item in currentList.Distinct().OrderByDescending(i => i.Rank.BaseScore))
                    {
                        dynamic record = new JObject();
                        record.id = item.Equipment.Key;
                        if (item.HasCraftingRecipe)
                        {
                            record.craft = 1;
                        }
                        if (item.HasGcVendor)
                        {
                            record.gc = 1;
                        }
                        if (item.HasGilVendor)
                        {
                            record.gil = 1;
                        }
                        records.Add(record);
                        _builder.Db.AddReference(levelingJobEquipmentArray, "item", item.Equipment.Key, false);
                    }
                    equipmentLevelSlots[scoresBySlot.Key.Key.ToString()] = records;
                }
                levelingJobEquipmentArray.Add(equipmentLevelSlots);

                // Link upgrades
                if (previousLevelingItems != null)
                {
                    foreach (var pair in currentLevelingItems)
                    {
                        if (!previousLevelingItems.TryGetValue(pair.Key, out var previousEquipment))
                        {
                            continue;
                        }

                        foreach (var previousItem in previousEquipment)
                        {
                            foreach (var currentItem in pair.Value)
                            {
                                // Skip identical equipment levels.  The tool covers horizontal upgrades.
                                if (currentItem.EquipmentLevel == previousItem.EquipmentLevel)
                                {
                                    continue;
                                }

                                // List all classes of upgrade, regardless of type.
                                if (currentItem.Rank.BaseScore > previousItem.Rank.BaseScore)
                                {
                                    _builder.UpgradeItem(previousItem.Item, currentItem.Item);
                                }
                            }
                        }
                    }
                }

                previousLevelingItems = currentLevelingItems;
            }
        }