Tuesday, December 4, 2007

Creating chat rooms for TGE 1.5






Creating chat rooms for TGE 1.5







Basic Information

Author: JuanMa (Nov 21, 2007)








Synopsis:

This tutorial will explain how to create simple in-game chat rooms
using torque script only. It mods the way MessageVector and
GuiMessageVectorCtrl are used in the original version of the
starter.fps game to manage the global chat only. This will not allow
you to dynamically create chat rooms in game or private chat rooms
managed by one user, though the idea of this resource is to provide
some basic understanding on how the chat works and how it could be mod
hoping that the community will take this idea to work on top of it and
create better and cooler resources. If you have any idea how to make
this resource better I will appreciate any comments.







Keywords:

ChatRoom chat room onChatMessage clientCmdChatMessage MessageVector HudMessageVector ChatHud






Article:

Open the file chatHud.cs right after the new
MessageVector(HudMessageVector); add the following code:

// All messages are stored in this HudMessageVector, the actual
// MainChatHud only displays the contents of this vector.

new MessageVector(HudMessageVector);
new MessageVector(HudMessageVectorGlobal);
new MessageVector(HudMessageVectorRoomA);
new MessageVector(HudMessageVectorRoomB);
new MessageVector(HudMessageVectorRoomC);
$LastHudTarget = 0;
$ChatRoom = HudMessageVector;
$ChatSelector = "g";
$ChatText = "GLOBAL:";

// this is a gui elements in chatHud.gui
$ChatHud = ChatHud;

function changeChat(%chatSelector){
$ChatSelector = %chatSelector;

if( %chatSelector $= "g" ){
$ChatRoom = HudMessageVector;

ChatHud.setVisible(true);
ChatRoomA.setVisible(false);
ChatRoomB.setVisible(false);
ChatRoomC.setVisible(false);
$ChatHud = ChatHud;
$ChatText = "GLOBAL:";
}
else if( %chatSelector $= "a" ){
$ChatRoom = HudMessageVectorRoomA;
ChatHud.setVisible(false);
ChatRoomA.setVisible(true);
ChatRoomB.setVisible(false);
ChatRoomC.setVisible(false);

$ChatHud = ChatRoomA;
$ChatText = "ROOM A:";
}
else if( %chatSelector $= "b" ){
$ChatRoom = HudMessageVectorRoomB;
ChatHud.setVisible(false);
ChatRoomA.setVisible(false);
ChatRoomB.setVisible(true);
ChatRoomC.setVisible(false);

$ChatHud = ChatRoomB;
$ChatText = "ROOM B:";
}
else if( %chatSelector $= "c" ){
$ChatRoom = HudMessageVectorRoomC;
ChatHud.setVisible(false);
ChatRoomA.setVisible(false);
ChatRoomB.setVisible(false);
ChatRoomC.setVisible(true);

$ChatHud = ChatRoomC;
$ChatText = "ROOM C:";
}
}


In this same file ChatHud.cs make the following changes:

Change
all the HudMessageVector with $ChatRoom or $HudMessageVector or any
variable name you feel comfortable using and all the ChatHud with
$ChatHud in the whole file, this will enable us to instead of
Using a single object we will use a "pointer" (the global variable) to the object so we can change it at any time.

Example:


while( !chatPageDown.isVisible() && HudMessageVector.getNumLines() && 
(HudMessageVector.getNumLines() >= $pref::HudMessageLogSize))


Should look like this.

while( !chatPageDown.isVisible() && $ChatRoom.getNumLines() && ($ChatRoom.getNumLines() 
>= $pref::HudMessageLogSize))




In the function onChatMessage add an extra parameter %chatWindow


function onChatMessage(%message, %voice, %pitch, %chatWindow){...}


and replace the whole if statement

 // Chat goes to the chat HUD.
if (getWordCount(%message)) {...}


with

   // Chat goes to the chat HUD.
if (getWordCount(%message)) {
// save the current variables
// to keep using them later
%tempChatHud = $ChatHud;
%tempHudMessageVect = $ChatRoom;

if( %chatWindow $= "g" ){
$ChatRoom = HudMessageVector;
$ChatHud = ChatHud;
}
else if( %chatWindow $= "a" ){
$ChatRoom = HudMessageVectorRoomA;
$ChatHud = ChatRoomA;
}
else if( %chatWindow $= "b" ){
$ChatRoom = HudMessageVectorRoomB;
$ChatHud = ChatRoomB;
}
else if( %chatWindow $= "c" ){
$ChatRoom = HudMessageVectorRoomC;
$ChatHud = ChatRoomC;
}
$ChatHud.addLine(%message);

$ChatHud = %tempChatHud;
$ChatRoom = %tempHudMessageVect;
}


Add at the end of the file. these are copies of ChatHud you will have to add one for work
For each chatRoomX that you have



//-----------------------------------------------------------------------------
// ChatRoomA methods
// This is the actual message vector/text control which is part of
// the MainChatHud dialog
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

function ChatRoomA::addLine(%this,%text)
{
//first, see if we're "scrolled up"...
%textHeight = %this.profile.fontSize;
if (%textHeight <= 0)
%textHeight = 12;
%chatScrollHeight = getWord(%this.getGroup().getGroup().extent, 1);
%chatPosition = getWord(%this.extent, 1) - %chatScrollHeight +
getWord(%this.position, 1);
%linesToScroll = mFloor((%chatPosition / %textHeight) + 0.5);
if (%linesToScroll > 0)
%origPosition = %this.position;

//add the message...
while( !chatPageDown.isVisible() && $ChatRoom.getNumLines() &&
($ChatRoom.getNumLines() >= $pref::HudMessageLogSize))
{
%tag = $ChatRoom.getLineTag(0);
if(%tag != 0)
%tag.delete();
$ChatRoom.popFrontLine();
}
$ChatRoom.pushBackLine(%text, $LastHudTarget);
$LastHudTarget = 0;

//now that we've added the message, see if we need to reset the position
if (%linesToScroll > 0)
{
chatPageDown.setVisible(true);
%this.position = %origPosition;
}
else
chatPageDown.setVisible(false);
}


//-----------------------------------------------------------------------------

function ChatRoomA::pageUp(%this)
{
// Find out the text line height
%textHeight = %this.profile.fontSize;
if (%textHeight <= 0)
%textHeight = 12;

// Find out how many lines per page are visible
%chatScrollHeight = getWord(%this.getGroup().getGroup().extent, 1);
if (%chatScrollHeight <= 0)
return;

%pageLines = mFloor(%chatScrollHeight / %textHeight) - 1;
if (%pageLines <= 0)
%pageLines = 1;

// See how many lines we actually can scroll up:
%chatPosition = -1 * getWord(%this.position, 1);
%linesToScroll = mFloor((%chatPosition / %textHeight) + 0.5);
if (%linesToScroll <= 0)
return;

if (%linesToScroll > %pageLines)
%scrollLines = %pageLines;
else
%scrollLines = %linesToScroll;

// Now set the position
%this.position = firstWord(%this.position) SPC (getWord(%this.position, 1) +
(%scrollLines * %textHeight));

// Display the pageup icon
chatPageDown.setVisible(true);
}


//-----------------------------------------------------------------------------

function ChatRoomA::pageDown(%this)
{
// Find out the text line height
%textHeight = %this.profile.fontSize;
if (%textHeight <= 0)
%textHeight = 12;

// Find out how many lines per page are visible
%chatScrollHeight = getWord(%this.getGroup().getGroup().extent, 1);
if (%chatScrollHeight <= 0)
return;

%pageLines = mFloor(%chatScrollHeight / %textHeight) - 1;
if (%pageLines <= 0)
%pageLines = 1;

// See how many lines we actually can scroll down:
%chatPosition = getWord(%this.extent, 1) - %chatScrollHeight +
getWord(%this.position, 1);
%linesToScroll = mFloor((%chatPosition / %textHeight) + 0.5);
if (%linesToScroll <= 0)
return;

if (%linesToScroll > %pageLines)
%scrollLines = %pageLines;
else
%scrollLines = %linesToScroll;

// Now set the position
%this.position = firstWord(%this.position) SPC (getWord(%this.position, 1) -
(%scrollLines * %textHeight));

// See if we have should (still) display the pagedown icon
if (%scrollLines < %linesToScroll)
chatPageDown.setVisible(true);
else
chatPageDown.setVisible(false);
}


Now add 4 buttons and 3 GuiMessageVectorCtrl in chatHud.gui this is not the whole code,
Just the part that adds the buttons and the GuiMessageVectorCtrl

...
new GuiControl() {
canSaveDynamicFields = "0";
Profile = "GuiDefaultProfile";
HorizSizing = "relative";
VertSizing = "bottom";
position = "0 0";
Extent = "640 300";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
hovertime = "1000";

new GuiButtonCtrl(Global) {
canSaveDynamicFields = "0";
Profile = "GuiButtonProfile";
HorizSizing = "left";
VertSizing = "bottom";
position = "515 6";
Extent = "38 14";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "changeChat(\"g\");";
hovertime = "1000";
text = "Glob";
groupNum = "-1";
buttonType = "PushButton";
};
new GuiButtonCtrl(RoomA) {
canSaveDynamicFields = "0";
Profile = "GuiButtonProfile";
HorizSizing = "left";
VertSizing = "bottom";
position = "515 21";
Extent = "38 14";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "changeChat(\"a\");";
hovertime = "1000";
text = "RoomA";
groupNum = "-1";
buttonType = "PushButton";
};
new GuiButtonCtrl(RoomB) {
canSaveDynamicFields = "0";
Profile = "GuiButtonProfile";
HorizSizing = "left";
VertSizing = "bottom";
position = "515 36";
Extent = "38 14";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "changeChat(\"b\");";
hovertime = "1000";
text = "RoomB";
groupNum = "-1";
buttonType = "PushButton";
};
new GuiButtonCtrl(RoomC) {
canSaveDynamicFields = "0";
Profile = "GuiButtonProfile";
HorizSizing = "left";
VertSizing = "bottom";
position = "515 51";
Extent = "38 14";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "changeChat(\"c\");";
hovertime = "1000";
text = "RoomC";
groupNum = "-1";
buttonType = "PushButton";
};
new GuiBitmapBorderCtrl(OuterChatHud) {
canSaveDynamicFields = "0";
Profile = "ChatHudBorderProfile";
HorizSizing = "width";
VertSizing = "bottom";
position = "0 0";
Extent = "512 72";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
hovertime = "1000";

new GuiBitmapCtrl() {
canSaveDynamicFields = "0";
Profile = "GuiDefaultProfile";
HorizSizing = "width";
VertSizing = "height";
position = "8 8";
Extent = "496 56";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
hovertime = "1000";
bitmap = "./hudfill.png";
wrap = "0";
};
new GuiButtonCtrl(ChatPageDown) {
canSaveDynamicFields = "0";
Profile = "GuiButtonProfile";
HorizSizing = "left";
VertSizing = "top";
position = "460 42";
Extent = "36 14";
MinExtent = "8 8";
canSave = "1";
Visible = "0";
hovertime = "1000";
text = "Dwn";
groupNum = "-1";
buttonType = "PushButton";
};
new GuiScrollCtrl(ChatScrollHud) {
canSaveDynamicFields = "0";
Profile = "ChatHudScrollProfile";
HorizSizing = "width";
VertSizing = "height";
position = "8 8";
Extent = "496 56";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
willFirstRespond = "1";
hScrollBar = "alwaysOff";
vScrollBar = "alwaysOff";
constantThumbHeight = "0";
childMargin = "0 0";

new GuiMessageVectorCtrl(ChatHud) {
canSaveDynamicFields = "0";
Profile = "ChatHudMessageProfile";
HorizSizing = "width";
VertSizing = "height";
position = "1 -382";
Extent = "492 16";
MinExtent = "8 8";
canSave = "1";
Visible = "1";
lineSpacing = "0";
lineContinuedIndex = "10";
allowedMatches[0] = "http";
allowedMatches[1] = "tgeserver";
matchColor = "0 0 255 255";
maxColorIndex = "5";
};
new GuiMessageVectorCtrl(ChatRoomA) {
canSaveDynamicFields = "0";
Profile = "ChatHudMessageProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "1 1";
Extent = "492 53";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
lineSpacing = "0";
lineContinuedIndex = "10";
allowedMatches[0] = "http";
allowedMatches[1] = "tgeserver";
matchColor = "0 0 255 255";
maxColorIndex = "9";
};
new GuiMessageVectorCtrl(ChatRoomB) {
canSaveDynamicFields = "0";
Profile = "ChatHudMessageProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "0 0";
Extent = "497 57";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
lineSpacing = "0";
lineContinuedIndex = "10";
allowedMatches[0] = "http";
allowedMatches[1] = "tgeserver";
matchColor = "0 0 255 255";
maxColorIndex = "9";
};
new GuiMessageVectorCtrl(ChatRoomC) {
canSaveDynamicFields = "0";
Profile = "ChatHudMessageProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "0 0";
Extent = "496 56";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
lineSpacing = "0";
lineContinuedIndex = "10";
allowedMatches[0] = "http";
allowedMatches[1] = "tgeserver";
matchColor = "0 0 255 255";
maxColorIndex = "9";
};
};
};
...


In the file messageHud.cs in the function

function MessageHud_Edit::eval(%this){...} 


around line 87 add one parameter to the commandToServer

      if(MessageHud.isTeamMsg)
commandToServer('teamMessageSent', %text);
else
******* commandToServer('messageSent', %text, $ChatSelector);




In the file common/client/message.cs change the function clientCmdChatMessage with this

function clientCmdChatMessage(%sender, %voice, %pitch, %msgString, %a1, %a2, %a3, %a4, 
%a5, %a6, %a7, %a8, %a9, %a10)
{
onChatMessage(detag(%msgString), %voice, %pitch, %a3);
}


Ok
so we are done with the client side, at this point if you start your
game you should see a chat window with four buttons on the side, if you
choose any of these buttons the screen should change. we do not have to
mod the server because thankfuly we are using one of the extra
paramenters that the messaging system has available :) and there for
the parameter of which chat room the message should go to has been
passed all the way back to each client that recieves the message and
has been taken care of in clientCmdChatMessage.

If you want to know where the messages are handled in the server go to
common/server/commands.cs and look at the function serverCmdMessageSent(%client, %text, 
%chatSelector){...}


Hope this will help someone.

JuanMa




No comments: