Index: ps/trunk/binaries/data/mods/public/gui/credits/texts/programming.json
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/credits/texts/programming.json
+++ ps/trunk/binaries/data/mods/public/gui/credits/texts/programming.json
@@ -36,6 +36,7 @@
{ "nick": "Arfrever", "name": "Arfrever Frehtes Taifersar Arahesis" },
{ "nick": "ArnH", "name": "Arno Hemelhof" },
{ "nick": "Aurium", "name": "Aurélio Heckert" },
+ { "nick": "azayrahmad", "name": "Aziz Rahmad" },
{ "nick": "badmadblacksad", "name": "Martin F" },
{ "nick": "badosu", "name": "Amadeus Folego" },
{ "nick": "bb", "name": "Bouke Jansen" },
Index: ps/trunk/binaries/data/mods/public/gui/hotkeys/spec/ingame.json
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/hotkeys/spec/ingame.json
+++ ps/trunk/binaries/data/mods/public/gui/hotkeys/spec/ingame.json
@@ -158,6 +158,14 @@
"session.queueunit.8": {
"name": "Queue 8th unit",
"desc": "Add eighth unit type to queue."
+ },
+ "session.queueunit.autoqueueon": {
+ "name": "Activate auto-queue",
+ "desc": "Turn on Auto-Queue for selected structures."
+ },
+ "session.queueunit.autoqueueoff": {
+ "name": "Deactivate auto-queue",
+ "desc": "Turn off Auto-Queue for selected structures."
}
}
}
Index: ps/trunk/binaries/data/mods/public/gui/session/hotkeys/training.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/session/hotkeys/training.xml
+++ ps/trunk/binaries/data/mods/public/gui/session/hotkeys/training.xml
@@ -34,4 +34,14 @@
+
+
+
+
+
+
Index: ps/trunk/binaries/data/mods/public/gui/session/selection_panels_helpers.js
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/session/selection_panels_helpers.js
+++ ps/trunk/binaries/data/mods/public/gui/session/selection_panels_helpers.js
@@ -546,3 +546,25 @@
})
});
}
+
+function turnAutoQueueOn()
+{
+ Engine.PostNetworkCommand({
+ "type": "autoqueue-on",
+ "entities": g_Selection.toList().filter(ent => {
+ let state = GetEntityState(ent);
+ return state && !!state.production.entities;
+ })
+ });
+}
+
+function turnAutoQueueOff()
+{
+ Engine.PostNetworkCommand({
+ "type": "autoqueue-off",
+ "entities": g_Selection.toList().filter(ent => {
+ let state = GetEntityState(ent);
+ return state && !!state.production.entities;
+ })
+ });
+}
Index: ps/trunk/binaries/data/mods/public/gui/session/unit_actions.js
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/session/unit_actions.js
+++ ps/trunk/binaries/data/mods/public/gui/session/unit_actions.js
@@ -1715,7 +1715,47 @@
// This command button is always disabled.
},
"allowedPlayers": ["Ally", "Observer"]
- }
+ },
+
+ "autoqueue-on": {
+ "getInfo": function(entStates)
+ {
+ if (entStates.every(entState => !entState.production || !entState.production.entities || entState.production.autoqueue))
+ return false;
+ return {
+ "tooltip": colorizeHotkey("%(hotkey)s" + " ", "session.queueunit.autoqueueon") +
+ translate("Activate auto-queue for selected structures."),
+ "icon": "autoqueue-on.png",
+ "enabled": true
+ };
+ },
+ "execute": function(entStates)
+ {
+ if (entStates.length)
+ turnAutoQueueOn();
+ },
+ "allowedPlayers": ["Player"]
+ },
+
+ "autoqueue-off": {
+ "getInfo": function(entStates)
+ {
+ if (entStates.every(entState => !entState.production || !entState.production.entities || !entState.production.autoqueue))
+ return false;
+ return {
+ "tooltip": colorizeHotkey("%(hotkey)s" + " ", "session.queueunit.autoqueueoff") +
+ translate("Deactivate auto-queue for selected structures."),
+ "icon": "autoqueue-off.png",
+ "enabled": true
+ };
+ },
+ "execute": function(entStates)
+ {
+ if (entStates.length)
+ turnAutoQueueOff();
+ },
+ "allowedPlayers": ["Player"]
+ },
};
function playerCheck(entState, targetState, validPlayers)
Index: ps/trunk/binaries/data/mods/public/simulation/components/GuiInterface.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/components/GuiInterface.js
+++ ps/trunk/binaries/data/mods/public/simulation/components/GuiInterface.js
@@ -344,7 +344,8 @@
"entities": cmpProductionQueue.GetEntitiesList(),
"technologies": cmpProductionQueue.GetTechnologiesList(),
"techCostMultiplier": cmpProductionQueue.GetTechCostMultiplier(),
- "queue": cmpProductionQueue.GetQueue()
+ "queue": cmpProductionQueue.GetQueue(),
+ "autoqueue": cmpProductionQueue.IsAutoQueueing()
};
let cmpTrader = Engine.QueryInterface(ent, IID_Trader);
Index: ps/trunk/binaries/data/mods/public/simulation/components/ProductionQueue.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/components/ProductionQueue.js
+++ ps/trunk/binaries/data/mods/public/simulation/components/ProductionQueue.js
@@ -74,6 +74,30 @@
};
/**
+ * @return {boolean} - Whether we are automatically queuing items.
+ */
+ProductionQueue.prototype.IsAutoQueueing = function()
+{
+ return !!this.autoqueuing;
+};
+
+/**
+ * Turn on Auto-Queue.
+ */
+ProductionQueue.prototype.EnableAutoQueue = function()
+{
+ this.autoqueuing = true;
+};
+
+/**
+ * Turn off Auto-Queue.
+ */
+ProductionQueue.prototype.DisableAutoQueue = function()
+{
+ delete this.autoqueuing;
+};
+
+/**
* Calculate the new list of producible entities
* and update any entities currently being produced.
*/
@@ -781,6 +805,13 @@
this.SetAnimation("training");
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)
Index: ps/trunk/binaries/data/mods/public/simulation/components/tests/test_ProductionQueue.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/components/tests/test_ProductionQueue.js
+++ ps/trunk/binaries/data/mods/public/simulation/components/tests/test_ProductionQueue.js
@@ -545,8 +545,81 @@
TS_ASSERT_EQUALS(cmpProductionQueue.GetQueue().length, 1);
}
+function test_auto_queue()
+{
+ let playerEnt = 2;
+ let playerID = 1;
+ let testEntity = 3;
+
+ ConstructComponent(playerEnt, "EntityLimits", {
+ "Limits": {
+ "some_limit": 8
+ },
+ "LimitChangers": {},
+ "LimitRemovers": {}
+ });
+
+ AddMock(SYSTEM_ENTITY, IID_GuiInterface, {
+ "PushNotification": () => {}
+ });
+
+ AddMock(SYSTEM_ENTITY, IID_Trigger, {
+ "CallEvent": () => {}
+ });
+
+ AddMock(SYSTEM_ENTITY, IID_Timer, {
+ "SetInterval": (ent, iid, func) => 1
+ });
+
+ AddMock(SYSTEM_ENTITY, IID_TemplateManager, {
+ "TemplateExists": () => true,
+ "GetTemplate": name => ({
+ "Cost": {
+ "BuildTime": 0,
+ "Population": 1,
+ "Resources": {}
+ },
+ "TrainingRestrictions": {
+ "Category": "some_limit"
+ }
+ })
+ });
+
+ AddMock(SYSTEM_ENTITY, IID_PlayerManager, {
+ "GetPlayerByID": id => playerEnt
+ });
+
+ AddMock(playerEnt, IID_Player, {
+ "GetCiv": () => "iber",
+ "GetPlayerID": () => playerID,
+ "GetTimeMultiplier": () => 0,
+ "BlockTraining": () => {},
+ "UnBlockTraining": () => {},
+ "UnReservePopulationSlots": () => {},
+ "TrySubtractResources": () => true,
+ "TryReservePopulationSlots": () => false // Always have pop space.
+ });
+
+ AddMock(testEntity, IID_Ownership, {
+ "GetOwner": () => playerID
+ });
+
+ let cmpProdQueue = ConstructComponent(testEntity, "ProductionQueue", {
+ "Entities": { "_string": "some_template" },
+ "BatchTimeModifier": 1
+ });
+
+ cmpProdQueue.EnableAutoQueue();
+
+ cmpProdQueue.AddItem("some_template", "unit", 3);
+ TS_ASSERT_EQUALS(cmpProdQueue.GetQueue().length, 1);
+ cmpProdQueue.ProgressTimeout(null, 0);
+ TS_ASSERT_EQUALS(cmpProdQueue.GetQueue().length, 2);
+}
+
testEntitiesList();
regression_test_d1879();
test_batch_adding();
test_batch_removal();
+test_auto_queue();
test_token_changes();
Index: ps/trunk/binaries/data/mods/public/simulation/helpers/Commands.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/helpers/Commands.js
+++ ps/trunk/binaries/data/mods/public/simulation/helpers/Commands.js
@@ -877,6 +877,27 @@
cmpResourceDropsite.SetSharing(cmd.shared);
}
},
+
+ "autoqueue-on": function(player, cmd, data)
+ {
+ for (let ent of data.entities)
+ {
+ let cmpProductionQueue = Engine.QueryInterface(ent, IID_ProductionQueue);
+ if (cmpProductionQueue)
+ cmpProductionQueue.EnableAutoQueue();
+ }
+ },
+
+ "autoqueue-off": function(player, cmd, data)
+ {
+ for (let ent of data.entities)
+ {
+ let cmpProductionQueue = Engine.QueryInterface(ent, IID_ProductionQueue);
+ if (cmpProductionQueue)
+ cmpProductionQueue.DisableAutoQueue();
+ }
+ },
+
};
/**