Advertisement
Guest User

Untitled

a guest
Sep 29th, 2010
396
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.00 KB | None | 0 0
  1. #include maps\mp\_utility;
  2. #include maps\mp\gametypes\_hud_util;
  3.  
  4. init()
  5. {
  6. precacheString(&"PLATFORM_PRESS_TO_SKIP");
  7. precacheString(&"PLATFORM_PRESS_TO_RESPAWN");
  8. precacheString(&"PLATFORM_PRESS_TO_COPYCAT");
  9. precacheShader("specialty_copycat");
  10.  
  11. level.killcam = maps\mp\gametypes\_tweakables::getTweakableValue( "game", "allowkillcam" );
  12. }
  13.  
  14. killcam(
  15. attackerNum, // entity number of the attacker
  16. killcamentityindex, // entity number of the entity to view (grenade, airstrike, etc)
  17. killcamentitystarttime, // time at which the killcamentity came into being
  18. sWeapon, // killing weapon
  19. predelay, // time between player death and beginning of killcam
  20. offsetTime, // something to do with how far back in time the killer was seeing the world when he made the kill; latency related, sorta
  21. timeUntilRespawn, // will the player be allowed to respawn after the killcam?
  22. maxtime, // time remaining until map ends; the killcam will never last longer than this. undefined = no limit
  23. attacker, // entity object of attacker
  24. victim // entity object of the victim
  25. )
  26. {
  27. // monitors killcam and hides HUD elements during killcam session
  28. //if ( !level.splitscreen )
  29. // self thread killcam_HUD_off();
  30.  
  31. self endon("disconnect");
  32. self endon("spawned");
  33. level endon("game_ended");
  34.  
  35. if ( attackerNum < 0 )
  36. return;
  37.  
  38. // length from killcam start to killcam end
  39. if (getdvar("scr_killcam_time") == "") {
  40. if ( sWeapon == "artillery_mp" || sWeapon == "stealth_bomb_mp" )
  41. camtime = (gettime() - killcamentitystarttime) / 1000 - predelay - .1;
  42. else if ( level.showingFinalKillcam )
  43. camtime = 4.0;
  44. else if ( sWeapon == "javelin_mp" )
  45. camtime = 8;
  46. else if ( issubstr( sWeapon, "remotemissile_" ) )
  47. camtime = 5;
  48. else if ( !timeUntilRespawn || timeUntilRespawn > 5.0 ) // if we're not going to respawn, we can take more time to watch what happened
  49. camtime = 5.0;
  50. else if ( sWeapon == "frag_grenade_mp" || sWeapon == "frag_grenade_short_mp" || sWeapon == "semtex_mp" )
  51. camtime = 4.25; // show long enough to see grenade thrown
  52. else
  53. camtime = 2.5;
  54. }
  55. else
  56. camtime = getdvarfloat("scr_killcam_time");
  57.  
  58. if (isdefined(maxtime)) {
  59. if (camtime > maxtime)
  60. camtime = maxtime;
  61. if (camtime < .05)
  62. camtime = .05;
  63. }
  64.  
  65. // time after player death that killcam continues for
  66. if (getdvar("scr_killcam_posttime") == "")
  67. postdelay = 2;
  68. else {
  69. postdelay = getdvarfloat("scr_killcam_posttime");
  70. if (postdelay < 0.05)
  71. postdelay = 0.05;
  72. }
  73.  
  74. /* timeline:
  75.  
  76. | camtime | postdelay |
  77. | | predelay |
  78.  
  79. ^ killcam start ^ player death ^ killcam end
  80. ^ player starts watching killcam
  81.  
  82. */
  83.  
  84. killcamlength = camtime + postdelay;
  85.  
  86. // don't let the killcam last past the end of the round.
  87. if (isdefined(maxtime) && killcamlength > maxtime)
  88. {
  89. // first trim postdelay down to a minimum of 1 second.
  90. // if that doesn't make it short enough, trim camtime down to a minimum of 1 second.
  91. // if that's still not short enough, cancel the killcam.
  92. if ( maxtime < 2 )
  93. return;
  94.  
  95. if (maxtime - camtime >= 1) {
  96. // reduce postdelay so killcam ends at end of match
  97. postdelay = maxtime - camtime;
  98. }
  99. else {
  100. // distribute remaining time over postdelay and camtime
  101. postdelay = 1;
  102. camtime = maxtime - 1;
  103. }
  104.  
  105. // recalc killcamlength
  106. killcamlength = camtime + postdelay;
  107. }
  108.  
  109. killcamoffset = camtime + predelay;
  110.  
  111. startTime = getTime();
  112. self notify ( "begin_killcam", startTime );
  113.  
  114. self.sessionstate = "spectator";
  115. self.forcespectatorclient = attackerNum;
  116. self.killcamentity = -1;
  117. if ( killcamentityindex >= 0 )
  118. self thread setKillCamEntity( killcamentityindex, killcamoffset, killcamentitystarttime );
  119. self.archivetime = killcamoffset;
  120. self.killcamlength = killcamlength;
  121. self.psoffsettime = offsetTime;
  122.  
  123. // ignore spectate permissions
  124. self allowSpectateTeam("allies", true);
  125. self allowSpectateTeam("axis", true);
  126. self allowSpectateTeam("freelook", true);
  127. self allowSpectateTeam("none", true);
  128.  
  129. if ( isDefined( attacker ) && level.showingFinalKillcam ) // attacker may have disconnected
  130. {
  131. self openMenu( "killedby_card_display" );
  132. self SetCardDisplaySlot( attacker, 7 );
  133. }
  134.  
  135. self thread endedKillcamCleanup();
  136.  
  137. // wait till the next server frame to allow code a chance to update archivetime if it needs trimming
  138. wait 0.05;
  139.  
  140. assertex( self.archivetime <= killcamoffset + 0.0001, "archivetime: " + self.archivetime + ", killcamoffset: " + killcamoffset );
  141. if ( self.archivetime < killcamoffset )
  142. println( "WARNING: Code trimmed killcam time by " + (killcamoffset - self.archivetime) + " seconds because it doesn't have enough game time recorded!" );
  143.  
  144. camtime = self.archivetime - .05 - predelay;
  145. killcamlength = camtime + postdelay;
  146. self.killcamlength = killcamlength;
  147.  
  148. if ( camtime <= 0 ) // if we're not looking back in time far enough to even see the death, cancel
  149. {
  150. println( "Cancelling killcam because we don't even have enough recorded to show the death." );
  151.  
  152. self.sessionstate = "dead";
  153. self.forcespectatorclient = -1;
  154. self.killcamentity = -1;
  155. self.archivetime = 0;
  156. self.psoffsettime = 0;
  157.  
  158. self notify ( "killcam_ended" );
  159.  
  160. return;
  161. }
  162.  
  163. if ( level.showingFinalKillcam )
  164. thread doFinalKillCamFX( camtime );
  165.  
  166. self.killcam = true;
  167.  
  168. self initKCElements();
  169.  
  170. if ( !level.splitscreen )
  171. {
  172. self.kc_timer.alpha = 1;
  173. self.kc_timer setTenthsTimer(camtime);
  174. }
  175.  
  176. if ( timeUntilRespawn && !level.gameEnded )
  177. {
  178. if ( timeUntilRespawn > 0 )
  179. setLowerMessage( "kc_info", game["strings"]["waiting_to_spawn"], timeUntilRespawn );
  180. else
  181. setLowerMessage( "kc_info", &"PLATFORM_PRESS_TO_SKIP" );
  182. }
  183. else if ( !level.gameEnded )
  184. {
  185. setLowerMessage( "kc_info", &"PLATFORM_PRESS_TO_RESPAWN" );
  186. }
  187.  
  188. if ( !level.showingFinalKillcam )
  189. self.kc_skiptext.alpha = 1;
  190. else
  191. self.kc_skiptext.alpha = 0;
  192.  
  193. self.kc_othertext.alpha = 0;
  194. self.kc_icon.alpha = 0;
  195.  
  196. self thread spawnedKillcamCleanup();
  197.  
  198. if ( self == victim && victim _hasPerk( "specialty_copycat" ) && isDefined( victim.pers["copyCatLoadout"] ) )
  199. self thread waitKCCopyCatButton( attacker );
  200.  
  201. if ( !level.showingFinalKillcam )
  202. self thread waitSkipKillcamButton( timeUntilRespawn );
  203. else
  204. self notify ( "showing_final_killcam" );
  205.  
  206. self thread endKillcamIfNothingToShow();
  207.  
  208. self waittillKillcamOver();
  209.  
  210. if ( level.showingFinalKillcam )
  211. {
  212. self thread maps\mp\gametypes\_playerlogic::spawnEndOfGame();
  213. return;
  214. }
  215.  
  216. self thread calculateKillCamTime( startTime );
  217.  
  218. self thread killcamCleanup( true );
  219. }
  220.  
  221.  
  222. doFinalKillCamFX( camTime )
  223. {
  224. if ( isDefined( level.doingFinalKillcamFx ) )
  225. return;
  226. level.doingFinalKillcamFx = true;
  227.  
  228. intoSlowMoTime = camTime;
  229. if ( intoSlowMoTime > 1.0 )
  230. {
  231. intoSlowMoTime = 1.0;
  232. wait( camTime - 1.0 );
  233. }
  234.  
  235. setSlowMotion( 1.0, 0.25, intoSlowMoTime ); // start timescale, end timescale, lerp duration
  236. wait( intoSlowMoTime + .5 );
  237. setSlowMotion( 0.25, 1, 1.0 );
  238.  
  239. level.doingFinalKillcamFx = undefined;
  240. }
  241.  
  242.  
  243. calculateKillCamTime( startTime )
  244. {
  245. watchedTime = int(getTime() - startTime);
  246. self incPlayerStat( "killcamtimewatched", watchedTime );
  247. }
  248.  
  249. waittillKillcamOver()
  250. {
  251. self endon("abort_killcam");
  252.  
  253. wait(self.killcamlength - 0.05);
  254. }
  255.  
  256. setKillCamEntity( killcamentityindex, killcamoffset, starttime )
  257. {
  258. self endon("disconnect");
  259. self endon("killcam_ended");
  260.  
  261. killcamtime = (gettime() - killcamoffset * 1000);
  262.  
  263. if ( starttime > killcamtime )
  264. {
  265. wait .05;
  266. // code may have trimmed archivetime after the first frame if we couldn't go back in time as far as requested.
  267. killcamoffset = self.archivetime;
  268. killcamtime = (gettime() - killcamoffset * 1000);
  269.  
  270. if ( starttime > killcamtime )
  271. wait (starttime - killcamtime) / 1000;
  272. }
  273. self.killcamentity = killcamentityindex;
  274. }
  275.  
  276. waitSkipKillcamButton( timeUntilRespawn )
  277. {
  278. self endon("disconnect");
  279. self endon("killcam_ended");
  280.  
  281. while(self useButtonPressed())
  282. wait .05;
  283.  
  284. while(!(self useButtonPressed()))
  285. wait .05;
  286.  
  287. if ( !matchMakingGame() )
  288. self incPlayerStat( "killcamskipped", 1 );
  289.  
  290. if ( timeUntilRespawn <= 0 )
  291. clearLowerMessage( "kc_info" );
  292.  
  293. self notify("abort_killcam");
  294. }
  295.  
  296. waitKCCopyCatButton( attacker )
  297. {
  298. self endon("disconnect");
  299. self endon("killcam_ended");
  300.  
  301. self waitCopyCatButton( attacker );
  302.  
  303. self notify("abort_killcam");
  304. }
  305.  
  306. waitDeathCopyCatButton( attacker )
  307. {
  308. self endon ( "disconnect" );
  309.  
  310. self initKCElements();
  311.  
  312. usedCopycat = self waitCopyCatButton( attacker );
  313.  
  314. if ( !isDefined( usedCopycat ) )
  315. {
  316. self.kc_icon.alpha = 0;
  317. self.kc_othertext.alpha = 0;
  318. }
  319. }
  320.  
  321. waitCopyCatButton( attacker )
  322. {
  323. self endon ( "spawned_player" );
  324. self endon ( "death_delay_finished" );
  325. self.kc_icon setShader( "specialty_copycat", 48, 48 );
  326. self.kc_othertext setText( &"PLATFORM_PRESS_TO_COPYCAT" );
  327. self.kc_othertext.alpha = 1;
  328. self.kc_icon.alpha = 1;
  329.  
  330. self notifyOnPlayerCommand( "use_copycat", "weapnext" );
  331.  
  332. self waittill( "use_copycat" );
  333.  
  334. self.pers["copyCatLoadout"]["inUse"] = true;
  335. self.pers["copyCatLoadout"]["owner"] = attacker;
  336.  
  337. self.kc_othertext fadeOverTime( 0.5 );
  338. self.kc_othertext.alpha = 0;
  339.  
  340. self.kc_icon fadeOverTime( 0.25 );
  341. self.kc_icon scaleOverTime( 0.25, 512, 512 );
  342. self.kc_icon.alpha = 0;
  343.  
  344. if ( isDefined( attacker ) )
  345. attacker thread maps\mp\gametypes\_hud_message::playerCardSplashNotify( "copied", self );
  346.  
  347. self playLocalSound( "copycat_steal_class" );
  348.  
  349. return true;
  350. }
  351.  
  352. waitSkipKillcamSafeSpawnButton()
  353. {
  354. self endon("disconnect");
  355. self endon("killcam_ended");
  356.  
  357. if ( !self maps\mp\gametypes\_playerlogic::maySpawn() )
  358. return;
  359.  
  360. while(self fragButtonPressed())
  361. wait .05;
  362.  
  363. while(!(self fragButtonPressed()))
  364. wait .05;
  365.  
  366. self.wantSafeSpawn = true;
  367.  
  368. self notify("abort_killcam");
  369. }
  370.  
  371. endKillcamIfNothingToShow()
  372. {
  373. self endon("disconnect");
  374. self endon("killcam_ended");
  375.  
  376. while(1)
  377. {
  378. // code may trim our archivetime to zero if there is nothing "recorded" to show.
  379. // this can happen when the person we're watching in our killcam goes into killcam himself.
  380. // in this case, end the killcam.
  381. if ( self.archivetime <= 0 )
  382. break;
  383. wait .05;
  384. }
  385.  
  386. self notify("abort_killcam");
  387. }
  388.  
  389. spawnedKillcamCleanup()
  390. {
  391. self endon("disconnect");
  392. self endon("killcam_ended");
  393.  
  394. self waittill("spawned");
  395. self thread killcamCleanup( false );
  396. }
  397.  
  398. endedKillcamCleanup()
  399. {
  400. self endon("disconnect");
  401. self endon("killcam_ended");
  402.  
  403. level waittill("game_ended");
  404.  
  405. self thread killcamCleanup( true );
  406. }
  407.  
  408. killcamCleanup( clearState )
  409. {
  410. if(isDefined(self.kc_skiptext))
  411. self.kc_skiptext.alpha = 0;
  412.  
  413. if(isDefined(self.kc_timer))
  414. self.kc_timer.alpha = 0;
  415.  
  416. if(isDefined(self.kc_icon))
  417. self.kc_icon.alpha = 0;
  418.  
  419. if(isDefined(self.kc_othertext))
  420. self.kc_othertext.alpha = 0;
  421.  
  422. self.killcam = undefined;
  423.  
  424. if ( !level.gameEnded )
  425. self clearLowerMessage( "kc_info" );
  426.  
  427. self thread maps\mp\gametypes\_spectating::setSpectatePermissions();
  428.  
  429. self notify("killcam_ended"); // do this last, in case this function was called from a thread ending on it
  430.  
  431. if ( !clearState )
  432. return;
  433.  
  434. self.sessionstate = "dead";
  435. self ClearKillcamState();
  436. }
  437.  
  438.  
  439.  
  440. cancelKillCamOnUse()
  441. {
  442. self.cancelKillcam = false;
  443. self thread cancelKillCamOnUse_specificButton( ::cancelKillCamUseButton, ::cancelKillCamCallback );
  444. //self thread cancelKillCamOnUse_specificButton( ::cancelKillCamSafeSpawnButton, ::cancelKillCamSafeSpawnCallback );
  445. }
  446.  
  447. cancelKillCamUseButton()
  448. {
  449. return self useButtonPressed();
  450. }
  451. cancelKillCamSafeSpawnButton()
  452. {
  453. return self fragButtonPressed();
  454. }
  455. cancelKillCamCallback()
  456. {
  457. self.cancelKillcam = true;
  458. }
  459. cancelKillCamSafeSpawnCallback()
  460. {
  461. self.cancelKillcam = true;
  462. self.wantSafeSpawn = true;
  463. }
  464.  
  465. cancelKillCamOnUse_specificButton( pressingButtonFunc, finishedFunc )
  466. {
  467. self endon ( "death_delay_finished" );
  468. self endon ( "disconnect" );
  469. level endon ( "game_ended" );
  470.  
  471. for ( ;; )
  472. {
  473. if ( !self [[pressingButtonFunc]]() )
  474. {
  475. wait ( 0.05 );
  476. continue;
  477. }
  478.  
  479. buttonTime = 0;
  480. while( self [[pressingButtonFunc]]() )
  481. {
  482. buttonTime += 0.05;
  483. wait ( 0.05 );
  484. }
  485.  
  486. if ( buttonTime >= 0.5 )
  487. continue;
  488.  
  489. buttonTime = 0;
  490.  
  491. while ( !self [[pressingButtonFunc]]() && buttonTime < 0.5 )
  492. {
  493. buttonTime += 0.05;
  494. wait ( 0.05 );
  495. }
  496.  
  497. if ( buttonTime >= 0.5 )
  498. continue;
  499.  
  500. self [[finishedFunc]]();
  501. return;
  502. }
  503. }
  504.  
  505. initKCElements()
  506. {
  507. if ( !isDefined( self.kc_skiptext ) )
  508. {
  509. self.kc_skiptext = newClientHudElem(self);
  510. self.kc_skiptext.archived = false;
  511. self.kc_skiptext.x = 0;
  512. self.kc_skiptext.alignX = "center";
  513. self.kc_skiptext.alignY = "top";
  514. self.kc_skiptext.horzAlign = "center_adjustable";
  515. self.kc_skiptext.vertAlign = "top_adjustable";
  516. self.kc_skiptext.sort = 1; // force to draw after the bars
  517. self.kc_skiptext.font = "default";
  518. self.kc_skiptext.foreground = true;
  519. self.kc_skiptext.hideWhenInMenu = true;
  520.  
  521. if ( level.splitscreen )
  522. {
  523. self.kc_skiptext.y = 20;
  524. self.kc_skiptext.fontscale = 1.2; // 1.8/1.5
  525. }
  526. else
  527. {
  528. self.kc_skiptext.y = 32;
  529. self.kc_skiptext.fontscale = 1.8;
  530. }
  531. }
  532.  
  533. if ( !isDefined( self.kc_othertext ) )
  534. {
  535. self.kc_othertext = newClientHudElem(self);
  536. self.kc_othertext.archived = false;
  537. self.kc_othertext.y = 18;
  538. self.kc_othertext.alignX = "left";
  539. self.kc_othertext.alignY = "top";
  540. self.kc_othertext.horzAlign = "center";
  541. self.kc_othertext.vertAlign = "middle";
  542. self.kc_othertext.sort = 10; // force to draw after the bars
  543. self.kc_othertext.font = "small";
  544. self.kc_othertext.foreground = true;
  545. self.kc_othertext.hideWhenInMenu = true;
  546.  
  547. if ( level.splitscreen )
  548. {
  549. self.kc_othertext.x = 16;
  550. self.kc_othertext.fontscale = 1.2;
  551. }
  552. else
  553. {
  554. self.kc_othertext.x = 62;
  555. self.kc_othertext.fontscale = 1.6;
  556. }
  557. }
  558.  
  559. if ( !isDefined( self.kc_icon ) )
  560. {
  561. self.kc_icon = newClientHudElem(self);
  562. self.kc_icon.archived = false;
  563. self.kc_icon.x = 16;
  564. self.kc_icon.y = 16;
  565. self.kc_icon.alignX = "left";
  566. self.kc_icon.alignY = "top";
  567. self.kc_icon.horzAlign = "center";
  568. self.kc_icon.vertAlign = "middle";
  569. self.kc_icon.sort = 1; // force to draw after the bars
  570. self.kc_icon.foreground = true;
  571. self.kc_icon.hideWhenInMenu = true;
  572. }
  573.  
  574. if ( !level.splitscreen )
  575. {
  576. if ( !isdefined( self.kc_timer ) )
  577. {
  578. self.kc_timer = createFontString( "hudbig", 1.0 );
  579. self.kc_timer.archived = false;
  580. self.kc_timer.x = 0;
  581. self.kc_timer.alignX = "center";
  582. self.kc_timer.alignY = "middle";
  583. self.kc_timer.horzAlign = "center_safearea";
  584. self.kc_timer.vertAlign = "top_adjustable";
  585. self.kc_timer.y = 42;
  586. self.kc_timer.sort = 1; // force to draw after the bars
  587. self.kc_timer.font = "hudbig";
  588. self.kc_timer.foreground = true;
  589. self.kc_timer.color = (0.85,0.85,0.85);
  590. self.kc_timer.hideWhenInMenu = true;
  591. }
  592. }
  593. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement