/// <summary> /// Based on the current situation, the bot needs to get an item, but doesn't have it. /// This function reserves the item the pod should pick up. Returns the pod that should be used, null if it's carying a pod and the current pod won't work (too full). /// </summary> /// <param name="bot">The bot to consider.</param> /// <param name="bestRequest">The best request to use for the best pickup task.</param> /// <param name="bestStation">The station to use for the best pickup task.</param> /// <param name="bestPod">The pod to use for the best pickup task.</param> public void ReserveBestItemToPickUp(Bot bot, out InsertRequest bestRequest, out Pod bestPod, out InputStation bestStation) { bestPod = null; bestStation = null; bestRequest = null; // If have a pod currently if (bot.Pod != null) { Pod pod = bot.Pod; // Current pod works, so find closest input station and best task double closestInputStationTime = double.PositiveInfinity; // Check all tasks foreach (var storeTask in Instance.ResourceManager.AvailableStoreRequests) { // See how long it would take to get to this input station // Choose the worst of delivering or waiting Waypoint sw = storeTask.Station.Waypoint; double time = Math.Max(Estimators.EstimateTravelTimeEuclid(bot, bot.CurrentWaypoint, sw), Estimators.EstimateInputStationWaitTime(bot, sw)); // If it's the best and it fits the current pod, then use it if (time < closestInputStationTime && pod.CapacityInUse + storeTask.Bundle.BundleWeight <= pod.Capacity) { bestRequest = storeTask; closestInputStationTime = time; } } // If no pickup suits the pod, get rid of it if (bestRequest == null) { return; } // Allocate task! bestStation = bestRequest.Station; bestPod = pod; } // Don't have a pod double bestPickupTime = double.PositiveInfinity; bestRequest = null; bestPod = null; foreach (var pod in Instance.ResourceManager.UnusedPods) { // Find time to pick up the bundle double pickupTime = Estimators.EstimateTravelTimeEuclid(bot, pod.Waypoint); // Check all tasks foreach (var storeTask in Instance.ResourceManager.AvailableStoreRequests) { // If it has room if (pod.CapacityInUse + storeTask.Bundle.BundleWeight <= pod.Capacity) { // See how long it would take to get to this input station // Choose the worst of delivering or waiting Waypoint sw = storeTask.Station.Waypoint; double deliverTime = Math.Max(Estimators.EstimateTravelTimeEuclid(bot, pod.Waypoint, sw), Estimators.EstimateInputStationWaitTime(bot, sw)); //if it's the best, then use it if (pickupTime + deliverTime < bestPickupTime) { bestRequest = storeTask; bestPickupTime = pickupTime + deliverTime; bestPod = pod; } } } } // No pickup request available if (bestRequest == null) { return; } // Pickup available - set it bestStation = bestRequest.Station; }