chatHud.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. //-----------------------------------------------------------------------------
  23. // Message Hud
  24. //-----------------------------------------------------------------------------
  25. // chat hud sizes in lines
  26. $outerChatLenY[1] = 4;
  27. $outerChatLenY[2] = 9;
  28. $outerChatLenY[3] = 13;
  29. // Only play sound files that are <= 5000ms in length.
  30. $MaxMessageWavLength = 5000;
  31. // Helper function to play a sound file if the message indicates.
  32. // Returns starting position of wave file indicator.
  33. function playMessageSound(%message, %voice, %pitch)
  34. {
  35. // Search for wav tag marker.
  36. %wavStart = strstr(%message, "~w");
  37. if (%wavStart == -1)
  38. {
  39. return -1;
  40. }
  41. %wav = getSubStr(%message, %wavStart + 2, 1000);
  42. if (%voice !$= "")
  43. {
  44. %wavFile = "art/sound/voice/" @ %voice @ "/" @ %wav;
  45. }
  46. else
  47. %wavFile = "art/sound/" @ %wav;
  48. if (strstr(%wavFile, ".wav") != (strlen(%wavFile) - 4))
  49. %wavFile = %wavFile @ ".wav";
  50. // XXX This only expands to a single filepath, of course; it
  51. // would be nice to support checking in each mod path if we
  52. // have multiple mods active.
  53. %wavFile = ExpandFilename(%wavFile);
  54. %wavSource = sfxCreateSource(AudioMessage, %wavFile);
  55. if (isObject(%wavSource))
  56. {
  57. %wavLengthMS = %wavSource.getDuration() * %pitch;
  58. if (%wavLengthMS == 0)
  59. error("** WAV file \"" @ %wavFile @ "\" is nonexistent or sound is zero-length **");
  60. else if (%wavLengthMS <= $MaxMessageWavLength)
  61. {
  62. if (isObject($ClientChatHandle[%sender]))
  63. $ClientChatHandle[%sender].delete();
  64. $ClientChatHandle[%sender] = %wavSource;
  65. if (%pitch != 1.0)
  66. $ClientChatHandle[%sender].setPitch(%pitch);
  67. $ClientChatHandle[%sender].play();
  68. }
  69. else
  70. error("** WAV file \"" @ %wavFile @ "\" is too long **");
  71. }
  72. else
  73. error("** Unable to load WAV file : \"" @ %wavFile @ "\" **");
  74. return %wavStart;
  75. }
  76. // All messages are stored in this HudMessageVector, the actual
  77. // MainChatHud only displays the contents of this vector.
  78. new MessageVector(HudMessageVector);
  79. $LastHudTarget = 0;
  80. //-----------------------------------------------------------------------------
  81. function onChatMessage(%message, %voice, %pitch)
  82. {
  83. // XXX Client objects on the server must have voiceTag and voicePitch
  84. // fields for values to be passed in for %voice and %pitch... in
  85. // this example mod, they don't have those fields.
  86. // Clients are not allowed to trigger general game sounds with their
  87. // chat messages... a voice directory MUST be specified.
  88. if (%voice $= "") {
  89. %voice = "default";
  90. }
  91. // See if there's a sound at the end of the message, and play it.
  92. if ((%wavStart = playMessageSound(%message, %voice, %pitch)) != -1) {
  93. // Remove the sound marker from the end of the message.
  94. %message = getSubStr(%message, 0, %wavStart);
  95. }
  96. // Chat goes to the chat HUD.
  97. if (getWordCount(%message)) {
  98. ChatHud.addLine(%message);
  99. }
  100. }
  101. function onServerMessage(%message)
  102. {
  103. // See if there's a sound at the end of the message, and play it.
  104. if ((%wavStart = playMessageSound(%message)) != -1) {
  105. // Remove the sound marker from the end of the message.
  106. %message = getSubStr(%message, 0, %wavStart);
  107. }
  108. // Server messages go to the chat HUD too.
  109. if (getWordCount(%message)) {
  110. ChatHud.addLine(%message);
  111. }
  112. }
  113. //-----------------------------------------------------------------------------
  114. // MainChatHud methods
  115. //-----------------------------------------------------------------------------
  116. function MainChatHud::onWake( %this )
  117. {
  118. // set the chat hud to the users pref
  119. %this.setChatHudLength( $Pref::ChatHudLength );
  120. }
  121. //------------------------------------------------------------------------------
  122. function MainChatHud::setChatHudLength( %this, %length )
  123. {
  124. %textHeight = ChatHud.Profile.fontSize + ChatHud.lineSpacing;
  125. if (%textHeight <= 0)
  126. %textHeight = 12;
  127. %lengthInPixels = $outerChatLenY[%length] * %textHeight;
  128. %chatMargin = getWord(OuterChatHud.extent, 1) - getWord(ChatScrollHud.Extent, 1)
  129. + 2 * ChatScrollHud.profile.borderThickness;
  130. OuterChatHud.setExtent(firstWord(OuterChatHud.extent), %lengthInPixels + %chatMargin);
  131. ChatScrollHud.scrollToBottom();
  132. ChatPageDown.setVisible(false);
  133. }
  134. //------------------------------------------------------------------------------
  135. function MainChatHud::nextChatHudLen( %this )
  136. {
  137. %len = $pref::ChatHudLength++;
  138. if ($pref::ChatHudLength == 4)
  139. $pref::ChatHudLength = 1;
  140. %this.setChatHudLength($pref::ChatHudLength);
  141. }
  142. //-----------------------------------------------------------------------------
  143. // ChatHud methods
  144. // This is the actual message vector/text control which is part of
  145. // the MainChatHud dialog
  146. //-----------------------------------------------------------------------------
  147. //-----------------------------------------------------------------------------
  148. function ChatHud::addLine(%this,%text)
  149. {
  150. //first, see if we're "scrolled up"...
  151. %textHeight = %this.profile.fontSize + %this.lineSpacing;
  152. if (%textHeight <= 0)
  153. %textHeight = 12;
  154. %scrollBox = %this.getGroup();
  155. %chatScrollHeight = getWord(%scrollBox.extent, 1) - 2 * %scrollBox.profile.borderThickness;
  156. %chatPosition = getWord(%this.extent, 1) - %chatScrollHeight + getWord(%this.position, 1) - %scrollBox.profile.borderThickness;
  157. %linesToScroll = mFloor((%chatPosition / %textHeight) + 0.5);
  158. if (%linesToScroll > 0)
  159. %origPosition = %this.position;
  160. //remove old messages from the top only if scrolled down all the way
  161. while( !chatPageDown.isVisible() && HudMessageVector.getNumLines() && (HudMessageVector.getNumLines() >= $pref::HudMessageLogSize))
  162. {
  163. %tag = HudMessageVector.getLineTag(0);
  164. if(%tag != 0)
  165. %tag.delete();
  166. HudMessageVector.popFrontLine();
  167. }
  168. //add the message...
  169. HudMessageVector.pushBackLine(%text, $LastHudTarget);
  170. $LastHudTarget = 0;
  171. //now that we've added the message, see if we need to reset the position
  172. if (%linesToScroll > 0)
  173. {
  174. chatPageDown.setVisible(true);
  175. %this.position = %origPosition;
  176. }
  177. else
  178. chatPageDown.setVisible(false);
  179. }
  180. //-----------------------------------------------------------------------------
  181. function ChatHud::pageUp(%this)
  182. {
  183. // Find out the text line height
  184. %textHeight = %this.profile.fontSize + %this.lineSpacing;
  185. if (%textHeight <= 0)
  186. %textHeight = 12;
  187. %scrollBox = %this.getGroup();
  188. // Find out how many lines per page are visible
  189. %chatScrollHeight = getWord(%scrollBox.extent, 1) - 2 * %scrollBox.profile.borderThickness;
  190. if (%chatScrollHeight <= 0)
  191. return;
  192. %pageLines = mFloor(%chatScrollHeight / %textHeight) - 1; // have a 1 line overlap on pages
  193. if (%pageLines <= 0)
  194. %pageLines = 1;
  195. // See how many lines we actually can scroll up:
  196. %chatPosition = -1 * (getWord(%this.position, 1) - %scrollBox.profile.borderThickness);
  197. %linesToScroll = mFloor((%chatPosition / %textHeight) + 0.5);
  198. if (%linesToScroll <= 0)
  199. return;
  200. if (%linesToScroll > %pageLines)
  201. %scrollLines = %pageLines;
  202. else
  203. %scrollLines = %linesToScroll;
  204. // Now set the position
  205. %this.position = firstWord(%this.position) SPC (getWord(%this.position, 1) + (%scrollLines * %textHeight));
  206. // Display the pageup icon
  207. chatPageDown.setVisible(true);
  208. }
  209. //-----------------------------------------------------------------------------
  210. function ChatHud::pageDown(%this)
  211. {
  212. // Find out the text line height
  213. %textHeight = %this.profile.fontSize + %this.lineSpacing;
  214. if (%textHeight <= 0)
  215. %textHeight = 12;
  216. %scrollBox = %this.getGroup();
  217. // Find out how many lines per page are visible
  218. %chatScrollHeight = getWord(%scrollBox.extent, 1) - 2 * %scrollBox.profile.borderThickness;
  219. if (%chatScrollHeight <= 0)
  220. return;
  221. %pageLines = mFloor(%chatScrollHeight / %textHeight) - 1;
  222. if (%pageLines <= 0)
  223. %pageLines = 1;
  224. // See how many lines we actually can scroll down:
  225. %chatPosition = getWord(%this.extent, 1) - %chatScrollHeight + getWord(%this.position, 1) - %scrollBox.profile.borderThickness;
  226. %linesToScroll = mFloor((%chatPosition / %textHeight) + 0.5);
  227. if (%linesToScroll <= 0)
  228. return;
  229. if (%linesToScroll > %pageLines)
  230. %scrollLines = %pageLines;
  231. else
  232. %scrollLines = %linesToScroll;
  233. // Now set the position
  234. %this.position = firstWord(%this.position) SPC (getWord(%this.position, 1) - (%scrollLines * %textHeight));
  235. // See if we have should (still) display the pagedown icon
  236. if (%scrollLines < %linesToScroll)
  237. chatPageDown.setVisible(true);
  238. else
  239. chatPageDown.setVisible(false);
  240. }
  241. //-----------------------------------------------------------------------------
  242. // Support functions
  243. //-----------------------------------------------------------------------------
  244. function pageUpMessageHud()
  245. {
  246. ChatHud.pageUp();
  247. }
  248. function pageDownMessageHud()
  249. {
  250. ChatHud.pageDown();
  251. }
  252. function cycleMessageHudSize()
  253. {
  254. MainChatHud.nextChatHudLen();
  255. }