Index: binaries/data/mods/public/gui/page_session.xml
===================================================================
--- binaries/data/mods/public/gui/page_session.xml
+++ binaries/data/mods/public/gui/page_session.xml
@@ -9,6 +9,7 @@
common/sprites.xml
common/styles.xml
+ session/setup.xml
session/sprites.xml
session/styles.xml
session/session.xml
Index: binaries/data/mods/public/gui/session/chat/ChatHistory.js
===================================================================
--- binaries/data/mods/public/gui/session/chat/ChatHistory.js
+++ binaries/data/mods/public/gui/session/chat/ChatHistory.js
@@ -57,7 +57,7 @@
{
// Save to chat history
let historical = {
- "txt": formatted,
+ "txt": formatted.text,
"timePrefix": sprintf(translate("\\[%(time)s]"), {
"time": Engine.FormatMillisecondsIntoDateStringLocal(Date.now(), translate("HH:mm"))
}),
Index: binaries/data/mods/public/gui/session/chat/ChatMessageFormatNetwork.js
===================================================================
--- binaries/data/mods/public/gui/session/chat/ChatMessageFormatNetwork.js
+++ binaries/data/mods/public/gui/session/chat/ChatMessageFormatNetwork.js
@@ -9,7 +9,7 @@
{
parse()
{
- return getUsernameList();
+ return { "text": getUsernameList() };
}
};
@@ -17,13 +17,15 @@
{
parse(msg)
{
- return sprintf(
- g_PlayerAssignments[msg.guid].player != -1 ?
- // Translation: A player that left the game joins again
- translate("%(player)s is starting to rejoin the game.") :
- // Translation: A player joins the game for the first time
- translate("%(player)s is starting to join the game."),
- { "player": colorizePlayernameByGUID(msg.guid) });
+ return {
+ "text": sprintf(
+ g_PlayerAssignments[msg.guid].player != -1 ?
+ // Translation: A player that left the game joins again
+ translate("%(player)s is starting to rejoin the game.") :
+ // Translation: A player joins the game for the first time
+ translate("%(player)s is starting to join the game."),
+ { "player": colorizePlayernameByGUID(msg.guid) })
+ };
}
};
@@ -31,9 +33,11 @@
{
parse(msg)
{
- return sprintf(translate("%(player)s has left the game."), {
- "player": colorizePlayernameByGUID(msg.guid)
- });
+ return {
+ "text": sprintf(translate("%(player)s has left the game."), {
+ "player": colorizePlayernameByGUID(msg.guid)
+ })
+ };
}
};
@@ -41,16 +45,18 @@
{
parse(msg)
{
- return sprintf(
- msg.banned ?
- translate("%(username)s has been banned") :
- translate("%(username)s has been kicked"),
- {
- "username": colorizePlayernameHelper(
- msg.username,
- g_Players.findIndex(p => p.name == msg.username)
- )
- });
+ return {
+ "text": sprintf(
+ msg.banned ?
+ translate("%(username)s has been banned") :
+ translate("%(username)s has been kicked"),
+ {
+ "username": colorizePlayernameHelper(
+ msg.username,
+ g_Players.findIndex(p => p.name == msg.username)
+ )
+ })
+ };
}
};
@@ -58,12 +64,14 @@
{
parse(msg)
{
- return sprintf(
- g_PlayerAssignments[msg.guid].player != -1 ?
- // Translation: A player that left the game joins again
- translate("%(player)s has rejoined the game.") :
- // Translation: A player joins the game for the first time
- translate("%(player)s has joined the game."),
- { "player": colorizePlayernameByGUID(msg.guid) });
+ return {
+ "text": sprintf(
+ g_PlayerAssignments[msg.guid].player != -1 ?
+ // Translation: A player that left the game joins again
+ translate("%(player)s has rejoined the game.") :
+ // Translation: A player joins the game for the first time
+ translate("%(player)s has joined the game."),
+ { "player": colorizePlayernameByGUID(msg.guid) })
+ };
}
};
Index: binaries/data/mods/public/gui/session/chat/ChatMessageFormatPlayer.js
===================================================================
--- binaries/data/mods/public/gui/session/chat/ChatMessageFormatPlayer.js
+++ binaries/data/mods/public/gui/session/chat/ChatMessageFormatPlayer.js
@@ -54,12 +54,14 @@
// GUID for players, playerID for AIs
let coloredUsername = msg.guid != -1 ? colorizePlayernameByGUID(msg.guid) : colorizePlayernameByID(msg.player);
- return sprintf(translate(this.strings[isMe ? "me" : "regular"][msg.context ? "context" : "no-context"]), {
- "message": msg.text,
- "context": msg.context ? translateWithContext("chat message context", msg.context) : "",
- "user": coloredUsername,
- "userTag": sprintf(translate("<%(user)s>"), { "user": coloredUsername })
- });
+ return {
+ "text": sprintf(translate(this.strings[isMe ? "me" : "regular"][msg.context ? "context" : "no-context"]), {
+ "message": msg.text,
+ "context": msg.context ? translateWithContext("chat message context", msg.context) : "",
+ "user": coloredUsername,
+ "userTag": sprintf(translate("<%(user)s>"), { "user": coloredUsername })
+ })
+ };
}
/**
Index: binaries/data/mods/public/gui/session/chat/ChatMessageFormatSimulation.js
===================================================================
--- binaries/data/mods/public/gui/session/chat/ChatMessageFormatSimulation.js
+++ binaries/data/mods/public/gui/session/chat/ChatMessageFormatSimulation.js
@@ -13,12 +13,22 @@
return "";
let message = msg.targetIsDomesticAnimal ?
- translate("Your livestock has been attacked by %(attacker)s!") :
- translate("You have been attacked by %(attacker)s!");
+ translate("%(icon)sYour livestock has been attacked by %(attacker)s!") :
+ translate("%(icon)sYou have been attacked by %(attacker)s!");
- return sprintf(message, {
- "attacker": colorizePlayernameByID(msg.attacker)
- });
+ return {
+ "text": sprintf(message, {
+ "icon": '[icon="icon_focusattacked"]',
+ "attacker": colorizePlayernameByID(msg.attacker)
+ }),
+ "callback": ((entityId, position) => function() {
+ if (GetEntityState(entityId))
+ setCameraFollow(entityId);
+ else
+ Engine.SetCameraTarget(position.x, position.y, position.z);
+ })(msg.target, msg.position),
+ "tooltip": translate("Click to focus on the attacked unit.")
+ };
}
};
@@ -35,11 +45,13 @@
let amountGained = {};
amountGained[msg.resourceGained] = msg.amountGained;
- return sprintf(translate("%(player)s bartered %(amountGiven)s for %(amountGained)s."), {
- "player": colorizePlayernameByID(msg.player),
- "amountGiven": getLocalizedResourceAmounts(amountGiven),
- "amountGained": getLocalizedResourceAmounts(amountGained)
- });
+ return {
+ "text": sprintf(translate("%(player)s bartered %(amountGiven)s for %(amountGained)s."), {
+ "player": colorizePlayernameByID(msg.player),
+ "amountGiven": getLocalizedResourceAmounts(amountGiven),
+ "amountGained": getLocalizedResourceAmounts(amountGained)
+ })
+ };
}
};
@@ -58,10 +70,12 @@
else
return "";
- return sprintf(translate(this.strings[messageType][msg.status]), {
- "player": colorizePlayernameByID(messageType == "active" ? msg.targetPlayer : msg.sourcePlayer),
- "player2": colorizePlayernameByID(messageType == "active" ? msg.sourcePlayer : msg.targetPlayer)
- });
+ return {
+ "text": sprintf(translate(this.strings[messageType][msg.status]), {
+ "player": colorizePlayernameByID(messageType == "active" ? msg.targetPlayer : msg.sourcePlayer),
+ "player2": colorizePlayernameByID(messageType == "active" ? msg.sourcePlayer : msg.targetPlayer)
+ })
+ };
}
};
@@ -102,10 +116,12 @@
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))
- });
+ return {
+ "text": sprintf(message, {
+ "player": colorizePlayernameByID(msg.player),
+ "phaseName": getEntityNames(GetTechnologyData(msg.phaseName, g_Players[msg.player].civ))
+ })
+ };
}
};
@@ -114,18 +130,22 @@
parse(msg)
{
if (!msg.message.pluralMessage)
- return sprintf(translate(msg.message), {
- "player": colorizePlayernameByID(msg.players[0])
- });
+ return {
+ "text": sprintf(translate(msg.message), {
+ "player": colorizePlayernameByID(msg.players[0])
+ })
+ };
let mPlayers = msg.players.map(playerID => colorizePlayernameByID(playerID));
let lastPlayer = mPlayers.pop();
- return sprintf(translatePlural(msg.message.message, msg.message.pluralMessage, msg.message.pluralCount), {
- // Translation: This comma is used for separating first to penultimate elements in an enumeration.
- "players": mPlayers.join(translate(", ")),
- "lastPlayer": lastPlayer
- });
+ return {
+ "text": sprintf(translatePlural(msg.message.message, msg.message.pluralMessage, msg.message.pluralCount), {
+ // Translation: This comma is used for separating first to penultimate elements in an enumeration.
+ "players": mPlayers.join(translate(", ")),
+ "lastPlayer": lastPlayer
+ })
+ };
}
};
@@ -148,10 +168,12 @@
g_Players[msg.targetPlayer].isMutualAlly[Engine.GetPlayerID()]))
message = translate("%(player)s has sent %(player2)s %(amounts)s.");
- return sprintf(message, {
- "player": colorizePlayernameByID(msg.sourcePlayer),
- "player2": colorizePlayernameByID(msg.targetPlayer),
- "amounts": getLocalizedResourceAmounts(msg.amounts)
- });
+ return {
+ "text": sprintf(message, {
+ "player": colorizePlayernameByID(msg.sourcePlayer),
+ "player2": colorizePlayernameByID(msg.targetPlayer),
+ "amounts": getLocalizedResourceAmounts(msg.amounts)
+ })
+ };
}
};
Index: binaries/data/mods/public/gui/session/chat/ChatMessageHandler.js
===================================================================
--- binaries/data/mods/public/gui/session/chat/ChatMessageHandler.js
+++ binaries/data/mods/public/gui/session/chat/ChatMessageHandler.js
@@ -68,9 +68,9 @@
for (let messageFormat of this.messageFormats[msg.type])
{
- let txt = messageFormat.parse(msg);
- if (txt)
- return txt;
+ let formatted = messageFormat.parse(msg);
+ if (formatted)
+ return formatted;
}
return undefined;
Index: binaries/data/mods/public/gui/session/chat/ChatOverlay.js
===================================================================
--- binaries/data/mods/public/gui/session/chat/ChatOverlay.js
+++ binaries/data/mods/public/gui/session/chat/ChatOverlay.js
@@ -8,7 +8,7 @@
/**
* Maximum number of lines to display simultaneously.
*/
- this.chatLines = 20;
+ this.chatLinesNumber = 20;
/**
* Number of seconds after which chatmessages will disappear.
@@ -26,6 +26,41 @@
this.chatMessages = [];
this.chatText = Engine.GetGUIObjectByName("chatText");
+ this.chatLines = Engine.GetGUIObjectByName("chatLines").children;
+ this.chatLinesNumber = Math.min(this.chatLinesNumber, this.chatLines.length);
+ }
+
+ displayChatMessages()
+ {
+ for (let i = 0; i < this.chatLinesNumber; ++i)
+ {
+ let chatMessage = this.chatMessages[i];
+ if (chatMessage && chatMessage.text)
+ {
+ // First scale line width to maximum size.
+ let lineSize = this.chatLines[i].size;
+ let height = lineSize.bottom - lineSize.top;
+ lineSize.top = i * height;
+ lineSize.bottom = lineSize.top + height;
+ lineSize.rright = 100;
+ this.chatLines[i].size = lineSize;
+
+ this.chatLines[i].caption = chatMessage.text;
+
+ // Now read the actual text width and scale the line width accordingly.
+ lineSize.rright = 0;
+ lineSize.right = lineSize.left + this.chatLines[i].getTextSize().width;
+ this.chatLines[i].size = lineSize;
+
+ if (chatMessage.callback)
+ this.chatLines[i].onPress = chatMessage.callback;
+
+ if (chatMessage.tooltip)
+ this.chatLines[i].tooltip = chatMessage.tooltip;
+ }
+ this.chatLines[i].hidden = !chatMessage || !chatMessage.text;
+ this.chatLines[i].ghost = !chatMessage || !chatMessage.callback;
+ }
}
/**
@@ -36,10 +71,10 @@
this.chatMessages.push(chatMessage);
this.chatTimers.push(setTimeout(this.removeOldChatMessage.bind(this), this.chatTimeout * 1000));
- if (this.chatMessages.length > this.chatLines)
+ if (this.chatMessages.length > this.chatLinesNumber)
this.removeOldChatMessage();
else
- this.chatText.caption = this.chatMessages.join("\n");
+ this.displayChatMessages();
}
/**
@@ -48,7 +83,7 @@
clearChatMessages()
{
this.chatMessages = [];
- this.chatText.caption = "";
+ this.displayChatMessages();
for (let timer of this.chatTimers)
clearTimeout(timer);
@@ -64,6 +99,6 @@
clearTimeout(this.chatTimers[0]);
this.chatTimers.shift();
this.chatMessages.shift();
- this.chatText.caption = this.chatMessages.join("\n");
+ this.displayChatMessages();
}
}
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
@@ -193,10 +193,13 @@
if (Engine.ConfigDB_GetValue("user", "gui.session.notifications.attack") !== "true")
return;
+ let entState = GetEntityState(notification.target);
addChatMessage({
"type": "attack",
"player": player,
"attacker": notification.attacker,
+ "target": notification.target,
+ "position": entState && entState.position,
"targetIsDomesticAnimal": notification.targetIsDomesticAnimal
});
},
Index: binaries/data/mods/public/gui/session/session.xml
===================================================================
--- binaries/data/mods/public/gui/session/session.xml
+++ binaries/data/mods/public/gui/session/session.xml
@@ -39,8 +39,12 @@
-