Changeset View
Standalone View
binaries/data/mods/public/gui/gamesetup/gamesetup.js
Show All 38 Lines | "kicked": msg => addChatMessage({ | ||||
"username": msg.username | "username": msg.username | ||||
}), | }), | ||||
"chat": msg => addChatMessage({ "type": "chat", "guid": msg.guid, "text": msg.text }) | "chat": msg => addChatMessage({ "type": "chat", "guid": msg.guid, "text": msg.text }) | ||||
}; | }; | ||||
const g_FormatChatMessage = { | const g_FormatChatMessage = { | ||||
"system": (msg, user) => systemMessage(msg.text), | "system": (msg, user) => systemMessage(msg.text), | ||||
"settings": (msg, user) => systemMessage(translate('Game settings have been changed')), | "settings": (msg, user) => systemMessage(translate('Game settings have been changed')), | ||||
"connect": (msg, user) => systemMessage(sprintf(translate("%(username)s has joined"), { "username": user })), | "connect": (msg, user) => systemMessage(sprintf(translate("%(username)s has joined"), { "username": user })), | ||||
elexis: That color is unacceptably ugly. Perhaps `150 150 250` | |||||
"disconnect": (msg, user) => systemMessage(sprintf(translate("%(username)s has left"), { "username": user })), | "disconnect": (msg, user) => systemMessage(sprintf(translate("%(username)s has left"), { "username": user })), | ||||
Not Done Inline ActionsYou removed the check but didn't add the empty string here, sounds like breakage elexis: You removed the check but didn't add the empty string here, sounds like breakage | |||||
"kicked": (msg, user) => systemMessage(sprintf(translate("%(username)s has been kicked"), { "username": user })), | "kicked": (msg, user) => systemMessage(sprintf(translate("%(username)s has been kicked"), { "username": user })), | ||||
"banned": (msg, user) => systemMessage(sprintf(translate("%(username)s has been banned"), { "username": user })), | "banned": (msg, user) => systemMessage(sprintf(translate("%(username)s has been banned"), { "username": user })), | ||||
"chat": (msg, user) => sprintf(translate("%(username)s %(message)s"), { | "chat": (msg, user) => sprintf(translate("%(username)s %(message)s"), { | ||||
"username": senderFont(sprintf(translate("<%(username)s>"), { "username": user })), | "username": senderFont(sprintf(translate("<%(username)s>"), { "username": user })), | ||||
"message": escapeText(msg.text || "") | "message": escapeText(msg.text || "") | ||||
}), | }), | ||||
"ready": (msg, user) => sprintf(translate("* %(username)s is ready!"), { | "ready": (msg, user) => g_ReadyData[msg.status] && g_ReadyData[msg.status].chat && | ||||
elexisUnsubmitted Not Done Inline ActionsThe first check seems okay, if the intention is to mute errors sent by a trollhost. But in that case the g_PlayerAssignments[guid].status].color should also have a check. If we don't care about trollhosts, then this check can be removed. I'd prefer to remove the second check and add an empty string to the global array, so it's more obvious that nothing will be printed in that case and that the array always has all properties. elexis: The first check seems okay, if the intention is to mute errors sent by a trollhost. But in that… | |||||
elexisUnsubmitted Not Done Inline ActionsFirst check should still be removed as the patch doesn't care about trollhosts otherwise elexis: First check should still be removed as the patch doesn't care about trollhosts otherwise | |||||
"username": user | sprintf(g_ReadyData[msg.status].chat, { "username": user }), | ||||
}), | |||||
"not-ready": (msg, user) => sprintf(translate("* %(username)s is not ready."), { | |||||
"username": user | |||||
}), | |||||
"clientlist": (msg, user) => getUsernameList() | "clientlist": (msg, user) => getUsernameList() | ||||
}; | }; | ||||
/** | /** | ||||
* The dropdownlist items will appear in the order they are added. | * The dropdownlist items will appear in the order they are added. | ||||
*/ | */ | ||||
const g_MapFilters = [ | const g_MapFilters = [ | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | |||||
const g_UnassignedColor = "140 140 140"; | const g_UnassignedColor = "140 140 140"; | ||||
/** | /** | ||||
* Highlight observer players in the dropdownlist. | * Highlight observer players in the dropdownlist. | ||||
*/ | */ | ||||
const g_UnassignedPlayerColor = "170 170 250"; | const g_UnassignedPlayerColor = "170 170 250"; | ||||
/** | /** | ||||
* Highlight ready players. | * Containing the colors to highlight the ready status of players, | ||||
*/ | * the chat ready messages | ||||
const g_ReadyColor = "green"; | * and the tooltips and captions for the ready button | ||||
elexisUnsubmitted Not Done Inline Actions(would move the "and" to the line above, since that's also the place where the comma would be placed) elexis: (would move the "and" to the line above, since that's also the place where the comma would be… | |||||
*/ | |||||
const g_ReadyData = [ | |||||
elexisUnsubmitted Not Done Inline ActionsBetter move it above g_FormatChatMessage, so that it's defined before being refered to (though only a code style thing, since the format chat functions won't be executed before the ready data is defined) elexis: Better move it above `g_FormatChatMessage`, so that it's defined before being refered to… | |||||
{ | |||||
"color": "", | |||||
"chat": translate("* %(username)s is not ready."), | |||||
"caption": translate("I'm ready"), | |||||
"tooltip": translate("State that you are ready to play!") | |||||
elexisUnsubmitted Not Done Inline Actions! -> . elexis: ! -> .
Perhaps it should also or instead state that the player accepts the settings.
| |||||
}, { | |||||
elexisUnsubmitted Not Done Inline Actions\n after the comma elexis: \n after the comma
| |||||
"color": "green", | |||||
"chat": translate("* %(username)s is ready!"), | |||||
"caption": translate("Stay ready"), | |||||
"tooltip": translate("Stay ready even when the game settings change.") | |||||
elexisUnsubmitted Not Done Inline ActionsStay ready comma elexis: Stay ready comma | |||||
ImarokAuthorUnsubmitted Not Done Inline Actionssure? Imarok: sure? | |||||
elexisUnsubmitted Not Done Inline ActionsNo, but it appears to be a https://en.wikipedia.org/wiki/Conjunction_(grammar)#Subordinating_conjunctions elexis: No, but it appears to be a https://en.wikipedia.org/wiki/Conjunction_… | |||||
ImarokAuthorUnsubmitted Not Done Inline Actionsyeah and between main clause and subordinate clause comes no comma. Imarok: yeah and between main clause and subordinate clause comes no comma. | |||||
elexisUnsubmitted Not Done Inline Actionsthanks for looking it up :) elexis: thanks for looking it up :) | |||||
}, { | |||||
"color": "blue", | |||||
"caption": translate("I'm not ready!"), | |||||
"tooltip": translate("State that you are not ready to play.") | |||||
}]; | |||||
elexisUnsubmitted Not Done Inline Actions\n after } elexis: \n after } | |||||
/** | /** | ||||
* Placeholder item for the map-dropdownlist. | * Placeholder item for the map-dropdownlist. | ||||
*/ | */ | ||||
const g_RandomMap = '[color="' + g_ColorRandom + '"]' + translateWithContext("map selection", "Random") + "[/color]"; | const g_RandomMap = '[color="' + g_ColorRandom + '"]' + translateWithContext("map selection", "Random") + "[/color]"; | ||||
/** | /** | ||||
* Placeholder item for the civ-dropdownlists. | * Placeholder item for the civ-dropdownlists. | ||||
Show All 19 Lines | |||||
/** | /** | ||||
* States whether the GUI is currently updated in response to network messages instead of user input | * States whether the GUI is currently updated in response to network messages instead of user input | ||||
* and therefore shouldn't send further messages to the network. | * and therefore shouldn't send further messages to the network. | ||||
*/ | */ | ||||
var g_IsInGuiUpdate; | var g_IsInGuiUpdate; | ||||
/** | /** | ||||
* Whether the current player is ready to start the game. | * Whether the current player is ready to start the game. | ||||
* 0 - not ready | |||||
* 1 - ready | |||||
* 2 - stay ready | |||||
*/ | */ | ||||
var g_IsReady; | var g_IsReady; | ||||
/** | /** | ||||
* Ignore duplicate ready commands on init. | * Ignore duplicate ready commands on init. | ||||
*/ | */ | ||||
var g_ReadyInit = true; | var g_ReadyInit = true; | ||||
▲ Show 20 Lines • Show All 518 Lines • ▼ Show 20 Lines | |||||
/** | /** | ||||
* Called whenever a client clicks on ready (or not ready). | * Called whenever a client clicks on ready (or not ready). | ||||
* @param {Object} message | * @param {Object} message | ||||
*/ | */ | ||||
function handleReadyMessage(message) | function handleReadyMessage(message) | ||||
{ | { | ||||
--g_ReadyChanged; | --g_ReadyChanged; | ||||
if (g_ReadyChanged < 1 && g_PlayerAssignments[message.guid].player != -1) | if (g_ReadyChanged < 1 && g_PlayerAssignments[message.guid].player != -1 && message.status < 2) | ||||
Done Inline ActionsIt were preferable to not hardcode the design decision to not display changes to stay-ready here. Improvement: Stay-Ready chat message, can be done in a separate simple ticket. However if we display a stay-ready chatmessage, then we will get one more chat message if people doubeclick (which might occur often). elexis: It were preferable to not hardcode the design decision to not display changes to stay-ready… | |||||
Not Done Inline ActionsThe < 2 check is unneeded, right? as that function will return an empty string and that wont print anything elexis: The < 2 check is unneeded, right? as that function will return an empty string and that wont… | |||||
addChatMessage({ | addChatMessage({ | ||||
"type": message.status == 1 ? "ready" : "not-ready", | "type": "ready", | ||||
"status": message.status, | |||||
Done Inline ActionsThis g_FormatChatMessage could just be "ready", the status could be passed as an argument and the translated strings could be moved to the proposed array below. When not implementing the timer proposed above, g_FormatChatMessage can return an empty string for the stay-ready case for now to still remove both hardcodings. elexis: This `g_FormatChatMessage` could just be "ready", the status could be passed as an argument and… | |||||
"guid": message.guid | "guid": message.guid | ||||
}); | }); | ||||
if (!g_IsController) | if (!g_IsController) | ||||
return; | return; | ||||
g_PlayerAssignments[message.guid].status = +message.status == 1; | g_PlayerAssignments[message.guid].status = +message.status == 1; | ||||
updateReadyUI(); | updateReadyUI(); | ||||
▲ Show 20 Lines • Show All 1,095 Lines • ▼ Show 20 Lines | function addChatMessage(msg) | ||||
if (!g_FormatChatMessage[msg.type]) | if (!g_FormatChatMessage[msg.type]) | ||||
return; | return; | ||||
let user = colorizePlayernameByGUID(msg.guid || -1, msg.username || ""); | let user = colorizePlayernameByGUID(msg.guid || -1, msg.username || ""); | ||||
let text = g_FormatChatMessage[msg.type](msg, user); | let text = g_FormatChatMessage[msg.type](msg, user); | ||||
if (!text) | |||||
return; | |||||
if (Engine.ConfigDB_GetValue("user", "chat.timestamp") == "true") | if (Engine.ConfigDB_GetValue("user", "chat.timestamp") == "true") | ||||
text = sprintf(translate("%(time)s %(message)s"), { | text = sprintf(translate("%(time)s %(message)s"), { | ||||
"time": sprintf(translate("\\[%(time)s]"), { | "time": sprintf(translate("\\[%(time)s]"), { | ||||
"time": Engine.FormatMillisecondsIntoDateString(new Date().getTime(), translate("HH:mm")) | "time": Engine.FormatMillisecondsIntoDateString(new Date().getTime(), translate("HH:mm")) | ||||
}), | }), | ||||
"message": text | "message": text | ||||
}); | }); | ||||
Show All 21 Lines | function resetTeams() | ||||
for (let i in g_GameAttributes.settings.PlayerData) | for (let i in g_GameAttributes.settings.PlayerData) | ||||
g_GameAttributes.settings.PlayerData[i].Team = -1; | g_GameAttributes.settings.PlayerData[i].Team = -1; | ||||
updateGameAttributes(); | updateGameAttributes(); | ||||
} | } | ||||
function toggleReady() | function toggleReady() | ||||
{ | { | ||||
setReady(!g_IsReady); | setReady((g_IsReady + 1) % 3); | ||||
Done Inline ActionsI guess the only reason we have that function is to not add a global ref to the XML file. elexis: I guess the only reason we have that function is to not add a global ref to the XML file. | |||||
Not Done Inline Actionsprobably Imarok: probably | |||||
} | } | ||||
function setReady(ready, sendMessage = true) | function setReady(ready, sendMessage = true) | ||||
{ | { | ||||
g_IsReady = ready; | g_IsReady = ready; | ||||
if (sendMessage) | if (sendMessage) | ||||
Engine.SendNetworkReady(+g_IsReady); | Engine.SendNetworkReady(+g_IsReady); | ||||
if (g_IsController) | if (g_IsController) | ||||
return; | return; | ||||
let button = Engine.GetGUIObjectByName("startGame"); | let button = Engine.GetGUIObjectByName("startGame"); | ||||
button.caption = g_ReadyData[+g_IsReady].caption; | |||||
button.caption = g_IsReady ? | button.tooltip = g_ReadyData[+g_IsReady].tooltip; | ||||
Done Inline ActionsWe don't construct these constant arrays again and again but init them only once. It could become a global array with 3 elements, each being an object with caption and tooltip. While at it move the colors there as well. elexis: We don't construct these constant arrays again and again but init them only once. It could… | |||||
translate("I'm not ready!") : | |||||
translate("I'm ready"); | |||||
button.tooltip = g_IsReady ? | |||||
translate("State that you are not ready to play.") : | |||||
translate("State that you are ready to play!"); | |||||
} | } | ||||
function updateReadyUI() | function updateReadyUI() | ||||
{ | { | ||||
if (!g_IsNetworked) | if (!g_IsNetworked) | ||||
return; | return; | ||||
let isAI = new Array(g_MaxPlayers + 1).fill(true); | let isAI = new Array(g_MaxPlayers + 1).fill(true); | ||||
let allReady = true; | let allReady = true; | ||||
for (let guid in g_PlayerAssignments) | for (let guid in g_PlayerAssignments) | ||||
{ | { | ||||
// We don't really care whether observers are ready. | // We don't really care whether observers are ready. | ||||
if (g_PlayerAssignments[guid].player == -1 || !g_GameAttributes.settings.PlayerData[g_PlayerAssignments[guid].player - 1]) | if (g_PlayerAssignments[guid].player == -1 || !g_GameAttributes.settings.PlayerData[g_PlayerAssignments[guid].player - 1]) | ||||
continue; | continue; | ||||
let pData = g_GameAttributes.settings.PlayerData ? g_GameAttributes.settings.PlayerData[g_PlayerAssignments[guid].player - 1] : {}; | let pData = g_GameAttributes.settings.PlayerData ? g_GameAttributes.settings.PlayerData[g_PlayerAssignments[guid].player - 1] : {}; | ||||
let pDefs = g_DefaultPlayerData ? g_DefaultPlayerData[g_PlayerAssignments[guid].player - 1] : {}; | let pDefs = g_DefaultPlayerData ? g_DefaultPlayerData[g_PlayerAssignments[guid].player - 1] : {}; | ||||
isAI[g_PlayerAssignments[guid].player] = false; | isAI[g_PlayerAssignments[guid].player] = false; | ||||
if (g_PlayerAssignments[guid].status || !g_IsNetworked) | if (g_PlayerAssignments[guid].status) | ||||
Engine.GetGUIObjectByName("playerName[" + (g_PlayerAssignments[guid].player - 1) + "]").caption = '[color="' + g_ReadyColor + '"]' + translate(getSetting(pData, pDefs, "Name")) + '[/color]'; | Engine.GetGUIObjectByName("playerName[" + (g_PlayerAssignments[guid].player - 1) + "]").caption = | ||||
Not Done Inline ActionsTrailing space elexis: Trailing space | |||||
'[color="' + g_ReadyData[+g_PlayerAssignments[guid].status].color + '"]' + | |||||
translate(getSetting(pData, pDefs, "Name")) + '[/color]'; | |||||
else | else | ||||
{ | { | ||||
Engine.GetGUIObjectByName("playerName[" + (g_PlayerAssignments[guid].player - 1) + "]").caption = translate(getSetting(pData, pDefs, "Name")); | Engine.GetGUIObjectByName("playerName[" + (g_PlayerAssignments[guid].player - 1) + "]").caption = translate(getSetting(pData, pDefs, "Name")); | ||||
allReady = false; | allReady = false; | ||||
} | } | ||||
} | } | ||||
// AIs are always ready. | // AIs are always ready. | ||||
for (let playerid = 0; playerid < g_MaxPlayers; ++playerid) | for (let playerid = 0; playerid < g_MaxPlayers; ++playerid) | ||||
{ | { | ||||
if (!g_GameAttributes.settings.PlayerData[playerid]) | if (!g_GameAttributes.settings.PlayerData[playerid]) | ||||
continue; | continue; | ||||
let pData = g_GameAttributes.settings.PlayerData ? g_GameAttributes.settings.PlayerData[playerid] : {}; | let pData = g_GameAttributes.settings.PlayerData ? g_GameAttributes.settings.PlayerData[playerid] : {}; | ||||
let pDefs = g_DefaultPlayerData ? g_DefaultPlayerData[playerid] : {}; | let pDefs = g_DefaultPlayerData ? g_DefaultPlayerData[playerid] : {}; | ||||
if (isAI[playerid + 1]) | if (isAI[playerid + 1]) | ||||
Engine.GetGUIObjectByName("playerName[" + playerid + "]").caption = '[color="' + g_ReadyColor + '"]' + translate(getSetting(pData, pDefs, "Name")) + '[/color]'; | Engine.GetGUIObjectByName("playerName[" + playerid + "]").caption = | ||||
'[color="' + g_ReadyData[2].color + '"]' + translate(getSetting(pData, pDefs, "Name")) + '[/color]'; | |||||
} | } | ||||
// The host is not allowed to start until everyone is ready. | // The host is not allowed to start until everyone is ready. | ||||
if (g_IsNetworked && g_IsController) | if (g_IsNetworked && g_IsController) | ||||
{ | { | ||||
let startGameButton = Engine.GetGUIObjectByName("startGame"); | let startGameButton = Engine.GetGUIObjectByName("startGame"); | ||||
startGameButton.enabled = allReady; | startGameButton.enabled = allReady; | ||||
// Add a explanation on to the tooltip if disabled. | // Add a explanation on to the tooltip if disabled. | ||||
Show All 20 Lines | function resetReadyData() | ||||
g_ReadyChanged = 2; | g_ReadyChanged = 2; | ||||
if (!g_IsNetworked) | if (!g_IsNetworked) | ||||
g_IsReady = true; | g_IsReady = true; | ||||
else if (g_IsController) | else if (g_IsController) | ||||
{ | { | ||||
Engine.ClearAllPlayerReady(); | Engine.ClearAllPlayerReady(); | ||||
setReady(true); | setReady(true); | ||||
} | } | ||||
else | else if (g_IsReady != 2) | ||||
setReady(false, false); | setReady(false, false); | ||||
} | } | ||||
/** | /** | ||||
* Send a list of playernames and distinct between players and observers. | * Send a list of playernames and distinct between players and observers. | ||||
* Don't send teams, AIs or anything else until the game was started. | * Don't send teams, AIs or anything else until the game was started. | ||||
* The playerData format from g_GameAttributes is kept to reuse the GUI function presenting the data. | * The playerData format from g_GameAttributes is kept to reuse the GUI function presenting the data. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 58 Lines • Show Last 20 Lines |
That color is unacceptably ugly. Perhaps 150 150 250