private void ProcessQueueItems(int timeDelta) { // Prevent refreshing of queue. m_processingLock = true; if (Sync.IsServer) { while (!IsQueueEmpty && timeDelta > 0) { var wrappedItem = TryGetFirstQueueItem(); Debug.Assert(wrappedItem.HasValue); QueueItem queueItem = wrappedItem.Value; // Compute how much blueprints could be processed in remaining time. MyFixedPoint blueprintsProcessed = (MyFixedPoint)((timeDelta * (m_refineryDef.RefineSpeed + UpgradeValues["Productivity"]) * MySession.Static.RefinerySpeedMultiplier) / (queueItem.Blueprint.BaseProductionTimeInSeconds * 1000)); // Fix that number according to how much items are in the inventory foreach (var prerequisite in queueItem.Blueprint.Prerequisites) { MyFixedPoint oreAvailable = InputInventory.GetItemAmount(prerequisite.Id); MyFixedPoint oreProcessed = blueprintsProcessed * prerequisite.Amount; if (oreAvailable < oreProcessed) { blueprintsProcessed = oreAvailable * (1f / (float)prerequisite.Amount); } } //GR: This assertion happens on last item to be removed when allowing duplicate blueprints. The queue is emptied but with small delay. Synchronization needed? //Debug.Assert(blueprintsProcessed > 0, "No items in inventory but there are blueprints in the queue!"); if (blueprintsProcessed == 0) { //GR: For now comment out bcause it spams the log on servers on occasions //MySandboxGame.Log.WriteLine("MyRefinery.ProcessQueueItems: Inventory empty while there are still blueprints in the queue!"); m_queueNeedsRebuild = true; break; } // Math.Max has to be here to avoid situations in which timeDelta wouldn't change at all. // Basically, this means that the refinery cannot spend less time processing items than 1ms, which is OK, I guess timeDelta = timeDelta - System.Math.Max(1, (int)((float)blueprintsProcessed * queueItem.Blueprint.BaseProductionTimeInSeconds / m_refineryDef.RefineSpeed * 1000)); if (timeDelta < 0) { timeDelta = 0; } ChangeRequirementsToResults(queueItem.Blueprint, blueprintsProcessed); } } IsProducing = !IsQueueEmpty; m_processingLock = false; }
public override void UpdateBeforeSimulation100() { base.UpdateBeforeSimulation100(); if (m_inventoryOwnersDirty) { GetCoveyorInventoryOwners(); } if (Sync.IsServer && IsWorking && m_useConveyorSystem) { if (DisassembleEnabled) // Dissasembling { if (OutputInventory.VolumeFillFactor < 0.99f) { //MyGridConveyorSystem.PullAllRequest(this, OutputInventory, OwnerId, OutputInventory.Constraint); var item = TryGetFirstQueueItem(); if (item != null) { if (!OutputInventory.ContainItems(null, item.Value.Blueprint.Results[0].Id)) { MyGridConveyorSystem.ItemPullRequest(this, OutputInventory, OwnerId, item.Value.Blueprint.Results[0].Id, item.Value.Amount); } } } if (InputInventory.VolumeFillFactor > 0.75f) { Debug.Assert(InputInventory.GetItems().Count > 0); MyGridConveyorSystem.PushAnyRequest(this, InputInventory, OwnerId); } } else // Assembling { if (IsSlave && m_queue.Count < 1 && MyFakes.ENABLE_ASSEMBLER_COOPERATION && !RepeatEnabled) { GetItemFromOtherAssemblers(); } if (InputInventory.VolumeFillFactor < 0.99f) { var next = false; int i = 0; var time = 0f; do { var item = TryGetQueueItem(i); if (item.HasValue) { var factor = MySession.Static.AssemblerSpeedMultiplier / MySession.Static.AssemblerEfficiencyMultiplier; var itemAmount = 1; var remainingTime = TIME_IN_ADVANCE - time; if (item.Value.Blueprint.BaseProductionTimeInSeconds < remainingTime) { itemAmount = Math.Min((int)item.Value.Amount, Convert.ToInt32(Math.Floor(remainingTime / (item.Value.Blueprint.BaseProductionTimeInSeconds / factor)))); time += itemAmount * item.Value.Blueprint.BaseProductionTimeInSeconds / MySession.Static.AssemblerSpeedMultiplier; if (time < TIME_IN_ADVANCE) { next = true; } } foreach (var component in item.Value.Blueprint.Prerequisites) { var availableAmount = InputInventory.GetItemAmount(component.Id); if (i > 0) { availableAmount = 0; } var neededAmount = component.Amount * itemAmount - availableAmount; if (neededAmount <= 0) { continue; } MyGridConveyorSystem.ItemPullRequest(this, InputInventory, OwnerId, component.Id, neededAmount); } } if (i > 0) { next = false; } i++; } while (next); } if (OutputInventory.VolumeFillFactor > 0.75f) { Debug.Assert(OutputInventory.GetItems().Count > 0); MyGridConveyorSystem.PushAnyRequest(this, OutputInventory, OwnerId); } } } }
public override void UpdateBeforeSimulation100() { base.UpdateBeforeSimulation100(); if (m_inventoryOwnersDirty) { GetCoveyorInventoryOwners(); } if (Sync.IsServer && IsWorking && m_useConveyorSystem) { if (DisassembleEnabled) // Dissasembling { if (OutputInventory.VolumeFillFactor < 0.99f) { //MyGridConveyorSystem.PullAllRequest(this, OutputInventory, OwnerId, OutputInventory.Constraint); var item = TryGetFirstQueueItem(); if (item != null) { if (!OutputInventory.ContainItems(null, item.Value.Blueprint.Results[0].Id)) { MyGridConveyorSystem.ItemPullRequest(this, OutputInventory, OwnerId, item.Value.Blueprint.Results[0].Id, item.Value.Amount); } } } if (InputInventory.VolumeFillFactor > 0.75f) { Debug.Assert(InputInventory.GetItems().Count > 0); MyGridConveyorSystem.PushAnyRequest(this, InputInventory, OwnerId); } } else // Assembling { //if (IsSlave && m_queue.Count < 1 && MyFakes.ENABLE_ASSEMBLER_COOPERATION && !RepeatEnabled) //{ // GetItemFromOtherAssemblers(TIME_IN_ADVANCE); //} if (InputInventory.VolumeFillFactor < 0.99f) { m_requiredComponents.Clear(); var next = false; int i = 0; var time = 0f; do { var item = TryGetQueueItem(i); var remainingTime = TIME_IN_ADVANCE - time; if (item.HasValue) { var productivity = (((MyAssemblerDefinition)BlockDefinition).AssemblySpeed + UpgradeValues["Productivity"]); var factor = MySession.Static.AssemblerSpeedMultiplier * productivity; var itemAmount = 1; if (item.Value.Blueprint.BaseProductionTimeInSeconds / factor < remainingTime) { itemAmount = Math.Min((int)item.Value.Amount, Convert.ToInt32(Math.Ceiling(remainingTime / (item.Value.Blueprint.BaseProductionTimeInSeconds / factor)))); } time += itemAmount * item.Value.Blueprint.BaseProductionTimeInSeconds / factor; if (time < TIME_IN_ADVANCE) { next = true; } var amountMult = (MyFixedPoint)(1.0f / MySession.Static.AssemblerEfficiencyMultiplier); foreach (var component in item.Value.Blueprint.Prerequisites) { var requiredAmount = component.Amount * itemAmount * amountMult; bool found = false; for (int j = 0; j < m_requiredComponents.Count; j++) { if (m_requiredComponents[j].Id == component.Id) { m_requiredComponents[j] = new MyBlueprintDefinitionBase.Item { Amount = m_requiredComponents[j].Amount + requiredAmount, Id = component.Id }; found = true; break; } } if (!found) { m_requiredComponents.Add(new MyBlueprintDefinitionBase.Item { Amount = requiredAmount, Id = component.Id }); } } } i++; if (i >= m_queue.Count) { next = false; } } while (next); foreach (var component in m_requiredComponents) { var availableAmount = InputInventory.GetItemAmount(component.Id); var neededAmount = component.Amount - availableAmount; if (neededAmount <= 0) { continue; } MyGridConveyorSystem.ItemPullRequest(this, InputInventory, OwnerId, component.Id, neededAmount); } if (IsSlave && !RepeatEnabled) { var remainingTime = TIME_IN_ADVANCE - time; if (remainingTime > 0) { GetItemFromOtherAssemblers(remainingTime); } } } if (OutputInventory.VolumeFillFactor > 0.75f) { Debug.Assert(OutputInventory.GetItems().Count > 0); MyGridConveyorSystem.PushAnyRequest(this, OutputInventory, OwnerId); } } } }