Index: binaries/data/mods/public/gui/session/input.js =================================================================== --- binaries/data/mods/public/gui/session/input.js +++ binaries/data/mods/public/gui/session/input.js @@ -1348,7 +1348,7 @@ return entitiesToCheck.filter(entity => { let state = GetEntityState(entity); return state && state.production && state.production.entities.length && - state.production.entities.indexOf(trainEntType) != -1; + state.production.entities.indexOf(trainEntType) != -1 && (!state.upgrade || !state.upgrade.upgrading); }); } 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 @@ -798,6 +798,14 @@ else button.enabled = controlsPlayer(data.player); + if (data.unitEntStates.every(state => state.upgrade && state.upgrade.isUpgrading)) + { + button.enabled = false; + modifier += "color:0 0 0 127:grayscale:"; + button.tooltip += "\n" + coloredText(translate("Cannot research while upgrading."), "red"); + + } + if (template.icon) icon.sprite = modifier + "stretched:session/portraits/" + template.icon; @@ -1011,6 +1019,13 @@ modifier = resourcesToAlphaMask(neededResources) + ":"; } + if (data.unitEntStates.every(state => state.upgrade && state.upgrade.isUpgrading)) + { + data.button.enabled = false; + modifier = "color:0 0 0 127:grayscale:"; + data.button.tooltip += "\n" + coloredText(translate("Cannot train while upgrading."), "red"); + } + if (template.icon) data.icon.sprite = modifier + "stretched:session/portraits/" + template.icon; @@ -1114,6 +1129,13 @@ modifier = resourcesToAlphaMask(neededResources) + ":"; } + if (data.unitEntStates.every(state => state.production && state.production.queue && state.production.queue.length)) + { + data.button.enabled = false; + modifier = "color:0 0 0 127:grayscale:"; + data.button.tooltip += "\n" + coloredText(translate("Cannot upgrade while training or researching"), "red"); + } + data.icon.sprite = modifier + "stretched:session/" + (data.item.icon || "portraits/" + template.icon); Index: binaries/data/mods/public/simulation/components/GuiInterface.js =================================================================== --- binaries/data/mods/public/simulation/components/GuiInterface.js +++ binaries/data/mods/public/simulation/components/GuiInterface.js @@ -308,7 +308,8 @@ ret.upgrade = { "upgrades": cmpUpgrade.GetUpgrades(), "progress": cmpUpgrade.GetProgress(), - "template": cmpUpgrade.GetUpgradingTo() + "template": cmpUpgrade.GetUpgradingTo(), + "isUpgrading": cmpUpgrade.IsUpgrading() }; let cmpStatusEffects = Engine.QueryInterface(ent, IID_StatusEffectsReceiver); 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 @@ -324,6 +324,21 @@ // to be possible to add a batch (based on resource costs and length limits). let cmpPlayer = QueryOwnerInterface(this.entity); + if (!this.queue.length) + { + let cmpUpgrade = Engine.QueryInterface(this.entity, IID_Upgrade); + if (cmpUpgrade && cmpUpgrade.IsUpgrading()) + { + let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); + cmpGUIInterface.PushNotification({ + "players": [cmpPlayer.GetPlayerID()], + "message": markForTranslation("Entity is being upgraded. Cannot start production."), + "translateMessage": true + }); + return; + } + } + if (this.queue.length < this.MaxQueueSize) { @@ -947,6 +962,11 @@ Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface).SetSelectionDirty(cmpPlayer.GetPlayerID()); }; +ProductionQueue.prototype.HasQueuedProduction = function() +{ + return this.queue.length > 0; +} + ProductionQueue.prototype.OnDisabledTemplatesChanged = function(msg) { // If the disabled templates of the player is changed, Index: binaries/data/mods/public/simulation/components/Upgrade.js =================================================================== --- binaries/data/mods/public/simulation/components/Upgrade.js +++ binaries/data/mods/public/simulation/components/Upgrade.js @@ -228,6 +228,17 @@ return false; let cmpPlayer = QueryOwnerInterface(this.entity, IID_Player); + let cmpProductionQueue = Engine.QueryInterface(this.entity, IID_ProductionQueue); + if (cmpProductionQueue && cmpProductionQueue.HasQueuedProduction()) + { + let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); + cmpGUIInterface.PushNotification({ + "players": [cmpPlayer.GetPlayerID()], + "message": markForTranslation("Entity is producing. Cannot start upgrading."), + "translateMessage": true + }); + return false; + } this.expendedResources = this.GetResourceCosts(template); if (!cmpPlayer.TrySubtractResources(this.expendedResources)) Index: binaries/data/mods/public/simulation/components/tests/test_ProductionQueue.js =================================================================== --- binaries/data/mods/public/simulation/components/tests/test_ProductionQueue.js +++ binaries/data/mods/public/simulation/components/tests/test_ProductionQueue.js @@ -9,6 +9,7 @@ Engine.LoadComponentScript("interfaces/Timer.js"); Engine.LoadComponentScript("interfaces/TrainingRestrictions.js"); Engine.LoadComponentScript("interfaces/Trigger.js"); +Engine.LoadComponentScript("interfaces/Upgrade.js"); Engine.LoadComponentScript("EntityLimits.js"); Engine.RegisterGlobal("Resources", { @@ -71,6 +72,10 @@ "GetCiv": () => "iber" }); + AddMock(productionQueueId, IID_Upgrade, { + "IsUpgrading": () => false + }); + cmpProductionQueue.CalculateEntitiesMap(); TS_ASSERT_UNEVAL_EQUALS( cmpProductionQueue.GetEntitiesList(), @@ -273,6 +278,10 @@ "PickSpawnPoint": () => ({ "x": -1, "y": -1, "z": -1 }) }); + AddMock(testEntity, IID_Upgrade, { + "IsUpgrading": () => false + }); + cmpProdQueue.AddBatch("some_template", "unit", 3); Engine.QueryInterface(testEntity, IID_ProductionQueue).ProgressTimeout(); Index: binaries/data/mods/public/simulation/components/tests/test_UpgradeModification.js =================================================================== --- binaries/data/mods/public/simulation/components/tests/test_UpgradeModification.js +++ binaries/data/mods/public/simulation/components/tests/test_UpgradeModification.js @@ -13,6 +13,7 @@ return "" + schema + ""; } }; +Engine.LoadComponentScript("interfaces/ProductionQueue.js"); Engine.LoadComponentScript("interfaces/ModifiersManager.js"); // Provides `IID_ModifiersManager`, used below. Engine.LoadComponentScript("interfaces/Timer.js"); // Provides `IID_Timer`, used below. @@ -120,6 +121,9 @@ AddMock(20, IID_Identity, { "GetCiv": () => civCode // Called in components/Upgrade.js::init(). }); +AddMock(20, IID_ProductionQueue, { + "HasQueuedProduction": () => false +}) let cmpUpgrade = ConstructComponent(20, "Upgrade", template.Upgrade); cmpUpgrade.owner = playerID;