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 @@ -10,6 +10,7 @@ /** * Maximum number of lines to display simultaneously. + * When changing that, also adapt the number inside chatPanel in session.xml. */ var g_ChatLines = 20; @@ -98,42 +99,51 @@ }; var g_FormatChatMessage = { - "system": msg => msg.text, - "connect": msg => - 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) } - ), - "disconnect": msg => - sprintf(translate("%(player)s has left the game."), { - "player": colorizePlayernameByGUID(msg.guid) - }), - "rejoined": msg => - 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) } - ), - "kicked": msg => - 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) - ) - } - ), - "clientlist": msg => getUsernameList(), + "system": msg => { + return {"text": msg.text }; + }, + "connect": msg => { + 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) } + )}; + }, + "disconnect": msg => { + return { "text": sprintf(translate("%(player)s has left the game."), { + "player": colorizePlayernameByGUID(msg.guid) + })}; + }, + "rejoined": msg => { + 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) } + )}; + }, + "kicked": msg => { + 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) + ) + } + ) + }; + }, + "clientlist": msg => { + return { "text": getUsernameList() }; + }, "message": msg => formatChatCommand(msg), "defeat-victory": msg => formatDefeatVictoryMessage(msg.message, msg.players), "diplomacy": msg => formatDiplomacyMessage(msg), @@ -405,6 +415,7 @@ "type": "attack", "player": player, "attacker": notification.attacker, + "target": notification.target, "targetIsDomesticAnimal": notification.targetIsDomesticAnimal }); }, @@ -901,6 +912,43 @@ submitChatDirectly(text); } +function showChatMessages() +{ + const leftMargin = 3; + const buttonMargin = 2; + for (let i = 0 ; i < g_ChatLines; ++i) + { + let chatLine = Engine.GetGUIObjectByName("chatLine[" + i + "]"); + let chatLineButton = Engine.GetGUIObjectByName("chatLineButton[" + i + "]"); + if (g_ChatMessages[i] && g_ChatMessages[i].text) + { + let lineSize = chatLine.size; + let height = lineSize.bottom - lineSize.top; + lineSize.top = 1 + i * height; + lineSize.bottom = 1 + (i + 1) * height; + lineSize.left = leftMargin + (!!g_ChatMessages[i].target && height); + chatLine.size= lineSize; + chatLine.caption = g_ChatMessages[i].text; + + if (g_ChatMessages[i].target) + { + let buttonSize = chatLineButton.size; + buttonSize.left = leftMargin + buttonMargin; + buttonSize.right = leftMargin + height - buttonMargin; + buttonSize.top = lineSize.top + buttonMargin; + buttonSize.bottom = lineSize.top + height - buttonMargin; + chatLineButton.size = buttonSize; + chatLineButton.onPress = (t => function() { + warn(t); + setCameraFollow(t); + })(g_ChatMessages[i].target); + } + } + chatLine.hidden = !g_ChatMessages[i] || !g_ChatMessages[i].text; + chatLineButton.hidden = !g_ChatMessages[i] || !g_ChatMessages[i].target; + } +} + /** * Displays the prepared chatmessage. * @@ -912,7 +960,7 @@ return; let formatted = g_FormatChatMessage[msg.type](msg); - if (!formatted) + if (!formatted || !formatted.text) return; // Update chat overlay @@ -922,11 +970,11 @@ if (g_ChatMessages.length > g_ChatLines) removeOldChatMessage(); else - Engine.GetGUIObjectByName("chatText").caption = g_ChatMessages.join("\n"); + showChatMessages(); // Save to chat history let historical = { - "txt": formatted, + "txt": formatted.text, "timePrefix": sprintf(translate("\\[%(time)s]"), { "time": Engine.FormatMillisecondsIntoDateStringLocal(Date.now(), translate("HH:mm")) }), @@ -950,7 +998,7 @@ clearTimeout(g_ChatTimers[0]); g_ChatTimers.shift(); g_ChatMessages.shift(); - Engine.GetGUIObjectByName("chatText").caption = g_ChatMessages.join("\n"); + showChatMessages(); } /** @@ -988,18 +1036,18 @@ function formatDefeatVictoryMessage(message, players) { if (!message.pluralMessage) - return sprintf(translate(message), { + return { "text": sprintf(translate(message), { "player": colorizePlayernameByID(players[0]) - }); + })}; let mPlayers = players.map(playerID => colorizePlayernameByID(playerID)); let lastPlayer = mPlayers.pop(); - return sprintf(translatePlural(message.message, message.pluralMessage, message.pluralCount), { + return { "text": sprintf(translatePlural(message.message, message.pluralMessage, message.pluralCount), { // Translation: This comma is used for separating first to penultimate elements in an enumeration. "players": mPlayers.join(translate(", ")), "lastPlayer": lastPlayer - }); + })}; } function formatDiplomacyMessage(msg) @@ -1015,10 +1063,10 @@ else return ""; - return sprintf(g_DiplomacyMessages[messageType][msg.status], { + return { "text": sprintf(g_DiplomacyMessages[messageType][msg.status], { "player": colorizePlayernameByID(messageType == "active" ? msg.targetPlayer : msg.sourcePlayer), "player2": colorizePlayernameByID(messageType == "active" ? msg.sourcePlayer : msg.targetPlayer) - }); + })}; } /** @@ -1038,11 +1086,11 @@ g_Players[msg.targetPlayer].isMutualAlly[Engine.GetPlayerID()])) message = translate("%(player)s has sent %(player2)s %(amounts)s."); - return sprintf(message, { + return { "text": sprintf(message, { "player": colorizePlayernameByID(msg.sourcePlayer), "player2": colorizePlayernameByID(msg.targetPlayer), "amounts": getLocalizedResourceAmounts(msg.amounts) - }); + })}; } function formatBarterMessage(msg) @@ -1056,11 +1104,11 @@ let amountsBought = {}; amountsBought[msg.resourceBought] = msg.amountsBought; - return sprintf(translate("%(player)s bartered %(amountsBought)s for %(amountsSold)s."), { + return { "text": sprintf(translate("%(player)s bartered %(amountsBought)s for %(amountsSold)s."), { "player": colorizePlayernameByID(msg.player), "amountsBought": getLocalizedResourceAmounts(amountsBought), "amountsSold": getLocalizedResourceAmounts(amountsSold) - }); + })}; } function formatAttackMessage(msg) @@ -1072,9 +1120,9 @@ translate("Your livestock has been attacked by %(attacker)s!") : translate("You have been attacked by %(attacker)s!"); - return sprintf(message, { + return { "target": msg.target, "text": sprintf(message, { "attacker": colorizePlayernameByID(msg.attacker) - }); + })}; } function formatPhaseMessage(msg) @@ -1094,10 +1142,10 @@ if (msg.phaseState == "completed") message = translate("%(player)s has reached the %(phaseName)s."); - return sprintf(message, { + return { "text": sprintf(message, { "player": colorizePlayernameByID(msg.player), "phaseName": getEntityNames(GetTechnologyData(msg.phaseName, g_Players[msg.player].civ)) - }); + })}; } function formatChatCommand(msg) @@ -1140,12 +1188,12 @@ // GUID for players, playerID for AIs let coloredUsername = msg.guid != -1 ? colorizePlayernameByGUID(msg.guid) : colorizePlayernameByID(msg.player); - return sprintf(g_ChatCommands[isMe ? "me" : "regular"][msg.context ? "context" : "no-context"], { + return { "text": sprintf(g_ChatCommands[isMe ? "me" : "regular"][msg.context ? "context" : "no-context"], { "message": msg.text, "context": msg.context || undefined, "user": coloredUsername, "userTag": sprintf(translate("<%(user)s>"), { "user": coloredUsername }) - }); + })}; } /** 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 @@ -78,8 +78,11 @@ - - + + +