private static int? GetQuantityToManufacture(Product item, CityStorage storage) { var storageProduct = storage.CurrentInventory.FirstOrDefault(x => x.ProductTypeId == item.ProductTypeId); if (storageProduct == null) return item.Quantity; var newStorage = storageProduct.Quantity - item.Quantity; if (newStorage <= 0) { storageProduct.Quantity = 0; return -1 * newStorage; } storageProduct.Quantity = newStorage; return 0; }
private void AddTopLevelProductToCityStorage(Product updateProduct, CityStorage cityStorage) { if (updateProduct.Quantity == 0) return; var prodType = _productTypes.FirstOrDefault(x => x.Id == updateProduct.ProductTypeId); var currentCityStorageProduct = cityStorage.CurrentInventory.FirstOrDefault(x => x.ProductTypeId == updateProduct.ProductTypeId); if (currentCityStorageProduct == null) return; //Add top level amount currentCityStorageProduct.Quantity += updateProduct.Quantity; if (prodType == null) return; //now subtract the required products it took to create the top level product. for (int i = 0; i < updateProduct.Quantity; i++) { SubtractChildProductsFromCityStorage(prodType.RequiredProducts, cityStorage); } }
private ProductType GetProductType(Product item) { return _productTypes.FirstOrDefault(x => x.Id.Equals(item.ProductTypeId)); }
/// <summary> /// Recurses through required products and calculates the total time required to produce the product /// based on product type duration and quanity of child products required. If city storage /// is specified then the amount in storage is subrtacted from the total durations and the /// quantity of items in storage is decremented to reflect the use of the required products. /// </summary> /// <param name="productType"></param> /// <param name="typesAlreadyAdded"></param> /// <param name="includeRequiredTypes"></param> /// <param name="cityStorage">If included then duration is decreased by what's in storage.</param> /// <param name="productsToUpdate"></param> /// <returns></returns> private int CalculateInventoryItemDurationByType(ProductType productType, ICollection<int> typesAlreadyAdded, bool includeRequiredTypes, CityStorage cityStorage, Product[] productsToUpdate) { // if we have one in storage then we consider the duration already having been elapsed. var cityStorageSpecified = cityStorage != null; var cityStorageDecremented = DecrementCityStorageByProductType(productType, cityStorage); if (cityStorageDecremented) return 0; var productTypeTotalDuration = CalculateTimeToManufacture(productType, typesAlreadyAdded); if (!includeRequiredTypes) return productTypeTotalDuration; foreach (var prod in productsToUpdate) { var productTotalDuration = 0; //product types should always have any product type. var requiredProductType = _productTypes.First(x => x.Id == prod.ProductTypeId); if (prod.RequiredProducts == null) prod.RequiredProducts = requiredProductType.RequiredProducts.Select(x => x.Clone()).ToArray(); for (var a = 0; a < prod.Quantity; a++) { productTotalDuration += CalculateInventoryItemDurationByType(requiredProductType, typesAlreadyAdded, true, cityStorage, prod.RequiredProducts); } //if city storage is not null then set remaining time if (cityStorageSpecified) { if (!prod.RemainingDuration.HasValue) prod.RemainingDuration = 0; prod.RemainingDuration += productTotalDuration; } else { if (!prod.TotalDuration.HasValue) prod.TotalDuration = 0; prod.TotalDuration += productTotalDuration; } productTypeTotalDuration += productTotalDuration; } return productTypeTotalDuration; }
/// <summary> /// Calculates the specified products duration based on the product types duration and quantity. /// </summary> /// <param name="item"></param> /// <param name="parallelTypesAlreadyAdded"></param> /// <param name="includeRequiredProducts"></param> /// <param name="cityStorage"></param> /// <returns></returns> private int CalculateInventoryItemDuration(Product item, ICollection<int> parallelTypesAlreadyAdded, bool includeRequiredProducts, CityStorage cityStorage) { if (item.Quantity < 1) return 0; var productType = GetProductType(item); if (productType == null) return 0; var duration = 0; var quantity = item.Quantity.HasValue ? item.Quantity.Value < 0 ? 0 : item.Quantity.Value : 0; if (item.RequiredProducts == null) item.RequiredProducts = productType.RequiredProducts.Select(x => x.Clone()).ToArray(); for (var a = 0; a < quantity; a++) { duration += CalculateInventoryItemDurationByType(productType, parallelTypesAlreadyAdded, includeRequiredProducts, cityStorage, item.RequiredProducts); } if (cityStorage == null) { item.TotalDuration += duration; } else { item.RemainingDuration += duration; } return duration; }
public void AddRequiredUpgradeItem(Product product) { Products.Add(product); }
private static Product[] PopulateRequiredProducts(ProductType[] productTypes, Product[] products) { foreach (var rp in products) { var pd = productTypes.FirstOrDefault(x => x.Id == rp.ProductTypeId); rp.RequiredProducts = pd != null ? pd.RequiredProducts.ToArray() : new Product[0]; } return products; }
private static Product[] GetProductsAlreadyInStorage(BuildingUpgrade propUpgrade, Product[] currentInventory) { return propUpgrade.Products.Select(prod => currentInventory.FirstOrDefault(x => x.ProductTypeId == prod.ProductTypeId)).Where(strgeProduct => strgeProduct != null).ToArray(); }