From a3eccc043d2e29eb81b360e98decac0dc013c0d5 Mon Sep 17 00:00:00 2001 From: Imarok Date: Tue, 12 Jan 2021 19:13:16 +0000 Subject: [PATCH] Hint the location for "You have been attacked" notifications Icon edited by Stan. Fixes: #5132 Differential Revision: https://code.wildfiregames.com/D1461 This was SVN commit r24565. --- .../ui/session/icons/focus-attacked.png | 3 + .../data/mods/public/gui/page_session.xml | 1 + .../public/gui/session/chat/ChatHistory.js | 2 +- .../session/chat/ChatMessageFormatNetwork.js | 64 +++++++------- .../session/chat/ChatMessageFormatPlayer.js | 14 ++-- .../chat/ChatMessageFormatSimulation.js | 84 ++++++++++++------- .../gui/session/chat/ChatMessageHandler.js | 6 +- .../public/gui/session/chat/ChatOverlay.js | 45 ++++++++-- .../data/mods/public/gui/session/messages.js | 3 + .../data/mods/public/gui/session/session.xml | 8 +- .../data/mods/public/gui/session/setup.xml | 7 ++ .../data/mods/public/gui/session/styles.xml | 2 +- 12 files changed, 162 insertions(+), 77 deletions(-) create mode 100644 binaries/data/mods/public/art/textures/ui/session/icons/focus-attacked.png create mode 100644 binaries/data/mods/public/gui/session/setup.xml diff --git a/binaries/data/mods/public/art/textures/ui/session/icons/focus-attacked.png b/binaries/data/mods/public/art/textures/ui/session/icons/focus-attacked.png new file mode 100644 index 0000000000..3429a0037c --- /dev/null +++ b/binaries/data/mods/public/art/textures/ui/session/icons/focus-attacked.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb47fcae34e98c65b86165bfb6118c3a79d198c5b04ac221296b259c849fc55d +size 5082 diff --git a/binaries/data/mods/public/gui/page_session.xml b/binaries/data/mods/public/gui/page_session.xml index 88d361219c..040840fb9c 100644 --- a/binaries/data/mods/public/gui/page_session.xml +++ b/binaries/data/mods/public/gui/page_session.xml @@ -10,6 +10,7 @@ common/sprites.xml common/styles.xml + session/setup.xml session/sprites.xml session/styles.xml session/session.xml diff --git a/binaries/data/mods/public/gui/session/chat/ChatHistory.js b/binaries/data/mods/public/gui/session/chat/ChatHistory.js index b39c335637..7c1c84d4f4 100644 --- a/binaries/data/mods/public/gui/session/chat/ChatHistory.js +++ b/binaries/data/mods/public/gui/session/chat/ChatHistory.js @@ -57,7 +57,7 @@ class ChatHistory { // Save to chat history let historical = { - "txt": formatted, + "txt": formatted.text, "timePrefix": sprintf(translate("\\[%(time)s]"), { "time": Engine.FormatMillisecondsIntoDateStringLocal(Date.now(), translate("HH:mm")) }), diff --git a/binaries/data/mods/public/gui/session/chat/ChatMessageFormatNetwork.js b/binaries/data/mods/public/gui/session/chat/ChatMessageFormatNetwork.js index e16f93710d..e9cd0973ce 100644 --- a/binaries/data/mods/public/gui/session/chat/ChatMessageFormatNetwork.js +++ b/binaries/data/mods/public/gui/session/chat/ChatMessageFormatNetwork.js @@ -9,7 +9,7 @@ ChatMessageFormatNetwork.clientlist = class { parse() { - return getUsernameList(); + return { "text": getUsernameList() }; } }; @@ -17,13 +17,15 @@ ChatMessageFormatNetwork.connect = class { 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 @@ ChatMessageFormatNetwork.disconnect = class { 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 @@ ChatMessageFormatNetwork.kicked = class { 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 @@ ChatMessageFormatNetwork.rejoined = class { 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) }) + }; } }; diff --git a/binaries/data/mods/public/gui/session/chat/ChatMessageFormatPlayer.js b/binaries/data/mods/public/gui/session/chat/ChatMessageFormatPlayer.js index d0dfd83ba0..ef1649965c 100644 --- a/binaries/data/mods/public/gui/session/chat/ChatMessageFormatPlayer.js +++ b/binaries/data/mods/public/gui/session/chat/ChatMessageFormatPlayer.js @@ -54,12 +54,14 @@ class ChatMessageFormatPlayer // 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 }) + }) + }; } /** diff --git a/binaries/data/mods/public/gui/session/chat/ChatMessageFormatSimulation.js b/binaries/data/mods/public/gui/session/chat/ChatMessageFormatSimulation.js index 52f0e85950..f7eed88903 100644 --- a/binaries/data/mods/public/gui/session/chat/ChatMessageFormatSimulation.js +++ b/binaries/data/mods/public/gui/session/chat/ChatMessageFormatSimulation.js @@ -13,12 +13,22 @@ ChatMessageFormatSimulation.attack = class 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 @@ ChatMessageFormatSimulation.barter = class 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 @@ ChatMessageFormatSimulation.diplomacy = class 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 @@ ChatMessageFormatSimulation.phase = class 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 @@ ChatMessageFormatSimulation.playerstate = class 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 @@ ChatMessageFormatSimulation.tribute = class 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) + }) + }; } }; diff --git a/binaries/data/mods/public/gui/session/chat/ChatMessageHandler.js b/binaries/data/mods/public/gui/session/chat/ChatMessageHandler.js index 60f8e3d354..62be3468f9 100644 --- a/binaries/data/mods/public/gui/session/chat/ChatMessageHandler.js +++ b/binaries/data/mods/public/gui/session/chat/ChatMessageHandler.js @@ -68,9 +68,9 @@ class ChatMessageHandler 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; diff --git a/binaries/data/mods/public/gui/session/chat/ChatOverlay.js b/binaries/data/mods/public/gui/session/chat/ChatOverlay.js index d764ed8d2e..9bc3947331 100644 --- a/binaries/data/mods/public/gui/session/chat/ChatOverlay.js +++ b/binaries/data/mods/public/gui/session/chat/ChatOverlay.js @@ -8,7 +8,7 @@ class ChatOverlay /** * 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 @@ class ChatOverlay 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 @@ class ChatOverlay 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 @@ class ChatOverlay clearChatMessages() { this.chatMessages = []; - this.chatText.caption = ""; + this.displayChatMessages(); for (let timer of this.chatTimers) clearTimeout(timer); @@ -64,6 +99,6 @@ class ChatOverlay clearTimeout(this.chatTimers[0]); this.chatTimers.shift(); this.chatMessages.shift(); - this.chatText.caption = this.chatMessages.join("\n"); + this.displayChatMessages(); } } diff --git a/binaries/data/mods/public/gui/session/messages.js b/binaries/data/mods/public/gui/session/messages.js index 5cf5fdad7f..b6f1b1765d 100644 --- a/binaries/data/mods/public/gui/session/messages.js +++ b/binaries/data/mods/public/gui/session/messages.js @@ -193,10 +193,13 @@ var g_NotificationsTypes = 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 }); }, diff --git a/binaries/data/mods/public/gui/session/session.xml b/binaries/data/mods/public/gui/session/session.xml index c8028481cf..2faef197c6 100644 --- a/binaries/data/mods/public/gui/session/session.xml +++ b/binaries/data/mods/public/gui/session/session.xml @@ -40,8 +40,12 @@ - - + + + + diff --git a/binaries/data/mods/public/gui/session/setup.xml b/binaries/data/mods/public/gui/session/setup.xml new file mode 100644 index 0000000000..e3d2bb5da1 --- /dev/null +++ b/binaries/data/mods/public/gui/session/setup.xml @@ -0,0 +1,7 @@ + + + + diff --git a/binaries/data/mods/public/gui/session/styles.xml b/binaries/data/mods/public/gui/session/styles.xml index 57dd2cb35a..3ae2ccc0e8 100644 --- a/binaries/data/mods/public/gui/session/styles.xml +++ b/binaries/data/mods/public/gui/session/styles.xml @@ -237,7 +237,7 @@ font="sans-bold-stroke-14" textcolor="white" text_align="left" - text_valign="top" + text_valign="center" />