Enable production entities to autoqueue.
This adds a new command button that enables training of units automatically. Use: - Enable auto-queue. - Train an entity. This adds a new item to the queue whenever the previous item starts, such that good micro is more resource-efficient. Patch by: @azayrahmad Differential revision: https://code.wildfiregames.com/D3865 Comments by: @Langbart, @nani, @Stan, @wraitii This was SVN commit r25381.
This commit is contained in:
parent
fe3ff1b0ff
commit
51ab4315ff
BIN
binaries/data/mods/public/art/textures/ui/session/icons/autoqueue-off.png
(Stored with Git LFS)
Normal file
BIN
binaries/data/mods/public/art/textures/ui/session/icons/autoqueue-off.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
binaries/data/mods/public/art/textures/ui/session/icons/autoqueue-on.png
(Stored with Git LFS)
Normal file
BIN
binaries/data/mods/public/art/textures/ui/session/icons/autoqueue-on.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -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" },
|
||||
|
@ -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."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,4 +34,14 @@
|
||||
<object hotkey="session.queueunit.7">
|
||||
<action on="KeyDown">addTrainingByPosition(6);</action>
|
||||
</object>
|
||||
|
||||
<!-- enable autoqueue -->
|
||||
<object hotkey="session.queueunit.autoqueueon">
|
||||
<action on="KeyDown">turnAutoQueueOn();</action>
|
||||
</object>
|
||||
|
||||
<!-- disable autoqueue -->
|
||||
<object hotkey="session.queueunit.autoqueueoff">
|
||||
<action on="KeyDown">turnAutoQueueOff();</action>
|
||||
</object>
|
||||
</object>
|
||||
|
@ -546,3 +546,25 @@ function endOfAlert()
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
})
|
||||
});
|
||||
}
|
||||
|
@ -1715,7 +1715,47 @@ var g_EntityCommands =
|
||||
// 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)
|
||||
|
@ -344,7 +344,8 @@ GuiInterface.prototype.GetEntityState = function(player, ent)
|
||||
"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);
|
||||
|
@ -73,6 +73,30 @@ ProductionQueue.prototype.GetEntitiesList = function()
|
||||
return Array.from(this.entitiesMap.values());
|
||||
};
|
||||
|
||||
/**
|
||||
* @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 @@ ProductionQueue.prototype.ProgressTimeout = function(data, lateness)
|
||||
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)
|
||||
|
@ -545,8 +545,81 @@ function test_token_changes()
|
||||
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();
|
||||
|
@ -877,6 +877,27 @@ var g_Commands = {
|
||||
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();
|
||||
}
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user