Index: binaries/data/mods/public/gui/session/selection_panels.js =================================================================== --- binaries/data/mods/public/gui/session/selection_panels.js +++ binaries/data/mods/public/gui/session/selection_panels.js @@ -509,6 +509,16 @@ foundNew = true; } } + if (unitEntStates.length === 1 && unitEntStates[0].production.autoqueue) + { + const og_length = queue.length; + if (og_length) + for (let i = 0; i + og_length < g_SelectionPanels.Queue.getMaxNumberOfItems(); ++i) + { + queue.push(clone(queue[i % og_length])); + queue[queue.length-1].ghost = true; + } + } return queue; }, "resizePanel": function(numberOfItems, rowLength) @@ -536,10 +546,11 @@ warning("Unknown production queue template " + uneval(queuedItem)); return false; } - data.button.onPress = function() { removeFromProductionQueue(data.item.producingEnt, queuedItem.id); }; const tooltips = [getEntityNames(template)]; + if (data.item.ghost) + tooltips.push(translate("Will be autoqueued later if resources are available.")); if (queuedItem.neededSlots) { tooltips.push(coloredText(translate("Insufficient population capacity:"), "red")); @@ -553,22 +564,32 @@ data.countDisplay.caption = queuedItem.count > 1 ? queuedItem.count : ""; - // Show the time remaining to finish the first item - if (data.i == 0) - Engine.GetGUIObjectByName("queueTimeRemaining").caption = - Engine.FormatMillisecondsIntoDateStringGMT(queuedItem.timeRemaining, translateWithContext("countdown format", "m:ss")); + if (data.item.ghost) + { + data.button.enabled = false; + Engine.GetGUIObjectByName("unitQueueProgressSlider[" + data.i + "]").sprite="color:0 150 250 50"; + } + else + { + // Show the time remaining to finish the first item + if (data.i == 0) + Engine.GetGUIObjectByName("queueTimeRemaining").caption = + Engine.FormatMillisecondsIntoDateStringGMT(queuedItem.timeRemaining, translateWithContext("countdown format", "m:ss")); - let guiObject = Engine.GetGUIObjectByName("unitQueueProgressSlider[" + data.i + "]"); - let size = guiObject.size; + const guiObject = Engine.GetGUIObjectByName("unitQueueProgressSlider[" + data.i + "]"); + guiObject.sprite = "queueProgressSlider"; + const size = guiObject.size; - // Buttons are assumed to be square, so left/right offsets can be used for top/bottom. - size.top = size.left + Math.round(queuedItem.progress * (size.right - size.left)); - guiObject.size = size; + // Buttons are assumed to be square, so left/right offsets can be used for top/bottom. + size.top = size.left + Math.round(queuedItem.progress * (size.right - size.left)); + guiObject.size = size; + + data.button.enabled = controlsPlayer(data.player); + } if (template.icon) - data.icon.sprite = "stretched:session/portraits/" + template.icon; + data.icon.sprite = (data.item.ghost ? "grayscale:" : "") + "stretched:session/portraits/" + template.icon; - data.button.enabled = controlsPlayer(data.player); const showTemplateFunc = () => { showTemplateDetails(data.item.queuedItem.unitTemplate || data.item.queuedItem.technologyTemplate, data.playerState.civ); }; data.button.onPressRight = showTemplateFunc; Index: binaries/data/mods/public/simulation/components/ProductionQueue.js =================================================================== --- binaries/data/mods/public/simulation/components/ProductionQueue.js +++ binaries/data/mods/public/simulation/components/ProductionQueue.js @@ -806,12 +806,6 @@ cmpPlayer.UnBlockTraining(); - // AutoQueue: We add the second batch after starting the first. - // (As opposed to when the first batch finishes.) - // This is to make the feature not infinitely better than good micro. - if (this.autoqueuing) - this.AddItem(item.unitTemplate, "unit", item.count, item.metadata); - Engine.PostMessage(this.entity, MT_TrainingStarted, { "entity": this.entity }); } if (item.technologyTemplate) @@ -844,6 +838,18 @@ { cmpPlayer.UnBlockTraining(); delete this.spawnNotified; + + if (this.autoqueuing) + if (!this.AddItem(item.unitTemplate, "unit", item.count, item.metadata)) + { + this.DisableAutoQueue(); + const cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); + cmpGUIInterface.PushNotification({ + "players": [cmpPlayer.GetPlayerID()], + "message": markForTranslation("Could not autoqueue unit, de-activating."), + "translateMessage": true + }); + } } else {