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 = 1 ; Show a chat notification if you or an ally have started, canceled 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: binaries/data/mods/public/gui/options/options.json
===================================================================
--- binaries/data/mods/public/gui/options/options.json
+++ binaries/data/mods/public/gui/options/options.json
@@ -122,7 +122,7 @@
"type": "dropdown",
"label": "Graphics quality",
"tooltip": "Graphics quality. REQUIRES GAME RESTART",
- "parameters": { "list": [ "Low", "Medium", "High" ], "config": "materialmgr.quality" }
+ "parameters": { "config": "materialmgr.quality", "list": [ "Low", "Medium", "High", "Custom" ] }
},
{
"type": "boolean",
@@ -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, canceled 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: binaries/data/mods/public/gui/options/options.xml
===================================================================
--- binaries/data/mods/public/gui/options/options.xml
+++ binaries/data/mods/public/gui/options/options.xml
@@ -78,7 +78,7 @@
-
+
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,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 == "canceled")
+ message = translate("The %(phaseName)s of %(player)s has been stopped.");
+ }
+ 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/gui/session/session.js
===================================================================
--- binaries/data/mods/public/gui/session/session.js
+++ binaries/data/mods/public/gui/session/session.js
@@ -1156,7 +1156,7 @@
function updateResearchDisplay()
{
- let researchStarted = Engine.GuiInterfaceCall("GetStartedResearch", g_ViewedPlayer);
+ let researchStarted = Engine.GuiInterfaceCall("GetStartedTechs", g_ViewedPlayer);
// Set up initial positioning.
let buttonSideLength = Engine.GetGUIObjectByName("researchStartedButton[0]").size.right;
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
@@ -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,17 +2210,8 @@
// 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/GuiInterface.js
===================================================================
--- binaries/data/mods/public/simulation/components/GuiInterface.js
+++ binaries/data/mods/public/simulation/components/GuiInterface.js
@@ -119,7 +119,7 @@
"entityCounts": cmpPlayerEntityLimits ? cmpPlayerEntityLimits.GetCounts() : null,
"entityLimitChangers": cmpPlayerEntityLimits ? cmpPlayerEntityLimits.GetLimitChangers() : null,
"researchQueued": cmpTechnologyManager ? cmpTechnologyManager.GetQueuedResearch() : null,
- "researchStarted": cmpTechnologyManager ? cmpTechnologyManager.GetStartedResearch() : null,
+ "researchStarted": cmpTechnologyManager ? cmpTechnologyManager.GetStartedTechs() : null,
"researchedTechs": cmpTechnologyManager ? cmpTechnologyManager.GetResearchedTechs() : null,
"classCounts": cmpTechnologyManager ? cmpTechnologyManager.GetClassCounts() : null,
"typeCountsByClass": cmpTechnologyManager ? cmpTechnologyManager.GetTypeCountsByClass() : null,
@@ -699,7 +699,7 @@
// Returns technologies that are being actively researched, along with
// which entity is researching them and how far along the research is.
-GuiInterface.prototype.GetStartedResearch = function(player)
+GuiInterface.prototype.GetStartedTechs = function(player)
{
let cmpTechnologyManager = QueryPlayerIDInterface(player, IID_TechnologyManager);
if (!cmpTechnologyManager)
@@ -706,7 +706,7 @@
return {};
let ret = {};
- for (let tech in cmpTechnologyManager.GetTechsStarted())
+ for (let tech in cmpTechnologyManager.GetStartedTechs())
{
ret[tech] = { "researcher": cmpTechnologyManager.GetResearcher(tech) };
let cmpProductionQueue = Engine.QueryInterface(ret[tech].researcher, IID_ProductionQueue);
@@ -1978,7 +1978,7 @@
"GetTechnologyData": 1,
"IsTechnologyResearched": 1,
"CheckTechnologyRequirements": 1,
- "GetStartedResearch": 1,
+ "GetStartedTechs": 1,
"GetBattleState": 1,
"GetIncomingAttacks": 1,
"GetNeededResources": 1,
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
@@ -374,6 +374,18 @@
// Call the related trigger event
var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger);
cmpTrigger.CallEvent("ResearchQueued", {"playerid": cmpPlayer.GetPlayerID(), "technologyTemplate": templateName, "researcherEntity": this.entity});
+
+ // If the researched technology is phasing, send a notification to GUI
+ if (templateName.startsWith("phase") && !template.autoResearch)
+ {
+ let cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
+ cmpGuiInterface.PushNotification({
+ "type": "phase",
+ "players": [cmpPlayer.GetPlayerID()],
+ "phaseName": templateName,
+ "phaseState": "started"
+ });
+ }
}
else
{
@@ -463,6 +475,18 @@
this.queue.splice(i, 1);
Engine.PostMessage(this.entity, MT_ProductionQueueChanged, { });
+ // If the researched technology was phasing, send a notification to GUI
+ if (item.technologyTemplate.startsWith("phase") && !item.technologyTemplate.autoResearch)
+ {
+ let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
+ cmpGUIInterface.PushNotification({
+ "type": "phase",
+ "players": [cmpPlayer.GetPlayerID()],
+ "phaseName": item.technologyTemplate,
+ "phaseState": "canceled"
+ });
+ }
+
return;
}
};
Index: binaries/data/mods/public/simulation/components/TechnologyManager.js
===================================================================
--- binaries/data/mods/public/simulation/components/TechnologyManager.js
+++ binaries/data/mods/public/simulation/components/TechnologyManager.js
@@ -321,7 +321,7 @@
if (cmpPlayerEntityLimits)
cmpPlayerEntityLimits.UpdateLimitsFromTech(tech);
- // always send research finished message
+ // Always send research finished message
Engine.PostMessage(this.entity, MT_ResearchFinished, {"player": playerID, "tech": tech});
for (var component in modifiedComponents)
@@ -329,6 +329,18 @@
Engine.PostMessage(SYSTEM_ENTITY, MT_TemplateModification, { "player": playerID, "component": component, "valueNames": modifiedComponents[component]});
Engine.BroadcastMessage(MT_ValueModification, { "entities": ents, "component": component, "valueNames": modifiedComponents[component]});
}
+
+ // Send a notification when the research of phase is finished
+ 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
@@ -398,12 +410,6 @@
return false;
};
-// Get all techs that are currently being researched
-TechnologyManager.prototype.GetTechsStarted = function()
-{
- return this.researchStarted;
-};
-
// Gets the entity currently researching a technology
TechnologyManager.prototype.GetResearcher = function(tech)
{
@@ -423,7 +429,8 @@
{
return this.researchQueued;
};
-TechnologyManager.prototype.GetStartedResearch = function()
+// Get all techs that are currently being researched
+TechnologyManager.prototype.GetStartedTechs = function()
{
return this.researchStarted;
};
Index: binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js
===================================================================
--- binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js
+++ binaries/data/mods/public/simulation/components/tests/test_GuiInterface.js
@@ -124,7 +124,7 @@
AddMock(100, IID_TechnologyManager, {
IsTechnologyResearched: function(tech) { if (tech == "phase_village") return true; else return false; },
GetQueuedResearch: function() { return {}; },
- GetStartedResearch: function() { return {}; },
+ GetStartedTechs: function() { return {}; },
GetResearchedTechs: function() { return {}; },
GetClassCounts: function() { return {}; },
GetTypeCountsByClass: function() { return {}; },
@@ -210,7 +210,7 @@
AddMock(101, IID_TechnologyManager, {
IsTechnologyResearched: function(tech) { if (tech == "phase_village") return true; else return false; },
GetQueuedResearch: function() { return {}; },
- GetStartedResearch: function() { return {}; },
+ GetStartedTechs: function() { return {}; },
GetResearchedTechs: function() { return {}; },
GetClassCounts: function() { return {}; },
GetTypeCountsByClass: function() { return {}; },