404 lines
12 KiB
C#
404 lines
12 KiB
C#
|
//-----------------------------------------------------------------------------
|
||
|
// Torque Game Engine
|
||
|
//
|
||
|
// Copyright (c) 2001 GarageGames.Com
|
||
|
// Portions Copyright (c) 2001 by Sierra Online, Inc.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Message Hud
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
// chat hud sizes
|
||
|
$outerChatLenY[1] = 72;
|
||
|
$outerChatLenY[2] = 140;
|
||
|
$outerChatLenY[3] = 200;
|
||
|
|
||
|
// Only play sound files that are <= 5000ms in length.
|
||
|
$MaxMessageWavLength = 5000;
|
||
|
|
||
|
// Helper function to play a sound file if the message indicates.
|
||
|
// Returns starting position of wave file indicator.
|
||
|
function playMessageSound(%message, %voice, %pitch)
|
||
|
{
|
||
|
// Search for wav tag marker.
|
||
|
%wavStart = strstr(%message, "~w");
|
||
|
if (%wavStart == -1) {
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
%wav = getSubStr(%message, %wavStart + 2, 1000);
|
||
|
if (%voice !$= "") {
|
||
|
%wavFile = "~/data/sound/voice/" @ %voice @ "/" @ %wav;
|
||
|
}
|
||
|
else {
|
||
|
%wavFile = "~/data/sound/" @ %wav;
|
||
|
}
|
||
|
if (strstr(%wavFile, ".wav") != (strlen(%wavFile) - 4)) {
|
||
|
%wavFile = %wavFile @ ".wav";
|
||
|
}
|
||
|
// XXX This only expands to a single filepath, of course; it
|
||
|
// would be nice to support checking in each mod path if we
|
||
|
// have multiple mods active.
|
||
|
%wavFile = ExpandFilename(%wavFile);
|
||
|
|
||
|
if ((%pitch < 0.5) || (%pitch > 2.0)) {
|
||
|
%pitch = 1.0;
|
||
|
}
|
||
|
|
||
|
%wavLengthMS = alxGetWaveLen(%wavFile) * %pitch;
|
||
|
if (%wavLengthMS == 0) {
|
||
|
error("** WAV file \"" @ %wavFile @ "\" is nonexistent or sound is zero-length **");
|
||
|
}
|
||
|
else if (%wavLengthMS <= $MaxMessageWavLength) {
|
||
|
if ($ClientChatHandle[%sender] != 0) {
|
||
|
alxStop($ClientChatHandle[%sender]);
|
||
|
}
|
||
|
$ClientChatHandle[%sender] = alxCreateSource(AudioMessage, %wavFile);
|
||
|
if (%pitch != 1.0) {
|
||
|
alxSourcef($ClientChatHandle[%sender], "AL_PITCH", %pitch);
|
||
|
}
|
||
|
alxPlay($ClientChatHandle[%sender]);
|
||
|
}
|
||
|
else {
|
||
|
error("** WAV file \"" @ %wavFile @ "\" is too long **");
|
||
|
}
|
||
|
|
||
|
return %wavStart;
|
||
|
}
|
||
|
|
||
|
|
||
|
// All messages are stored in this HudMessageVector, the actual
|
||
|
// MainChatHud only displays the contents of this vector.
|
||
|
|
||
|
new MessageVector(HudMessageVector);
|
||
|
$LastHudTarget = 0;
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
function onChatMessage(%message, %voice, %pitch)
|
||
|
{
|
||
|
// XXX Client objects on the server must have voiceTag and voicePitch
|
||
|
// fields for values to be passed in for %voice and %pitch... in
|
||
|
// this example mod, they don't have those fields.
|
||
|
|
||
|
// Clients are not allowed to trigger general game sounds with their
|
||
|
// chat messages... a voice directory MUST be specified.
|
||
|
if (%voice $= "") {
|
||
|
%voice = "default";
|
||
|
}
|
||
|
|
||
|
// See if there's a sound at the end of the message, and play it.
|
||
|
if ((%wavStart = playMessageSound(%message, %voice, %pitch)) != -1) {
|
||
|
// Remove the sound marker from the end of the message.
|
||
|
%message = getSubStr(%message, 0, %wavStart);
|
||
|
}
|
||
|
|
||
|
// Chat goes to the chat HUD.
|
||
|
addChatLine(%message);
|
||
|
}
|
||
|
|
||
|
function chatFade(%fade)
|
||
|
{
|
||
|
ChatTextForeground.setAlpha(0.8 * %fade);
|
||
|
ChatTextBackground.setAlpha(%fade);
|
||
|
if(%fade > 0)
|
||
|
{
|
||
|
%nextFade = %fade - 0.03;
|
||
|
if(%nextFade < 0)
|
||
|
%nextFade = 0;
|
||
|
$ChatFadeTimer = schedule(32, 0, chatFade, %nextFade);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function addChatLine(%message)
|
||
|
{
|
||
|
if (getWordCount(%message)) {
|
||
|
%text = "<just:center><font:DomCasualD:32>" @ %message;
|
||
|
ChatTextBackground.setText("<color:000000>" @ %text);
|
||
|
ChatTextForeground.setText(%text);
|
||
|
|
||
|
cancel($ChatFadeTimer);
|
||
|
ChatTextForeground.setAlpha(0.8);
|
||
|
ChatTextBackground.setAlpha(1.0);
|
||
|
$ChatFadeTimer = schedule(3000, 0, chatFade, 1.0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
package GuiMLTextHelper
|
||
|
{
|
||
|
|
||
|
// strip out any <func:> tags and call the display func on them
|
||
|
function GuiMLTextCtrl::setText(%this, %text)
|
||
|
{
|
||
|
%start = 0;
|
||
|
while((%pos = strpos(%text, "<func:", %start)) != -1)
|
||
|
{
|
||
|
%end = strpos(%text, ">", %pos + 5);
|
||
|
if(%end == -1)
|
||
|
break;
|
||
|
|
||
|
%pre = getSubStr(%text, 0, %pos);
|
||
|
%post = getSubStr(%text, %end+1, 100000);
|
||
|
%func = getSubStr(%text, %pos + 6, %end - (%pos + 6));
|
||
|
%val = %this.evalTextFunc(%func);
|
||
|
%start = strlen(%val) + %pos;
|
||
|
%text = %pre @ %val @ %post;
|
||
|
}
|
||
|
Parent::setText(%this, %text);
|
||
|
}
|
||
|
|
||
|
};
|
||
|
|
||
|
activatePackage(GuiMLTextHelper);
|
||
|
|
||
|
function GuiMLTextCtrl::evalTextFunc(%this, %text)
|
||
|
{
|
||
|
%func = getWord(%text, 0);
|
||
|
switch$(%func)
|
||
|
{
|
||
|
case "bind":
|
||
|
%binding = moveMap.getBinding(getWord(%text, 1));
|
||
|
return getMapDisplayName(getField(%binding, 0), getField(%binding, 1), true);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function helpFade(%fade)
|
||
|
{
|
||
|
HelpTextForeground.setAlpha(1.0 * %fade);
|
||
|
HelpTextBackground.setAlpha(%fade);
|
||
|
if(%fade > 0)
|
||
|
{
|
||
|
%nextFade = %fade - 0.03;
|
||
|
if(%nextFade < 0)
|
||
|
%nextFade = 0;
|
||
|
$HelpFadeTimer = schedule(32, 0, helpFade, %nextFade);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function addHelpLine(%message, %playBeep)
|
||
|
{
|
||
|
if (getWordCount(%message)) {
|
||
|
%text = "<just:center><font:DomCasualD:32>" @ %message;
|
||
|
HelpTextBackground.setText("<color:000000>" @ %text);
|
||
|
HelpTextForeground.setText("<color:FFFFFF>" @ %text);
|
||
|
|
||
|
cancel($HelpFadeTimer);
|
||
|
HelpTextForeground.setAlpha(1.0);
|
||
|
HelpTextBackground.setAlpha(1.0);
|
||
|
$HelpFadeTimer = schedule(3000, 0, helpFade, 1.0);
|
||
|
}
|
||
|
if(%playBeep)
|
||
|
{
|
||
|
serverplay2d(HelpDingSfx);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function onServerMessage(%message)
|
||
|
{
|
||
|
// See if there's a sound at the end of the message, and play it.
|
||
|
if ((%wavStart = playMessageSound(%message)) != -1) {
|
||
|
// Remove the sound marker from the end of the message.
|
||
|
%message = getSubStr(%message, 0, %wavStart);
|
||
|
}
|
||
|
|
||
|
addChatLine(%message);
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// MainChatHud methods
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
function MainChatHud::onWake( %this )
|
||
|
{
|
||
|
// set the chat hud to the users pref
|
||
|
%this.setChatHudLength( $Pref::ChatHudLength );
|
||
|
}
|
||
|
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
|
||
|
function MainChatHud::setChatHudLength( %this, %length )
|
||
|
{
|
||
|
%outerChatLenX = firstWord(outerChatHud.extent);
|
||
|
%chatScrollLenX = firstWord(chatScrollHud.extent);
|
||
|
|
||
|
outerChatHud.extent = %outerChatLenX SPC $outerChatLenY[%length];
|
||
|
chatScrollHud.extent = %chatScrollLenX SPC $outerChatLenY[%length];
|
||
|
|
||
|
//find out how many lines per page are visible
|
||
|
%chatScrollHeight = getWord(chatHud.getGroup().getGroup().extent, 1);
|
||
|
if (%chatScrollHeight <= 0)
|
||
|
return;
|
||
|
|
||
|
%textHeight = chatHud.profile.fontSize;
|
||
|
if (%textHeight <= 0)
|
||
|
%textHeight = 12;
|
||
|
|
||
|
%pageLines = mFloor(%chatScrollHeight / %textHeight);
|
||
|
if (%pageLines <= 0)
|
||
|
%pageLines = 1;
|
||
|
|
||
|
// Put the last line at the bottom.
|
||
|
%pos = HudMessageVector.getNumLines() - %pageLines;
|
||
|
if (%pos < 0)
|
||
|
%pos = 0;
|
||
|
ChatHud.position = "0" SPC (-1 * %pos * %textHeight);
|
||
|
|
||
|
ChatHud.resize(firstWord(ChatHud.position), getWord(ChatHud.position, 1), firstWord(ChatHud.extent), getWord(ChatHud.extent, 1));
|
||
|
ChatPageDown.position = (firstWord(outerChatHud.extent) - firstWord(ChatPageDown.extent))
|
||
|
SPC ($outerChatLenY[%length] - getWord(ChatPageDown.extent, 1));
|
||
|
ChatPageDown.setVisible(false);
|
||
|
}
|
||
|
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
|
||
|
function MainChatHud::nextChatHudLen( %this )
|
||
|
{
|
||
|
%len = $pref::ChatHudLength++;
|
||
|
if ($pref::ChatHudLength == 4)
|
||
|
$pref::ChatHudLength = 1;
|
||
|
%this.setChatHudLength($pref::ChatHudLength);
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// ChatHud methods
|
||
|
// This is the actual message vector/text control which is part of
|
||
|
// the MainChatHud dialog
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
function ChatHud::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() && HudMessageVector.getNumLines() && (HudMessageVector.getNumLines() >= $pref::HudMessageLogSize))
|
||
|
{
|
||
|
%tag = HudMessageVector.getLineTag(0);
|
||
|
if(%tag != 0)
|
||
|
%tag.delete();
|
||
|
HudMessageVector.popFrontLine();
|
||
|
}
|
||
|
HudMessageVector.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 ChatHud::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 ChatHud::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);
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Support functions
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
function pageUpMessageHud()
|
||
|
{
|
||
|
ChatHud.pageUp();
|
||
|
}
|
||
|
|
||
|
function pageDownMessageHud()
|
||
|
{
|
||
|
ChatHud.pageDown();
|
||
|
}
|
||
|
|
||
|
function cycleMessageHudSize()
|
||
|
{
|
||
|
MainChatHud.nextChatHudLen();
|
||
|
}
|