Index: binaries/data/config/default.cfg =================================================================== --- binaries/data/config/default.cfg +++ binaries/data/config/default.cfg @@ -345,6 +345,7 @@ attack = true ; Show a chat notification if you are attacked by another player tribute = true ; Show a chat notification if an ally tributes resources to another team member if teams are locked, and all tributes in observer mode barter = true ; Show a chat notification to observers when a player bartered resources +phase = true ; Show a chat notification when an ally is advancing or has reached a new phase, and all phases in observer mode [gui.splashscreen] enable = true ; Enable/disable the splashscreen Index: binaries/data/mods/public/gui/options/options.json =================================================================== --- binaries/data/mods/public/gui/options/options.json +++ binaries/data/mods/public/gui/options/options.json @@ -278,6 +278,12 @@ "label": "Barter", "tooltip": "Show a chat notification to observers when a player bartered resources", "parameters": { "config": "gui.session.notifications.barter" } + }, + { + "type": "boolean", + "label": "New phase", + "tooltip": "Show a chat notification when an ally is advancing or has reached a new phase, and all phases in observer mode", + "parameters": { "config": "gui.session.notifications.phase" } } ] } Index: binaries/data/mods/public/gui/session/messages.js =================================================================== --- binaries/data/mods/public/gui/session/messages.js +++ binaries/data/mods/public/gui/session/messages.js @@ -128,7 +128,8 @@ "diplomacy": msg => formatDiplomacyMessage(msg), "tribute": msg => formatTributeMessage(msg), "barter": msg => formatBarterMessage(msg), - "attack": msg => formatAttackMessage(msg) + "attack": msg => formatAttackMessage(msg), + "phase": msg => formatPhaseMessage(msg) }; /** @@ -394,6 +395,15 @@ "targetIsDomesticAnimal": notification.targetIsDomesticAnimal }); }, + "phase": function(notification, player) + { + addChatMessage({ + "type": "phase", + "player": player, + "phaseName": notification.phaseName, + "phaseState": notification.phaseState + }); + }, "dialog": function(notification, player) { if (player == Engine.GetPlayerID()) @@ -950,6 +960,24 @@ }); } +function formatPhaseMessage(msg) +{ + if (Engine.ConfigDB_GetValue("user", "gui.session.notifications.phase") != "true" || + (msg.player != g_ViewedPlayer && !g_IsObserver && !g_Players[msg.player].isMutualAlly[g_ViewedPlayer])) + return ""; + + let message = ""; + if (msg.phaseState == "started") + message = translate("%(player)s is advancing to the %(phaseName)s."); + else if (msg.phaseState == "completed") + message = translate("%(player)s has reached the %(phaseName)s."); + + return sprintf(message, { + "player": colorizePlayernameByID(msg.player), + "phaseName": getEntityNames(GetTechnologyData(msg.phaseName, g_Players[msg.player].civ)) + }); +} + function formatChatCommand(msg) { if (!msg.text) Index: binaries/data/mods/public/simulation/ai/petra/chatHelper.js =================================================================== --- binaries/data/mods/public/simulation/ai/petra/chatHelper.js +++ binaries/data/mods/public/simulation/ai/petra/chatHelper.js @@ -43,15 +43,6 @@ markForTranslation("A new trade route is set up with %(_player_)s. Take your share of the profits.") ]; -m.newPhaseMessages = { - "started": [ - markForTranslation("I am advancing to the %(phase)s.") - ], - "completed": [ - markForTranslation("I have reached the %(phase)s.") - ] -}; - m.newDiplomacyMessages = { "ally": [ markForTranslation("%(_player_)s and I are now allies.") Index: binaries/data/mods/public/simulation/ai/petra/headquarters.js =================================================================== --- binaries/data/mods/public/simulation/ai/petra/headquarters.js +++ binaries/data/mods/public/simulation/ai/petra/headquarters.js @@ -411,20 +411,6 @@ } }; -/** Called by the "town phase" research plan once it's started */ -m.HQ.prototype.OnTownPhase = function(gameState) -{ - let phaseName = gameState.getTemplate(gameState.townPhase()).name(); - m.chatNewPhase(gameState, phaseName, "started"); -}; - -/** Called by the "city phase" research plan once it's started */ -m.HQ.prototype.OnCityPhase = function(gameState) -{ - let phaseName = gameState.getTemplate(gameState.cityPhase()).name(); - m.chatNewPhase(gameState, phaseName, "started"); -}; - /** This code trains citizen workers, trying to keep close to a ratio of worker/soldiers */ m.HQ.prototype.trainMoreWorkers = function(gameState, queues) { @@ -2213,18 +2199,6 @@ this.researchManager.checkPhase(gameState, queues); // TODO find a better way to update - if (this.currentPhase != gameState.currentPhase()) - { - this.currentPhase = gameState.currentPhase(); - let phaseName = "Unknown Phase"; - if (this.currentPhase == 2) - phaseName = gameState.getTemplate(gameState.townPhase()).name(); - else if (this.currentPhase == 3) - phaseName = gameState.getTemplate(gameState.cityPhase()).name(); - - m.chatNewPhase(gameState, phaseName, "completed"); - } - if (this.numActiveBase() > 0) { this.trainMoreWorkers(gameState, queues); Index: binaries/data/mods/public/simulation/components/Player.js =================================================================== --- binaries/data/mods/public/simulation/components/Player.js +++ binaries/data/mods/public/simulation/components/Player.js @@ -731,6 +731,20 @@ this.UpdateSharedLos(); else if (msg.tech == this.template.SharedDropsitesTech) this.sharedDropsites = true; + + let cmpDataTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager); + let template = cmpDataTemplateManager.GetTechnologyTemplate(msg.tech); + // Send a notification for new phase + if (msg.tech.startsWith("phase_") && !template.autoResearch) + { + var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); + cmpGUIInterface.PushNotification({ + "type": "phase", + "players": [this.playerID], + "phaseName": msg.tech, + "phaseState": "completed" + }); + } }; Player.prototype.OnDiplomacyChanged = function() Index: binaries/data/mods/public/simulation/helpers/Commands.js =================================================================== --- binaries/data/mods/public/simulation/helpers/Commands.js +++ binaries/data/mods/public/simulation/helpers/Commands.js @@ -334,6 +334,18 @@ var queue = Engine.QueryInterface(cmd.entity, IID_ProductionQueue); if (queue) queue.AddBatch(cmd.template, "technology"); + + // if the researched technology is phasing, send a notification to GUI + if (cmd.template.startsWith("phase_") && !cmd.template.autoResearch) + { + var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); + cmpGuiInterface.PushNotification({ + "type": "phase", + "players": [player], + "phaseName": cmd.template, + "phaseState": "started" + }); + } }, "stop-production": function(player, cmd, data)