示例#1
0
        private static void ApplyIngredientsDepthWise(ComponentCost recipe, Dictionary <string, int> owned, int remainingDepth)
        {
            if (remainingDepth == 0)
            {
                if (owned.ContainsKey(recipe.Record))
                {
                    var numSpent = Math.Min(owned[recipe.Record], recipe.NumRequired);
                    owned[recipe.Record] -= numSpent;
                    recipe.NumOwned       = numSpent;

                    if (numSpent > 0)
                    {
                        ReduceChildrenTotals(recipe, recipe.NumRequired, recipe.NumRequired - numSpent);
                    }
                }
            }
            else if (remainingDepth > 0)
            {
                if (recipe.NumOwned >= recipe.NumRequired)
                {
                    MarkComplete(recipe);
                }
                else
                {
                    foreach (var child in recipe.Cost)
                    {
                        ApplyIngredientsDepthWise(child, owned, remainingDepth - 1);
                    }
                }
            }
        }
示例#2
0
        public void Populate(ComponentCost recipe)
        {
            if (recipe != null)
            {
                ISet <string> recipeRecords = new HashSet <string>();
                GetRecords(recipe, recipeRecords);

                // Fetch player held items
                Dictionary <string, int> storedItems = _playerItemDao.GetCountByRecord(_mod);
                var stashItems = _stashManager.UnlootedItems
                                 .Where(item => recipeRecords.Contains(item.BaseRecord))
                                 .Where(item => item.MateriaCombines == 0 || item.MateriaCombines >= 3) // "Good enough" for now, TODO: Check the DB for the real amount
                                 .ToList();

                // Merge the two lists
                foreach (var item in stashItems)
                {
                    if (storedItems.ContainsKey(item.BaseRecord))
                    {
                        storedItems[item.BaseRecord] += Math.Max(1, (int)item.StackCount);
                    }
                    else
                    {
                        storedItems[item.BaseRecord] = Math.Max(1, (int)item.StackCount);
                    }
                }

                // Apply "already have" items
                for (int depth = 0; depth < 10; depth++)
                {
                    ApplyIngredientsDepthWise(recipe, storedItems, depth);
                }
            }
        }
示例#3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="formulas">Every formula in the database</param>
        /// <param name="components">Every component craftable by a formula</param>
        /// <param name="record"></param>
        /// <param name="numRequired"></param>
        /// <param name="depth">Max search depth to prevent stack overflows etc</param>
        /// <returns>A tree showing the construction costs for the given record</returns>
        private ComponentCost CreateComponent(IList <DatabaseItemDto> formulas, IList <DatabaseItemDto> components, string record, int numRequired, int depth = 0)
        {
            // Obs: if 'item' is null, search the database for it, some items are components without being craftable
            var item = components.FirstOrDefault(m => m.Record == record);

            if (item == null)
            {
                item = _itemDao.FindDtoByRecord(record);
                Logger.Warn($"Component {record} was not preloaded, this may be a performance issue");
                components.Add(item);
            }


            var result = new ComponentCost {
                NumRequired = numRequired,
                Name        = item?.Name,
                Bitmap      = GetBitmap(item?.Stats),
                Cost        = new List <ComponentCost>(),
                Record      = record
            };

            if (_looped.Contains(record) || depth >= 10)
            {
                return(result);
            }



            var recipeStat = formulas.SelectMany(m => m.Stats).FirstOrDefault(m => m.Stat == "artifactName" && m.TextValue == record);


            // For stuff like claws we only crate 1/4, so need the real number required
            // Only do this if this is not the last item in the chain. (makes no sense to list 4x when you obviously need a complete)
            int  costMultiplier  = numRequired;
            var  relicLevel      = item?.Stats.FirstOrDefault(m => m.Stat == "completedRelicLevel");
            bool nonPartialCraft = recipeStat?.Parent.Stats.Any(m => m.Stat == "forcedRelicCompletion") ?? false;

            if (relicLevel != null && !nonPartialCraft)
            {
                costMultiplier *= (int)relicLevel.Value;
            }

            // Calculate costs for this item/component
            var recipe = recipeStat?.Parent;

            foreach (var reagent in _reagents)
            {
                var rcd = (recipe?.Stats)?.FirstOrDefault(m => m.Stat == $"{reagent}BaseName")?.TextValue;
                var qtd = (recipe?.Stats)?.FirstOrDefault(m => m.Stat == $"{reagent}Quantity")?.Value;
                if (rcd != null && qtd.HasValue)
                {
                    result.Cost.Add(CreateComponent(formulas, components, rcd, (int)qtd.Value * costMultiplier, depth + 1));
                }
            }



            return(result);
        }
示例#4
0
 private static void ReduceChildrenTotals(ComponentCost recipe, int original, int newValue)
 {
     foreach (var child in recipe.Cost)
     {
         child.NumRequired = child.NumRequired / original * newValue;
         ReduceChildrenTotals(child, original, newValue);
     }
 }
示例#5
0
 private static void GetRecords(ComponentCost recipe, ISet <string> records)
 {
     records.Add(recipe.Record);
     foreach (var cost in recipe.Cost)
     {
         GetRecords(cost, records);
     }
 }
示例#6
0
 private static void MarkComplete(ComponentCost recipe)
 {
     recipe.IsComplete = true;
     foreach (var child in recipe.Cost)
     {
         MarkComplete(child);
     }
 }