Index: ps/trunk/binaries/data/config/default.cfg
===================================================================
--- ps/trunk/binaries/data/config/default.cfg
+++ ps/trunk/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 = 1 ; Show a chat notification if you or an ally have started, aborted or completed a new phase, and phases of all players in observer mode (0 = disable, 1 = completed phase only and 2 = display all)
[gui.splashscreen]
enable = true ; Enable/disable the splashscreen
Index: ps/trunk/binaries/data/mods/public/gui/options/options.json
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/options/options.json
+++ ps/trunk/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": "dropdown",
+ "label": "Phase",
+ "tooltip": "Show a chat notification if you or an ally have started, aborted or completed a new phase, and phases of all players in observer mode",
+ "parameters": { "config": "gui.session.notifications.phase", "list": [ "Disable", "Completed", "All displayed" ] }
}
]
}
Index: ps/trunk/binaries/data/mods/public/gui/options/options.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/options/options.xml
+++ ps/trunk/binaries/data/mods/public/gui/options/options.xml
@@ -78,7 +78,7 @@
-
+
Index: ps/trunk/binaries/data/mods/public/gui/session/messages.js
===================================================================
--- ps/trunk/binaries/data/mods/public/gui/session/messages.js
+++ ps/trunk/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,29 @@
});
}
+function formatPhaseMessage(msg)
+{
+ let notifyPhase = Engine.ConfigDB_GetValue("user", "gui.session.notifications.phase");
+ if (notifyPhase == 0 || msg.player != g_ViewedPlayer && !g_IsObserver && !g_Players[msg.player].isMutualAlly[g_ViewedPlayer])
+ return "";
+
+ let message = "";
+ if (notifyPhase == 2)
+ {
+ if (msg.phaseState == "started")
+ message = translate("%(player)s is advancing to the %(phaseName)s.");
+ else if (msg.phaseState == "aborted")
+ message = translate("The %(phaseName)s of %(player)s has been aborted.");
+ }
+ 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: ps/trunk/binaries/data/mods/public/simulation/ai/petra/chatHelper.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/ai/petra/chatHelper.js
+++ ps/trunk/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: ps/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
+++ ps/trunk/binaries/data/mods/public/simulation/ai/petra/headquarters.js
@@ -414,15 +414,11 @@
/** 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 */
@@ -2214,16 +2210,7 @@
// 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)
{
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
@@ -358,7 +358,7 @@
var cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager);
cmpTechnologyManager.QueuedResearch(templateName, this.entity);
if (this.queue.length == 0)
- cmpTechnologyManager.StartedResearch(templateName);
+ cmpTechnologyManager.StartedResearch(templateName, false);
this.queue.push({
"id": this.nextID++,
@@ -455,7 +455,7 @@
{
// item.player is used as this.entity's owner may be invalid (deletion, etc.)
var cmpTechnologyManager = QueryPlayerIDInterface(item.player, IID_TechnologyManager);
- cmpTechnologyManager.StoppedResearch(item.technologyTemplate);
+ cmpTechnologyManager.StoppedResearch(item.technologyTemplate, true);
}
// Remove from the queue
@@ -721,7 +721,7 @@
{
// Mark the research as started.
var cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager);
- cmpTechnologyManager.StartedResearch(item.technologyTemplate);
+ cmpTechnologyManager.StartedResearch(item.technologyTemplate, true);
}
item.productionStarted = true;
Index: ps/trunk/binaries/data/mods/public/simulation/components/TechnologyManager.js
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/components/TechnologyManager.js
+++ ps/trunk/binaries/data/mods/public/simulation/components/TechnologyManager.js
@@ -255,7 +255,7 @@
// Marks a technology as researched. Note that this does not verify that the requirements are met.
TechnologyManager.prototype.ResearchTechnology = function(tech)
{
- this.StoppedResearch(tech); // The tech is no longer being currently researched
+ this.StoppedResearch(tech, false);
var template = this.GetTechnologyTemplate(tech);
@@ -329,6 +329,17 @@
Engine.PostMessage(SYSTEM_ENTITY, MT_TemplateModification, { "player": playerID, "component": component, "valueNames": modifiedComponents[component]});
Engine.BroadcastMessage(MT_ValueModification, { "entities": ents, "component": component, "valueNames": modifiedComponents[component]});
}
+
+ if (tech.startsWith("phase") && !template.autoResearch)
+ {
+ let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
+ cmpGUIInterface.PushNotification({
+ "type": "phase",
+ "players": [playerID],
+ "phaseName": tech,
+ "phaseState": "completed"
+ });
+ }
};
// Clears the cached data for an entity from the modifications cache
@@ -377,14 +388,38 @@
};
// Marks a technology as actively being researched
-TechnologyManager.prototype.StartedResearch = function(tech)
+TechnologyManager.prototype.StartedResearch = function(tech, notification)
{
this.researchStarted[tech] = true;
+
+ if (notification && tech.startsWith("phase"))
+ {
+ let cmpPlayer = Engine.QueryInterface(this.entity, IID_Player);
+ let cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
+ cmpGuiInterface.PushNotification({
+ "type": "phase",
+ "players": [cmpPlayer.GetPlayerID()],
+ "phaseName": tech,
+ "phaseState": "started"
+ });
+ }
};
// Marks a technology as not being currently researched
-TechnologyManager.prototype.StoppedResearch = function(tech)
+TechnologyManager.prototype.StoppedResearch = function(tech, notification)
{
+ if (notification && tech.startsWith("phase") && this.researchStarted[tech])
+ {
+ let cmpPlayer = Engine.QueryInterface(this.entity, IID_Player);
+ let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
+ cmpGUIInterface.PushNotification({
+ "type": "phase",
+ "players": [cmpPlayer.GetPlayerID()],
+ "phaseName": tech,
+ "phaseState": "aborted"
+ });
+ }
+
delete this.researchQueued[tech];
delete this.researchStarted[tech];
};