Added Multi-player chat in menu and hotkey (return key)
Made player names match custom names in multi-player The chat window will still need some more aesthetic work This was SVN commit r7909.
This commit is contained in:
parent
54d9224918
commit
4cfca1625d
@ -190,6 +190,13 @@ hotkey.menu.toggle = "F10" ; Toggle in-game menu.
|
||||
hotkey.menu.resign = "Alt+X" ; End current game session and return to main menu.
|
||||
|
||||
; > HOTKEYS ONLY
|
||||
|
||||
|
||||
|
||||
hotkey.chat = Return ; Toggles chat window
|
||||
|
||||
|
||||
|
||||
hotkey.onlinehelp = "F1" ; Enable/disable online manual entry for current selection.
|
||||
hotkey.music.toggle = "M" ; Enable/disable music.
|
||||
hotkey.audio.toggle = "Ctrl+A" ; Enable/disable sound.
|
||||
|
@ -132,7 +132,7 @@ function handleNetMessage(message)
|
||||
break;
|
||||
|
||||
case "start":
|
||||
Engine.SwitchGuiPage("page_loading.xml", { "attribs": g_GameAttributes });
|
||||
Engine.SwitchGuiPage("page_loading.xml", { "attribs": g_GameAttributes, "isNetworked" : g_IsNetworked, "playerAssignments": g_PlayerAssignments});
|
||||
break;
|
||||
|
||||
case "chat":
|
||||
|
@ -1,9 +1,20 @@
|
||||
var g_Data;
|
||||
|
||||
function init(data)
|
||||
{
|
||||
var mapName = "map";
|
||||
if (data && data.attribs)
|
||||
mapName = data.attribs.map;
|
||||
|
||||
|
||||
|
||||
|
||||
if (data)
|
||||
g_Data = data;
|
||||
|
||||
|
||||
|
||||
|
||||
// Set to "hourglass" cursor.
|
||||
setCursor("cursor-wait");
|
||||
|
||||
@ -45,7 +56,7 @@ function reallyStartGame()
|
||||
// to start the game (i.e. loading progress has reached 100%).
|
||||
|
||||
// Switch GUI from loading screen to game session.
|
||||
Engine.SwitchGuiPage("page_session_new.xml");
|
||||
Engine.SwitchGuiPage("page_session_new.xml", g_Data);
|
||||
|
||||
// Restore default cursor.
|
||||
setCursor ("arrow-default");
|
||||
|
@ -39,3 +39,18 @@ function toggleMenu()
|
||||
else
|
||||
getGUIObjectByName("menu").hidden = true; // Hide menu
|
||||
}
|
||||
|
||||
function toggleChatWindow()
|
||||
{
|
||||
if (getGUIObjectByName("chatWindow").hidden)
|
||||
{
|
||||
getGUIObjectByName("chatInput").focus();
|
||||
getGUIObjectByName("chatWindow").hidden = false; // View chat
|
||||
}
|
||||
else
|
||||
{
|
||||
getGUIObjectByName("chatWindow").hidden = true; // Hide chat
|
||||
}
|
||||
|
||||
getGUIObjectByName("menu").hidden = true; // Hide menu
|
||||
}
|
@ -29,21 +29,14 @@ function layoutSelectionSingle(entState)
|
||||
}
|
||||
|
||||
// Fills out information that most entities have
|
||||
function displayGeneralInfo(playerState, entState, template)
|
||||
function displayGeneralInfo(entState, template)
|
||||
{
|
||||
var civName = toTitleCase(playerState.civ);
|
||||
var color = playerState.color;
|
||||
var playerColor = color["r"]*255 + " " + color["g"]*255 + " " + color["b"]*255 + " " + color["a"]*255;
|
||||
var civName = toTitleCase(g_Players[entState.player].civ);
|
||||
var playerColor = g_Players[entState.player].color.r + " " + g_Players[entState.player].color.g + " " +
|
||||
g_Players[entState.player].color.b+ " " + g_Players[entState.player].color.a;
|
||||
|
||||
var iconTooltip = "";
|
||||
|
||||
// Rank Icon
|
||||
// var rankId = getRankCellId(entState);
|
||||
// getGUIObjectByName("sdRankIcon").cell_id = rankId;
|
||||
|
||||
// Rank Title
|
||||
// var rankText = getRankTitle(getRankCellId(entState.template));
|
||||
// rankText = (rankText? rankText : "");
|
||||
|
||||
// Specific Name
|
||||
var name = template.name.specific + getRankTitle(getRankCellId(entState.template));
|
||||
getGUIObjectByName("sdSpecific").caption = name;
|
||||
@ -56,7 +49,7 @@ function displayGeneralInfo(playerState, entState, template)
|
||||
getGUIObjectByName("sdSpecific").tooltip = "";
|
||||
|
||||
// Player Name
|
||||
getGUIObjectByName("sdPlayer").caption = playerState.name;
|
||||
getGUIObjectByName("sdPlayer").caption = g_Players[entState.player].name;
|
||||
getGUIObjectByName("sdPlayer").tooltip = getFormalCivName(civName);
|
||||
getGUIObjectByName("sdPlayer").textcolor = playerColor;
|
||||
|
||||
@ -130,7 +123,7 @@ function displayGeneralInfo(playerState, entState, template)
|
||||
}
|
||||
|
||||
// Updates middle entity Selection Details Panel
|
||||
function updateSelectionDetails(simState)
|
||||
function updateSelectionDetails()
|
||||
{
|
||||
var detailsPanel = getGUIObjectByName("selectionDetails");
|
||||
var commandsPanel = getGUIObjectByName("unitCommands");
|
||||
@ -152,10 +145,6 @@ function updateSelectionDetails(simState)
|
||||
if (!entState)
|
||||
return;
|
||||
|
||||
var playerState = simState.players[entState.player];
|
||||
if (!playerState)
|
||||
return;
|
||||
|
||||
// Choose the highest ranked version of the primary selection
|
||||
// Different selection details are shown based on whether multiple units or a single unit is selected
|
||||
if (selection.length > 1)
|
||||
@ -166,7 +155,7 @@ function updateSelectionDetails(simState)
|
||||
var template = Engine.GuiInterfaceCall("GetTemplateData", entState.template);
|
||||
|
||||
// Fill out general info and display it
|
||||
displayGeneralInfo(playerState, entState, template); // must come after layout functions
|
||||
displayGeneralInfo(entState, template); // must come after layout functions
|
||||
|
||||
// Show Panels
|
||||
detailsPanel.hidden = false;
|
||||
|
@ -2,7 +2,6 @@ const GEOLOGY = "geology";
|
||||
const FLORA = "flora";
|
||||
const FAUNA = "fauna";
|
||||
const SPECIAL = "special";
|
||||
const CAMP = "camp";
|
||||
|
||||
const GAIA = "Gaia"
|
||||
const CART = "Cart";
|
||||
@ -19,6 +18,17 @@ const CELTS = "Celts";
|
||||
const PERSIANS = "Persians";
|
||||
const IBERIANS = "Iberians";
|
||||
|
||||
// Chat data
|
||||
const maxNumChatLines = 30;
|
||||
var g_ChatMessages = [];
|
||||
var g_ChatTimers = [];
|
||||
|
||||
// Network Mode
|
||||
var g_IsNetworked = false;
|
||||
|
||||
// Cache the basic player data (name, civ, color)
|
||||
var g_Players = [];
|
||||
|
||||
// Cache dev-mode settings that are frequently or widely used
|
||||
var g_DevSettings = {
|
||||
controlAll: false
|
||||
@ -36,9 +46,55 @@ function init(initData, hotloadData)
|
||||
startMusic();
|
||||
}
|
||||
|
||||
if (initData)
|
||||
{
|
||||
g_IsNetworked = initData.isNetworked; // Set network mode
|
||||
g_Players = getPlayerData(initData.playerAssignments); // Cache the player data
|
||||
}
|
||||
|
||||
onSimulationUpdate();
|
||||
}
|
||||
|
||||
// Get the basic player data
|
||||
function getPlayerData(playerAssignments)
|
||||
{
|
||||
var players = [];
|
||||
|
||||
var simState = Engine.GuiInterfaceCall("GetSimulationState");
|
||||
if (!simState)
|
||||
return players;
|
||||
|
||||
for (var i = 0; i < simState.players.length; i++)
|
||||
{
|
||||
var playerState = simState.players[i];
|
||||
if (!playerState)
|
||||
continue;
|
||||
|
||||
var name = playerState.name;
|
||||
var civ = playerState.civ;
|
||||
var color = {"r": 255, "g": 255, "b": 255, "a": 255};
|
||||
color.r = playerState.color["r"]*255;
|
||||
color.g = playerState.color["g"]*255;
|
||||
color.b = playerState.color["b"]*255;
|
||||
color.a = playerState.color["a"]*255;
|
||||
|
||||
var player = {"name": name, "civ": civ, "color": color};
|
||||
players.push(player);
|
||||
}
|
||||
|
||||
var i = 1;
|
||||
if (playerAssignments)
|
||||
{
|
||||
for each (var playerAssignment in playerAssignments)
|
||||
{
|
||||
players[i].name = playerAssignment.name;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return players;
|
||||
}
|
||||
|
||||
function leaveGame()
|
||||
{
|
||||
stopMusic();
|
||||
@ -75,16 +131,97 @@ function handleNetMessage(message)
|
||||
obj.hidden = false;
|
||||
// TODO: we need to give players some way to exit
|
||||
break;
|
||||
|
||||
default:
|
||||
error("Unrecognised netstatus type "+message.status);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "chat":
|
||||
addChatMessage({ "type": "message", "username": message.username, "text": message.text });
|
||||
break;
|
||||
default:
|
||||
error("Unrecognised net message type "+message.type);
|
||||
}
|
||||
}
|
||||
|
||||
function submitChatInput()
|
||||
{
|
||||
toggleChatWindow();
|
||||
|
||||
var input = getGUIObjectByName("chatInput");
|
||||
var text = input.caption;
|
||||
if (text.length)
|
||||
{
|
||||
if (g_IsNetworked)
|
||||
Engine.SendNetworkChat(text);
|
||||
else
|
||||
getGUIObjectByName("chatText").caption = "Chat is not currently supported in single player mode.";
|
||||
|
||||
input.caption = "";
|
||||
}
|
||||
}
|
||||
|
||||
function addChatMessage(msg)
|
||||
{
|
||||
// TODO: we ought to escape all values before displaying them,
|
||||
// to prevent people inserting colours and newlines etc
|
||||
|
||||
var playerColor;
|
||||
|
||||
for (var i = 0; i < g_Players.length; i++)
|
||||
{
|
||||
if (msg.username == g_Players[i].name)
|
||||
{
|
||||
playerColor = g_Players[i].color.r + " " + g_Players[i].color.g + " " + g_Players[i].color.b;
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var formatted;
|
||||
|
||||
switch (msg.type)
|
||||
{
|
||||
case "connect":
|
||||
formatted = '<[color="' + playerColor + '"]' + msg.username + '[/color]> [color="64 64 64"]has joined[/color]';
|
||||
break;
|
||||
|
||||
case "disconnect":
|
||||
formatted = '<[color="' + playerColor + '"]' + msg.username + '[/color]> [color="64 64 64"]has left[/color]';
|
||||
break;
|
||||
|
||||
case "message":
|
||||
formatted = '<[color="' + playerColor + '"]' + msg.username + '[/color]> ' + msg.text;
|
||||
break;
|
||||
|
||||
default:
|
||||
error("Invalid chat message '" + uneval(msg) + "'");
|
||||
return;
|
||||
}
|
||||
|
||||
var timerExpiredFunction = function () { removeOldChatMessages(); }
|
||||
|
||||
g_ChatMessages.push(formatted);
|
||||
g_ChatTimers.push(setTimeout(timerExpiredFunction, 30000));
|
||||
|
||||
if (g_ChatMessages.length > maxNumChatLines)
|
||||
{
|
||||
clearTimeout(g_ChatTimers[0]);
|
||||
g_ChatTimers.shift();
|
||||
g_ChatMessages.shift();
|
||||
}
|
||||
|
||||
getGUIObjectByName("chatText").caption = g_ChatMessages.join("\n");
|
||||
}
|
||||
|
||||
function removeOldChatMessages()
|
||||
{
|
||||
clearTimeout(g_ChatTimers[0]);
|
||||
g_ChatTimers.shift();
|
||||
g_ChatMessages.shift();
|
||||
getGUIObjectByName("chatText").caption = g_ChatMessages.join("\n");
|
||||
}
|
||||
|
||||
function onTick()
|
||||
{
|
||||
while (true)
|
||||
@ -125,7 +262,11 @@ function onSimulationUpdate()
|
||||
|
||||
updateDebug(simState);
|
||||
updatePlayerDisplay(simState);
|
||||
updateSelectionDetails(simState);
|
||||
updateSelectionDetails();
|
||||
|
||||
if (g_ChatTimers.length)
|
||||
console.write(g_ChatTimers[0]);
|
||||
|
||||
}
|
||||
|
||||
function updateDebug(simState)
|
||||
@ -161,7 +302,6 @@ function updateDebug(simState)
|
||||
function updatePlayerDisplay(simState)
|
||||
{
|
||||
var playerState = simState.players[Engine.GetPlayerID()];
|
||||
|
||||
if (!playerState)
|
||||
return;
|
||||
|
||||
|
@ -51,9 +51,14 @@
|
||||
]]></action>
|
||||
</object>
|
||||
|
||||
<!-- Depending on the current state, it either opens message window or closes message window / posts message -->
|
||||
<object hotkey="chat">
|
||||
<action on="Press">toggleChatWindow();</action>
|
||||
</object>
|
||||
|
||||
<!-- Delete button Hotkey (For some reason it won't work when the console is visible -->
|
||||
<object hotkey="killUnit">
|
||||
<action on="Press">performCommand(g_Selection.toList()[0], "delete")</action>
|
||||
<action on="Press">performCommand(g_Selection.toList()[0], "delete");</action>
|
||||
</object>
|
||||
|
||||
<!-- ================================ ================================ -->
|
||||
@ -119,6 +124,27 @@
|
||||
<action on="Press">togglePause();</action>
|
||||
</object>
|
||||
|
||||
<!-- ================================ ================================ -->
|
||||
<!-- Chat -->
|
||||
<!-- ================================ ================================ -->
|
||||
|
||||
<!-- Chat panel -->
|
||||
<object name="chatPanel" size="0 50 512 100%-200" type="image" ghost="true">
|
||||
<object name="chatText" size="3 1 100%-1 100%-25" type="text" style="chatPanel" ghost="true"/>
|
||||
</object>
|
||||
|
||||
<!-- Chat window -->
|
||||
<object name="chatWindow" size="50%-200 50%-13 50%+200 50%+13" type="image" sprite="wheatIndentFillLight" hidden="true" z="10">
|
||||
<object name="chatInput" size="2 100%-23 100%-66 100%-3" type="input" style="wheatInput" max_length="40">
|
||||
<action on="Press">submitChatInput();</action>
|
||||
</object>
|
||||
|
||||
<object size="100%-65 100%-25 100%-1 100%" type="button" style="wheatButton">
|
||||
Send
|
||||
<action on="Press">submitChatInput();</action>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<!-- ================================ ================================ -->
|
||||
<!-- Settings Window -->
|
||||
<!-- ================================ ================================ -->
|
||||
@ -127,7 +153,7 @@
|
||||
type="image"
|
||||
size="50%-180 50%-200 50%+180 50%+50"
|
||||
hidden="true"
|
||||
z="50"
|
||||
z="30"
|
||||
>
|
||||
<object name="settingsTitleBar" style="wheatWindowTitleBar" type="text">Settings</object>
|
||||
|
||||
@ -178,10 +204,11 @@
|
||||
<!-- Menu Details -->
|
||||
<!-- ================================ ================================ -->
|
||||
<object name="menu"
|
||||
size="0 0 114 128"
|
||||
size="0 0 114 160"
|
||||
type="image"
|
||||
sprite="menuBackground"
|
||||
hidden="true"
|
||||
z="20"
|
||||
>
|
||||
<!-- Settings button -->
|
||||
<object type="button"
|
||||
@ -194,14 +221,25 @@
|
||||
<action on="Press">toggleSettingsWindow();</action>
|
||||
</object>
|
||||
|
||||
<!-- Chat button -->
|
||||
<object type="button"
|
||||
name="chatButton"
|
||||
style="wheatButtonFancy"
|
||||
size="0 64 114 96"
|
||||
tooltip_style="snToolTip"
|
||||
>
|
||||
<object size="0 0 100% 100%" type="text" style="centeredText" name="chatButtonText" ghost="true">Chat</object>
|
||||
<action on="Press">toggleChatWindow();</action>
|
||||
</object>
|
||||
|
||||
<!-- Pause Button -->
|
||||
<object type="button"
|
||||
style="wheatButtonFancy"
|
||||
name="pauseButton"
|
||||
size="0 64 114 96"
|
||||
size="0 96 114 128"
|
||||
tooltip_style="snToolTip"
|
||||
>
|
||||
<object size="0 0 100% 100%" type="text" ghost="true" style="centeredText">Pause Game</object>
|
||||
<object size="0 0 100% 100%" type="text" ghost="true" style="centeredText">Pause</object>
|
||||
<action on="Press">togglePause();</action>
|
||||
</object>
|
||||
|
||||
@ -209,10 +247,10 @@
|
||||
<object type="button"
|
||||
name="exitButton"
|
||||
style="wheatButtonFancy"
|
||||
size="0 96 114 128"
|
||||
size="0 128 114 160"
|
||||
tooltip_style="snToolTip"
|
||||
>
|
||||
<object size="0 0 100% 100%" type="text" style="centeredText" name="exitButtonText" ghost="true" font="serif-14">Quit Game</object>
|
||||
<object size="0 0 100% 100%" type="text" style="centeredText" name="exitButtonText" ghost="true" font="serif-14">Quit</object>
|
||||
<action on="Press">
|
||||
toggleMenu();
|
||||
<![CDATA[messageBox(400, 200, "Do you really want to quit?", "Confirmation", 0, ["Yes", "No!"], [leaveGame, null]);]]>
|
||||
@ -226,6 +264,7 @@
|
||||
style="wheatButtonFancy"
|
||||
size="0 0 114 32"
|
||||
tooltip_style="snToolTip"
|
||||
z="30"
|
||||
>
|
||||
<object size="0 0 100% 100%" type="text" style="largeBoldCenteredText" name="menuButtonText" ghost="true">Menu</object>
|
||||
<action on="Press">toggleMenu();</action>
|
||||
|
@ -146,4 +146,13 @@
|
||||
sprite="netStatusBackground"
|
||||
/>
|
||||
|
||||
<style name="chatPanel"
|
||||
buffer_zone="5"
|
||||
font="serif-bold-13"
|
||||
textcolor="white"
|
||||
textcolor_selected="white"
|
||||
text_align="left"
|
||||
text_valign="top"
|
||||
/>
|
||||
|
||||
</styles>
|
||||
|
Loading…
Reference in New Issue
Block a user