1
0
forked from 0ad/0ad

Allow to push items to the front of the ProductionQueue.

Refs. #6104
Differential revision: https://code.wildfiregames.com/D4241
Comments by: @bb, @Langbart, @Stan
This was SVN commit r25958.
This commit is contained in:
Freagarach 2021-10-10 19:07:42 +00:00
parent b1a01005b8
commit 75aa2091b7
10 changed files with 74 additions and 21 deletions

View File

@ -55,6 +55,7 @@ class ResearchProgressButton
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 @@ class ResearchProgressButton
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 @@ class ResearchProgressButton
Engine.FormatMillisecondsIntoDateStringGMT(
researchStatus.timeRemaining,
translateWithContext("countdown format", this.CountdownFormat));
this.paused.hidden = !researchStatus.paused;
}
onPress()
@ -107,3 +115,6 @@ ResearchProgressButton.prototype.PortraitDirectory = "session/portraits/";
* 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.)");

View File

@ -7,6 +7,7 @@
<object name="researchStartedIcon[n]" ghost="true" type="image" size="3 3 35 35"/>
<object name="researchStartedProgressSlider[n]" type="image" sprite="queueProgressSlider" ghost="true" size="3 3 37 37"/>
<object name="researchStartedTimeRemaining[n]" ghost="true" style="iconButtonProgress" type="text"/>
<object name="researchPausedIcon[n]" ghost="true" type="image" sprite="stretched:session/icons/stop.png" size="3 3 35 35"/>
</object>
</repeat>
</object>

View File

@ -1521,7 +1521,8 @@ function addTrainingToQueue(selection, trainEntType, playerState)
"type": "train",
"template": trainEntType,
"count": 1,
"entities": buildingsForTraining
"entities": buildingsForTraining,
"pushFront": Engine.HotkeyIsPressed("session.pushorderfront")
});
}
}
@ -1579,7 +1580,8 @@ function flushTrainingBatch()
"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 @@ function flushTrainingBatch()
"type": "train",
"entities": [appropriateBuildings[buildingsCountToTrainFullBatch]],
"template": g_BatchTrainingType,
"count": remainer
"count": remainer,
"pushFront": Engine.HotkeyIsPressed("session.pushorderfront")
});
}
else
@ -1597,7 +1600,8 @@ function flushTrainingBatch()
"type": "train",
"entities": appropriateBuildings,
"template": g_BatchTrainingType,
"count": batchedSize
"count": batchedSize,
"pushFront": Engine.HotkeyIsPressed("session.pushorderfront")
});
}

View File

@ -590,10 +590,22 @@ g_SelectionPanels.Queue = {
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); };

View File

@ -272,7 +272,8 @@ function addResearchToQueue(entity, researchType)
Engine.PostNetworkCommand({
"type": "research",
"entity": entity,
"template": researchType
"template": researchType,
"pushFront": Engine.HotkeyIsPressed("session.pushorderfront")
});
}

View File

@ -12,8 +12,9 @@
<repeat count="16">
<object name="unitQueueButton[n]" hidden="true" style="iconButton" type="button" size="2 2 40 40" tooltip_style="sessionToolTipBottom">
<object name="unitQueueIcon[n]" ghost="true" type="image" size="3 3 35 35"/>
<object name="unitQueueProgressSlider[n]" type="image" sprite="queueProgressSlider" ghost="true" size="3 3 35 35" z="20"/>
<object name="unitQueueProgressSlider[n]" type="image" sprite="queueProgressSlider" ghost="true" size="3 3 35 35"/>
<object name="unitQueueCount[n]" ghost="true" style="groupIconsText" type="text" z="20"/>
<object name="unitQueuePausedIcon[n]" ghost="true" type="image" sprite="stretched:session/icons/stop.png" size="3 3 35 35"/>
</object>
</repeat>
</object>

View File

@ -940,7 +940,7 @@ m.Entity = m.Class({
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 @@ m.Entity = m.Class({
"template": type,
"count": count,
"metadata": metadata,
"promoted": promotedTypes
"promoted": promotedTypes,
"pushFront": pushFront
});
return this;
},
@ -985,8 +986,13 @@ m.Entity = m.Class({
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;
},

View File

@ -692,13 +692,16 @@ GuiInterface.prototype.GetStartedResearch = function(player)
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;

View File

@ -47,6 +47,7 @@ ProductionQueue.prototype.Init = function()
"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 @@ ProductionQueue.prototype.IsTechnologyResearchedOrInProgress = function(tech)
* @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 @@ ProductionQueue.prototype.AddItem = function(templateName, type, count, metadata
"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 @@ ProductionQueue.prototype.AddItem = function(templateName, type, count, metadata
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 @@ ProductionQueue.prototype.GetQueue = function()
"neededSlots": item.entity?.neededSlots,
"progress": 1 - (item.timeRemaining / (item.timeTotal || 1)),
"timeRemaining": item.timeRemaining,
"paused": item.paused,
"metadata": item.metadata
}));
};
@ -797,6 +808,8 @@ ProductionQueue.prototype.ProgressTimeout = function(data, lateness)
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 @@ ProductionQueue.prototype.PauseProduction = function()
{
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();
};

View File

@ -372,10 +372,7 @@ var g_Commands = {
}
}
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 g_Commands = {
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)