Index: ps/trunk/binaries/data/mods/public/gui/session/ResearchProgress.js
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/session/ResearchProgress.js
+++ ps/trunk/binaries/data/mods/public/gui/session/ResearchProgress.js
@@ -55,6 +55,7 @@
this.sprite = Engine.GetGUIObjectByName("researchStartedIcon[" + i + "]");
this.progress = Engine.GetGUIObjectByName("researchStartedProgressSlider[" + i + "]");
this.timeRemaining = Engine.GetGUIObjectByName("researchStartedTimeRemaining[" + i + "]");
+ this.paused = Engine.GetGUIObjectByName("researchPausedIcon[" + i + "]");
this.buttonHeight = this.button.size.bottom - this.button.size.top;
this.buttonTop = this.Margin + (this.Margin + this.buttonHeight) * i;
@@ -68,13 +69,18 @@
this.researcher = researchStatus.researcher;
let template = GetTechnologyData(techName, g_Players[g_ViewedPlayer].civ);
- this.sprite.sprite = "stretched:" + this.PortraitDirectory + template.icon;
+ let modifier = "stretched:";
+ if (researchStatus.paused)
+ modifier += "color:0 0 0 127:grayscale:";
+ this.sprite.sprite = modifier + this.PortraitDirectory + template.icon;
let size = this.button.size;
size.top = offset + this.buttonTop;
size.bottom = size.top + this.buttonHeight;
this.button.size = size;
this.button.tooltip = getEntityNames(template);
+ if (researchStatus.paused)
+ this.button.tooltip += "\n" + translate(this.PausedResearchString);
this.button.hidden = false;
size = this.progress.size;
@@ -85,6 +91,8 @@
Engine.FormatMillisecondsIntoDateStringGMT(
researchStatus.timeRemaining,
translateWithContext("countdown format", this.CountdownFormat));
+
+ this.paused.hidden = !researchStatus.paused;
}
onPress()
@@ -107,3 +115,6 @@
* This format is used when displaying the remaining time of the currently viewed techs in research.
*/
ResearchProgressButton.prototype.CountdownFormat = markForTranslationWithContext("countdown format", "m:ss");
+
+// Translation: String displayed when the research is paused. E.g. by being garrisoned or when not the first item in the queue.
+ResearchProgressButton.prototype.PausedResearchString = markForTranslation("(This item is paused.)");
Index: ps/trunk/binaries/data/mods/public/gui/session/ResearchProgress.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/session/ResearchProgress.xml
+++ ps/trunk/binaries/data/mods/public/gui/session/ResearchProgress.xml
@@ -7,6 +7,7 @@
+
Index: ps/trunk/binaries/data/mods/public/gui/session/input.js
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/session/input.js
+++ ps/trunk/binaries/data/mods/public/gui/session/input.js
@@ -1521,7 +1521,8 @@
"type": "train",
"template": trainEntType,
"count": 1,
- "entities": buildingsForTraining
+ "entities": buildingsForTraining,
+ "pushFront": Engine.HotkeyIsPressed("session.pushorderfront")
});
}
}
@@ -1579,7 +1580,8 @@
"type": "train",
"entities": appropriateBuildings.slice(0, buildingsCountToTrainFullBatch),
"template": g_BatchTrainingType,
- "count": batchedSize
+ "count": batchedSize,
+ "pushFront": Engine.HotkeyIsPressed("session.pushorderfront")
});
// Train remainer in one more structure.
@@ -1589,7 +1591,8 @@
"type": "train",
"entities": [appropriateBuildings[buildingsCountToTrainFullBatch]],
"template": g_BatchTrainingType,
- "count": remainer
+ "count": remainer,
+ "pushFront": Engine.HotkeyIsPressed("session.pushorderfront")
});
}
else
@@ -1597,7 +1600,8 @@
"type": "train",
"entities": appropriateBuildings,
"template": g_BatchTrainingType,
- "count": batchedSize
+ "count": batchedSize,
+ "pushFront": Engine.HotkeyIsPressed("session.pushorderfront")
});
}
Index: ps/trunk/binaries/data/mods/public/gui/session/selection_panels.js
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/session/selection_panels.js
+++ ps/trunk/binaries/data/mods/public/gui/session/selection_panels.js
@@ -590,10 +590,22 @@
guiObject.size = size;
data.button.enabled = controlsPlayer(data.player);
+
+ Engine.GetGUIObjectByName("unitQueuePausedIcon[" + data.i + "]").hidden = !queuedItem.paused;
+ if (queuedItem.paused)
+ // Translation: String displayed when the research is paused. E.g. by being garrisoned or when not the first item in the queue.
+ data.button.tooltip += "\n" + translate("(This item is paused.)");
}
if (template.icon)
- data.icon.sprite = (data.item.ghost ? "grayscale:" : "") + "stretched:session/portraits/" + template.icon;
+ {
+ let modifier = "stretched:";
+ if (queuedItem.paused)
+ modifier += "color:0 0 0 127:grayscale:";
+ else if (data.item.ghost)
+ modifier += "grayscale:";
+ data.icon.sprite = modifier + "session/portraits/" + template.icon;
+ }
const showTemplateFunc = () => { showTemplateDetails(data.item.queuedItem.unitTemplate || data.item.queuedItem.technologyTemplate, data.playerState.civ); };
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
@@ -272,7 +272,8 @@
Engine.PostNetworkCommand({
"type": "research",
"entity": entity,
- "template": researchType
+ "template": researchType,
+ "pushFront": Engine.HotkeyIsPressed("session.pushorderfront")
});
}
Index: ps/trunk/binaries/data/mods/public/gui/session/selection_panels_right/queue_panel.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/session/selection_panels_right/queue_panel.xml
+++ ps/trunk/binaries/data/mods/public/gui/session/selection_panels_right/queue_panel.xml
@@ -12,8 +12,9 @@
Index: ps/trunk/binaries/data/mods/public/simulation/ai/common-api/entity.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/ai/common-api/entity.js
+++ ps/trunk/binaries/data/mods/public/simulation/ai/common-api/entity.js
@@ -940,7 +940,7 @@
return this;
},
- "train": function(civ, type, count, metadata, promotedTypes)
+ "train": function(civ, type, count, metadata, promotedTypes, pushFront = false)
{
let trainable = this.trainableEntities(civ);
if (!trainable)
@@ -960,7 +960,8 @@
"template": type,
"count": count,
"metadata": metadata,
- "promoted": promotedTypes
+ "promoted": promotedTypes,
+ "pushFront": pushFront
});
return this;
},
@@ -985,8 +986,13 @@
return this;
},
- "research": function(template) {
- Engine.PostCommand(PlayerID, { "type": "research", "entity": this.id(), "template": template });
+ "research": function(template, pushFront = false) {
+ Engine.PostCommand(PlayerID, {
+ "type": "research",
+ "entity": this.id(),
+ "template": template,
+ "pushFront": pushFront
+ });
return this;
},
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
@@ -692,13 +692,16 @@
let cmpProductionQueue = Engine.QueryInterface(ret[tech].researcher, IID_ProductionQueue);
if (cmpProductionQueue)
{
- ret[tech].progress = cmpProductionQueue.GetQueue()[0].progress;
- ret[tech].timeRemaining = cmpProductionQueue.GetQueue()[0].timeRemaining;
+ const research = cmpProductionQueue.GetQueue().find(item => item.technologyTemplate === tech);
+ ret[tech].progress = research.progress;
+ ret[tech].timeRemaining = research.timeRemaining;
+ ret[tech].paused = research.paused;
}
else
{
ret[tech].progress = 0;
ret[tech].timeRemaining = 0;
+ ret[tech].paused = true;
}
}
return ret;
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
@@ -47,6 +47,7 @@
"productionStarted": false, // true iff production has started (we have reserved population).
"timeTotal": 15000, // msecs
"timeRemaining": 10000, // msecs
+ "paused": false, // Whether the item is currently paused (e.g. not the first item or parent is garrisoned).
"resources": { "wood": 100, ... }, // Total resources of the item when queued.
"entity": {
"template": "units/example",
@@ -340,10 +341,11 @@
* @param {string} type - The type of production (i.e. "unit" or "technology").
* @param {number} count - The amount of units to be produced. Ignored for a tech.
* @param {any} metadata - Optionally any metadata to be attached to the item.
+ * @param {boolean} pushFront - Whether to push the item to the front of the queue and pause any item(s) currently in progress.
*
* @return {boolean} - Whether the addition of the item has succeeded.
*/
-ProductionQueue.prototype.AddItem = function(templateName, type, count, metadata)
+ProductionQueue.prototype.AddItem = function(templateName, type, count, metadata, pushFront = false)
{
// TODO: there should be a way for the GUI to determine whether it's going
// to be possible to add a batch (based on resource costs and length limits).
@@ -382,6 +384,7 @@
"metadata": metadata,
"productionStarted": false,
"resources": {}, // The total resource costs.
+ "paused": false
};
// ToDo: Still some duplication here, some can might be combined,
@@ -490,7 +493,14 @@
return false;
item.id = this.nextID++;
- this.queue.push(item);
+ if (pushFront)
+ {
+ if (this.queue[0])
+ this.queue[0].paused = true;
+ this.queue.unshift(item);
+ }
+ else
+ this.queue.push(item);
const cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger);
if (item.entity)
@@ -618,6 +628,7 @@
"neededSlots": item.entity?.neededSlots,
"progress": 1 - (item.timeRemaining / (item.timeTotal || 1)),
"timeRemaining": item.timeRemaining,
+ "paused": item.paused,
"metadata": item.metadata
}));
};
@@ -797,6 +808,8 @@
while (this.queue.length)
{
let item = this.queue[0];
+ if (item.paused)
+ item.paused = false;
if (!item.productionStarted)
{
if (item.entity)
@@ -924,10 +937,14 @@
{
this.StopTimer();
this.paused = true;
+ if (this.queue[0])
+ this.queue[0].paused = true;
};
ProductionQueue.prototype.UnpauseProduction = function()
{
+ if (this.queue[0])
+ this.queue[0].paused = false;
delete this.paused;
this.StartTimer();
};
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
@@ -372,10 +372,7 @@
}
}
if (queue && queue.GetEntitiesList().indexOf(cmd.template) != -1)
- if ("metadata" in cmd)
- queue.AddItem(cmd.template, "unit", +cmd.count, cmd.metadata);
- else
- queue.AddItem(cmd.template, "unit", +cmd.count);
+ queue.AddItem(cmd.template, "unit", +cmd.count, cmd.metadata, cmd.pushFront);
}
},
@@ -391,7 +388,7 @@
var queue = Engine.QueryInterface(cmd.entity, IID_ProductionQueue);
if (queue)
- queue.AddItem(cmd.template, "technology");
+ queue.AddItem(cmd.template, "technology", undefined, cmd.metadata, cmd.pushFront);
},
"stop-production": function(player, cmd, data)