Index: ps/trunk/binaries/data/mods/public/gui/page_session.xml =================================================================== --- ps/trunk/binaries/data/mods/public/gui/page_session.xml +++ ps/trunk/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 Index: ps/trunk/binaries/data/mods/public/gui/session/chat/ChatHistory.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/session/chat/ChatHistory.js +++ ps/trunk/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: ps/trunk/binaries/data/mods/public/gui/session/chat/ChatMessageFormatNetwork.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/session/chat/ChatMessageFormatNetwork.js +++ ps/trunk/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: ps/trunk/binaries/data/mods/public/gui/session/chat/ChatMessageFormatPlayer.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/session/chat/ChatMessageFormatPlayer.js +++ ps/trunk/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: ps/trunk/binaries/data/mods/public/gui/session/chat/ChatMessageFormatSimulation.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/session/chat/ChatMessageFormatSimulation.js +++ ps/trunk/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: ps/trunk/binaries/data/mods/public/gui/session/chat/ChatMessageHandler.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/session/chat/ChatMessageHandler.js +++ ps/trunk/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: ps/trunk/binaries/data/mods/public/gui/session/chat/ChatOverlay.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/session/chat/ChatOverlay.js +++ ps/trunk/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: 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 @@ -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: ps/trunk/binaries/data/mods/public/gui/session/session.xml =================================================================== --- ps/trunk/binaries/data/mods/public/gui/session/session.xml +++ ps/trunk/binaries/data/mods/public/gui/session/session.xml @@ -40,8 +40,12 @@ - - + + + + Index: ps/trunk/binaries/data/mods/public/gui/session/setup.xml =================================================================== --- ps/trunk/binaries/data/mods/public/gui/session/setup.xml +++ ps/trunk/binaries/data/mods/public/gui/session/setup.xml @@ -0,0 +1,7 @@ + + + + Index: ps/trunk/binaries/data/mods/public/gui/session/styles.xml =================================================================== --- ps/trunk/binaries/data/mods/public/gui/session/styles.xml +++ ps/trunk/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" />