Advertisement
Guest User

_killcam - Notesblok

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