1//************************************************************************** 2//** 3//** ## ## ## ## ## #### #### ### ### 4//** ## ## ## ## ## ## ## ## ## ## #### #### 5//** ## ## ## ## ## ## ## ## ## ## ## ## ## ## 6//** ## ## ######## ## ## ## ## ## ## ## ### ## 7//** ### ## ## ### ## ## ## ## ## ## 8//** # ## ## # #### #### ## ## 9//** 10//** $Id: IntermissionScreen.vc 4082 2009-10-22 11:48:22Z dj_jl $ 11//** 12//** Copyright (C) 1999-2006 Jānis Legzdiņš 13//** 14//** This program is free software; you can redistribute it and/or 15//** modify it under the terms of the GNU General Public License 16//** as published by the Free Software Foundation; either version 2 17//** of the License, or (at your option) any later version. 18//** 19//** This program is distributed in the hope that it will be useful, 20//** but WITHOUT ANY WARRANTY; without even the implied warranty of 21//** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22//** GNU General Public License for more details. 23//** 24//************************************************************************** 25 26class IntermissionScreen : Widget; 27 28enum 29{ 30 IMS_Stats, 31 IMS_Text, 32 IMS_Done 33}; 34 35ClientGameBase ClGame; 36 37const float TALLY_EFFECT_TIME = 0.625; 38const float TALLY_FINAL_X_DELTA = 23.0; 39const float TALLY_FINAL_Y_DELTA = 13.0; 40const float TALLY_START_XPOS = 338.0; 41const float TALLY_STOP_XPOS = 250.0; 42const float TALLY_START_YPOS = 272.0; 43const float TALLY_STOP_YPOS = 223.0; 44const int TALLY_TOP_X = 245; 45const int TALLY_TOP_Y = 149; 46const int TALLY_LEFT_X = 167; 47const int TALLY_LEFT_Y = 211; 48const int TALLY_TOTALS_X = 451; 49 50float TextSpeed; 51float TextWait; 52name TextFlat; 53int TextPic; 54 55// specifies current state 56int interstate; 57float intertime; 58 59// background (map of levels). 60int patchINTERPIC; 61 62float HubCount; 63string HubText; 64 65// used for general timing 66float cnt; 67 68int slaughterboy; 69 70int tallytop; 71int tallylft; 72 73bool showTotals; 74 75//========================================================================== 76// 77// Start 78// 79//========================================================================== 80 81void Start() 82{ 83 IM_InitStats(); 84 IM_LoadPics(); 85 86 if (!ClGame.deathmatch && !HubCount) 87 { 88 interstate = IMS_Done; 89 cnt = 0.3; 90 } 91} 92 93//========================================================================== 94// 95// Tick 96// 97//========================================================================== 98 99void Tick(float DeltaTime) 100{ 101 if (interstate == IMS_Done) 102 { 103 if (cnt > 0.0) 104 { 105 cnt -= DeltaTime; 106 if (cnt <= 0.0) 107 { 108 IM_UnloadPics(); 109 CmdBuf_AddText("TeleportNewMap\n"); 110 } 111 } 112 return; 113 } 114 intertime += DeltaTime; 115 if (ClGame.skipintermission || (!ClGame.deathmatch && !HubCount)) 116 { 117 interstate = IMS_Done; 118 cnt = 0.3; 119 ClGame.skipintermission = false; 120 } 121} 122 123//========================================================================== 124// 125// OnDraw 126// 127//========================================================================== 128 129void OnDraw() 130{ 131 if (interstate == IMS_Done) 132 { 133 return; 134 } 135 136 switch (interstate) 137 { 138 case IMS_Stats: 139 IM_DrawDeathTally(); 140 break; 141 142 case IMS_Text: 143 IM_DrawHubText(); 144 } 145} 146 147//======================================================================== 148// 149// IM_LoadPics 150// 151//======================================================================== 152 153void IM_LoadPics() 154{ 155} 156 157//======================================================================== 158// 159// IM_UnloadPics 160// 161//======================================================================== 162 163void IM_UnloadPics() 164{ 165} 166 167//======================================================================== 168// 169// IM_InitStats 170// 171// Initialises the stats for single player mode 172// 173//======================================================================== 174 175void IM_InitStats() 176{ 177 int i; 178 int j; 179 int slaughterfrags; 180 int posnum; 181 int slaughtercount; 182 int playercount; 183 PlayerReplicationInfo RepInfo; 184 PlayerReplicationInfo Other; 185 186 ClGame.skipintermission = false; 187 intertime = 0.0; 188 if (!ClGame.deathmatch) 189 { 190 if (!ClGame.cl.Level.bNoIntermission) 191 { 192 print("Single player stats are not implemented"); 193 } 194 IM_InitHubText(); 195 } 196 else 197 { 198 patchINTERPIC = R_RegisterPic('interpic'); 199 tallytop = R_RegisterPic('tallytop'); 200 tallylft = R_RegisterPic('tallylft'); 201 202 interstate = IMS_Stats; 203 slaughterboy = 0; 204 slaughterfrags = -9999; 205 posnum = 0; 206 playercount = 0; 207 slaughtercount = 0; 208 foreach ClGame.GLevel.LevelInfo.AllThinkers(PlayerReplicationInfo, RepInfo) 209 { 210 i = RepInfo.PlayerNum; 211 playercount++; 212 posnum++; 213 if (RepInfo.Frags > slaughterfrags) 214 { 215 slaughterboy = 1 << i; 216 slaughterfrags = RepInfo.Frags; 217 slaughtercount = 1; 218 } 219 else if (RepInfo.Frags == slaughterfrags) 220 { 221 slaughterboy |= 1 << i; 222 slaughtercount++; 223 } 224 } 225 if (playercount == slaughtercount) 226 { // don't do the slaughter stuff if everyone is equal 227 slaughterboy = 0; 228 } 229#ifdef FIXME 230 S_StartSong("hub", P_GetCDIntermissionTrack(), true); 231#else 232 CmdBuf_AddText("music loop hub\n"); 233#endif 234 } 235} 236 237//======================================================================== 238// 239// IM_InitHubText 240// 241// Initialises the stats for single player mode 242// 243//======================================================================== 244 245void IM_InitHubText() 246{ 247 interstate = IMS_Text; 248 HubCount = 0.0; 249 if (ClGame.im.Text) 250 { 251 if (ClGame.im.bTextIsLump) 252 { 253 HubText = LoadTextLump(StrToName(ClGame.im.Text)); 254 } 255 else 256 { 257 HubText = ClGame.im.Text; 258 } 259 HubCount = itof(strlen(HubText)) * TextSpeed + TextWait; 260 261 TextFlat = ''; 262 TextPic = 0; 263 if (ClGame.im.TextPic) 264 { 265 TextPic = R_RegisterPic(ClGame.im.TextPic); 266 } 267 else if (ClGame.im.TextFlat) 268 { 269 TextFlat = ClGame.im.TextFlat; 270 } 271 272 if (ClGame.im.TextMusic) 273 { 274 CmdBuf_AddText(va("music loop %n\n", ClGame.im.TextMusic)); 275 } 276 else 277 { 278#ifdef FIXME 279 S_StartSong("hub", P_GetCDIntermissionTrack(), true); 280#else 281 CmdBuf_AddText("music loop hub\n"); 282#endif 283 } 284 } 285} 286 287//=========================================================================== 288// 289// IM_DrawHubText 290// 291//=========================================================================== 292 293void IM_DrawHubText() 294{ 295 if (TextPic) 296 { 297 DrawFullScreenPic(TextPic); 298 } 299 else if (TextFlat) 300 { 301 FillRectWithFlat(0, 0, 640, 480, TextFlat); 302 } 303 else 304 { 305 R_FillRect(0, 0, 640, 480, 0); 306 } 307 int count = ftoi((intertime - 0.3) / TextSpeed); 308 if (count < 0) 309 { 310 count = 0; 311 } 312 if (count > strlen(HubText)) 313 { 314 count = strlen(HubText); 315 } 316 SetFont('smallfont'); 317 SetTextAlign(hleft, vtop); 318 DrawText(170, 145, substr(HubText, 0, count)); 319} 320 321//========================================================================== 322// 323// IM_DrawNumber 324// 325//========================================================================== 326 327void IM_DrawNumber(int val, int x, int y, int wrapThresh) 328{ 329 SetFont('smallfont'); 330 SetTextAlign(hcentre, vtop); 331 if (!(val < -9 && wrapThresh < 1000)) 332 { 333 DrawText(x, y, va("%d", 334 val >= wrapThresh ? val % wrapThresh : val)); 335 } 336 else 337 { 338 DrawText(x, y, "XX"); 339 } 340} 341 342//========================================================================== 343// 344// IM_DrawNumberBold 345// 346//========================================================================== 347 348void IM_DrawNumberBold(int val, int x, int y, int wrapThresh) 349{ 350 SetFont('smallfont'); 351 SetTextAlign(hcentre, vtop); 352 if (!(val < -9 && wrapThresh < 1000)) 353 { 354 DrawText(x, y, va("%d", val >= wrapThresh ? val % wrapThresh : val), CR_YELLOW); 355 } 356 else 357 { 358 DrawText(x, y, "XX", CR_YELLOW); 359 } 360} 361 362//======================================================================== 363// 364// IM_DrawDeathTally 365// 366//======================================================================== 367 368void IM_DrawDeathTally() 369{ 370 int i, j; 371 float xPos, yPos; 372 float xDelta, yDelta; 373 float xStart, scale; 374 int x, y; 375 bool bold; 376 PlayerReplicationInfo RepInfo; 377 PlayerReplicationInfo Other; 378 379 DrawFullScreenPic(patchINTERPIC); 380 if (intertime < TALLY_EFFECT_TIME) 381 { 382 showTotals = false; 383 scale = intertime / TALLY_EFFECT_TIME; 384 xDelta = scale * TALLY_FINAL_X_DELTA; 385 yDelta = scale * TALLY_FINAL_Y_DELTA; 386 xStart = TALLY_START_XPOS - 387 scale * (TALLY_START_XPOS - TALLY_STOP_XPOS); 388 yPos = TALLY_START_YPOS - 389 scale * (TALLY_START_YPOS - TALLY_STOP_YPOS); 390 } 391 else 392 { 393 xDelta = TALLY_FINAL_X_DELTA; 394 yDelta = TALLY_FINAL_Y_DELTA; 395 xStart = TALLY_STOP_XPOS; 396 yPos = TALLY_STOP_YPOS; 397 } 398 if (intertime >= TALLY_EFFECT_TIME && showTotals == false) 399 { 400 showTotals = true; 401 LocalSound('PlatformStop'); 402 } 403 y = ftoi(yPos); 404 foreach ClGame.GLevel.LevelInfo.AllThinkers(PlayerReplicationInfo, RepInfo) 405 { 406 i = RepInfo.PlayerNum; 407 xPos = xStart; 408 SetFont('smallfont'); 409 SetTextAlign(hleft, vtop); 410 DrawText(ftoi(xPos), y, RepInfo.PlayerName, 411 i == ClGame.cl.ClientNum ? CR_YELLOW : CR_WHITE); 412 if (showTotals && !((slaughterboy & (1 << i)) && 413 !(ftoi(32.0 * intertime) & 16))) 414 { 415 if (i == ClGame.cl.ClientNum) 416 { 417 IM_DrawNumberBold(RepInfo.Frags, TALLY_TOTALS_X, y, 1000); 418 } 419 else 420 { 421 IM_DrawNumber(RepInfo.Frags, TALLY_TOTALS_X, y, 1000); 422 } 423 } 424 yPos += yDelta; 425 y = ftoi(yPos); 426 } 427} 428 429//========================================================================== 430// 431// OnVisibilityChanged 432// 433//========================================================================== 434 435void OnVisibilityChanged(bool bNewVisibility) 436{ 437 bTickEnabled = bNewVisibility; 438} 439 440defaultproperties 441{ 442 bTickEnabled = true; 443 Focusable = true; 444 Width = 640; 445 Height = 480; 446 TextSpeed = 0.1; 447 TextWait = 4.0; 448} 449