public bool TrySelectIngot(ItemType ingotType, out IRefineryIterator iterator) { if (!iterators.TryGetValue(ingotType, out iterator)) { return(false); } return(iterator.CanAllocate()); }
/// <summary> /// Provide the specified refinery with enough work to keep it busy until the next iteration. /// </summary> /// <remarks> /// Ore already being processed is not considered when estimating how many ingots will be produced. /// This is because we already have at least one interval of lag in adjusting to new requests anyway /// and the amount of ore in flight should be insignificant in comparison (approx. one /// 'IntervalOverlapSeconds'); it's not worth the hassle to calculate it. /// </remarks> private bool FillCurrentRefinery(IngotWorklist ingotWorklist, IRefineryIterator worklist) { var assignedWork = false; // How much work does this refinery need to keep it busy until the next iteration, with a safety margin? Debug.Assert(worklist.PreferredWorkSeconds > 0, "PreferredWorkSeconds <= 0"); // Get candidate blueprints in priority order. var candidates = worklist.GetCandidateBlueprints().OrderByDescending(ingotWorklist.ScoreBlueprint).ToArray(); for (var i = 0; i < candidates.Length; i++) { var blueprint = candidates[i]; var workProvidedSeconds = TryFillRefinery(worklist.Current, blueprint, worklist.PreferredWorkSeconds); if (workProvidedSeconds <= 0) { Debug.Write(Debug.Level.All, new Message("Unable to allocate any {0}, moving to next candidate.", blueprint.Input.ItemType.SubtypeId)); continue; } assignedWork = true; var isRefinerySatisfied = worklist.AssignedWork(ref workProvidedSeconds); if (workProvidedSeconds > 0) { Debug.Write(Debug.Level.Debug, new Message("Provided {0} seconds of work using {1}.", workProvidedSeconds, blueprint.Name)); // Some of the new work will be processed before next iteration. Update our estimates. ingotWorklist.UpdateStockpileEstimates(worklist.Current, blueprint, workProvidedSeconds); } // If the refinery's work target is satisfied, it should not run dry before we run again. if (isRefinerySatisfied) { break; } } // No more ore available for this refinery. worklist.Next(); return(assignedWork); }