Advertisement
Guest User

sd - Notesblok

a guest
Nov 19th, 2011
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 34.70 KB | None | 0 0
  1. #include common_scripts\utility;
  2. #include maps\mp\_utility;
  3. #include maps\mp\gametypes\_hud_util;
  4. // Rallypoints should be destroyed on leaving your team/getting killed
  5. // Compass icons need to be looked at
  6. // Doesn't seem to be setting angle on spawn so that you are facing your rallypoint
  7.  
  8. /*
  9. Search and Destroy
  10. Attackers objective: Bomb one of 2 positions
  11. Defenders objective: Defend these 2 positions / Defuse planted bombs
  12. Round ends: When one team is eliminated, bomb explodes, bomb is defused, or roundlength time is reached
  13. Map ends: When one team reaches the score limit, or time limit or round limit is reached
  14. Respawning: Players remain dead for the round and will respawn at the beginning of the next round
  15.  
  16. Level requirements
  17. ------------------
  18. Allied Spawnpoints:
  19. classname mp_sd_spawn_attacker
  20. Allied players spawn from these. Place at least 16 of these relatively close together.
  21.  
  22. Axis Spawnpoints:
  23. classname mp_sd_spawn_defender
  24. Axis players spawn from these. Place at least 16 of these relatively close together.
  25.  
  26. Spectator Spawnpoints:
  27. classname mp_global_intermission
  28. Spectators spawn from these and intermission is viewed from these positions.
  29. Atleast one is required, any more and they are randomly chosen between.
  30.  
  31. Bombzones:
  32. classname trigger_multiple
  33. targetname bombzone
  34. script_gameobjectname bombzone
  35. script_bombmode_original <if defined this bombzone will be used in the original bomb mode>
  36. script_bombmode_single <if defined this bombzone will be used in the single bomb mode>
  37. script_bombmode_dual <if defined this bombzone will be used in the dual bomb mode>
  38. script_team Set to allies or axis. This is used to set which team a bombzone is used by in dual bomb mode.
  39. script_label Set to A or B. This sets the letter shown on the compass in original mode.
  40. This is a volume of space in which the bomb can planted. Must contain an origin brush.
  41.  
  42. Bomb:
  43. classname trigger_lookat
  44. targetname bombtrigger
  45. script_gameobjectname bombzone
  46. This should be a 16x16 unit trigger with an origin brush placed so that it's center lies on the bottom plane of the trigger.
  47. Must be in the level somewhere. This is the trigger that is used when defusing a bomb.
  48. It gets moved to the position of the planted bomb model.
  49.  
  50. Level script requirements
  51. -------------------------
  52. Team Definitions:
  53. game["attackers"] = "allies";
  54. game["defenders"] = "axis";
  55. This sets which team is attacking and which team is defending. Attackers plant the bombs. Defenders protect the targets.
  56.  
  57. Exploder Effects:
  58. Setting script_noteworthy on a bombzone trigger to an exploder group can be used to trigger additional effects.
  59. */
  60.  
  61. /*QUAKED mp_sd_spawn_attacker (0.0 1.0 0.0) (-16 -16 0) (16 16 72)
  62. Attacking players spawn randomly at one of these positions at the beginning of a round.*/
  63.  
  64. /*QUAKED mp_sd_spawn_defender (1.0 0.0 0.0) (-16 -16 0) (16 16 72)
  65. Defending players spawn randomly at one of these positions at the beginning of a round.*/
  66.  
  67. main()
  68. {
  69. if(getdvar("mapname") == "mp_background")
  70. return;
  71.  
  72. maps\mp\gametypes\_globallogic::init();
  73. maps\mp\gametypes\_callbacksetup::SetupCallbacks();
  74. maps\mp\gametypes\_globallogic::SetupCallbacks();
  75.  
  76. if ( isUsingMatchRulesData() )
  77. {
  78. level.initializeMatchRules = ::initializeMatchRules;
  79. [[level.initializeMatchRules]]();
  80. level thread reInitializeMatchRulesOnMigration();
  81. }
  82. else
  83. {
  84. registerRoundSwitchDvar( level.gameType, 3, 0, 9 );
  85. registerTimeLimitDvar( level.gameType, 2.5 );
  86. registerScoreLimitDvar( level.gameType, 1 );
  87. registerRoundLimitDvar( level.gameType, 0 );
  88. registerWinLimitDvar( level.gameType, 4 );
  89. registerNumLivesDvar( level.gameType, 1 );
  90. registerHalfTimeDvar( level.gameType, 0 );
  91.  
  92. level.matchRules_damageMultiplier = 0;
  93. level.matchRules_vampirism = 0;
  94. }
  95.  
  96. level.objectiveBased = true;
  97. level.teamBased = true;
  98. level.onPrecacheGameType = ::onPrecacheGameType;
  99. level.onStartGameType = ::onStartGameType;
  100. level.getSpawnPoint = ::getSpawnPoint;
  101. level.onSpawnPlayer = ::onSpawnPlayer;
  102. level.onPlayerKilled = ::onPlayerKilled;
  103. level.onDeadEvent = ::onDeadEvent;
  104. level.onOneLeftEvent = ::onOneLeftEvent;
  105. level.onTimeLimit = ::onTimeLimit;
  106. level.onNormalDeath = ::onNormalDeath;
  107. level.initGametypeAwards = ::initGametypeAwards;
  108.  
  109. if ( level.matchRules_damageMultiplier || level.matchRules_vampirism )
  110. level.modifyPlayerDamage = maps\mp\gametypes\_damage::gamemodeModifyPlayerDamage;
  111.  
  112. game["dialog"]["gametype"] = "searchdestroy";
  113.  
  114. if ( getDvarInt( "g_hardcore" ) )
  115. game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
  116. else if ( getDvarInt( "camera_thirdPerson" ) )
  117. game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
  118. else if ( getDvarInt( "scr_diehard" ) )
  119. game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
  120. else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
  121. game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
  122.  
  123. game["dialog"]["offense_obj"] = "obj_destroy";
  124. game["dialog"]["defense_obj"] = "obj_defend";
  125.  
  126. makeDvarServerInfo( "ui_bomb_timer_endtime", -1 );
  127.  
  128. /#
  129. SetDevDvarIfUninitialized( "scr_sd_debugBombKillCamEnt", 0 );
  130. #/
  131. }
  132.  
  133.  
  134. initializeMatchRules()
  135. {
  136. // set common values
  137. setCommonRulesFromMatchRulesData();
  138.  
  139. // set everything else (private match options, default .cfg file values, and what normally is registered in the 'else' below)
  140. roundLength = GetMatchRulesData( "sdData", "roundLength" );
  141. SetDynamicDvar( "scr_sd_timelimit", roundLength );
  142. registerTimeLimitDvar( "sd", roundLength );
  143.  
  144. roundSwitch = GetMatchRulesData( "sdData", "roundSwitch" );
  145. SetDynamicDvar( "scr_sd_roundswitch", roundSwitch );
  146. registerRoundSwitchDvar( "sd", roundSwitch, 0, 9 );
  147.  
  148. winLimit = GetMatchRulesData( "commonOption", "scoreLimit" );
  149. SetDynamicDvar( "scr_sd_winlimit", winLimit );
  150. registerWinLimitDvar( "sd", winLimit );
  151.  
  152. SetDynamicDvar( "scr_sd_bombtimer", GetMatchRulesData( "sdData", "bombTimer" ) );
  153. SetDynamicDvar( "scr_sd_planttime", GetMatchRulesData( "sdData", "plantTime" ) );
  154. SetDynamicDvar( "scr_sd_defusetime", GetMatchRulesData( "sdData", "defuseTime" ) );
  155. SetDynamicDvar( "scr_sd_multibomb", GetMatchRulesData( "sdData", "multiBomb" ) );
  156.  
  157. SetDynamicDvar( "scr_sd_roundlimit", 0 );
  158. registerRoundLimitDvar( "sd", 0 );
  159. SetDynamicDvar( "scr_sd_scorelimit", 1 );
  160. registerScoreLimitDvar( "sd", 1 );
  161. SetDynamicDvar( "scr_sd_halftime", 0 );
  162. registerHalfTimeDvar( "sd", 0 );
  163.  
  164. SetDynamicDvar( "scr_sd_promode", 0 );
  165. }
  166.  
  167.  
  168. onPrecacheGameType()
  169. {
  170. game["bomb_dropped_sound"] = "mp_war_objective_lost";
  171. game["bomb_recovered_sound"] = "mp_war_objective_taken";
  172.  
  173. precacheShader("waypoint_bomb");
  174. precacheShader("hud_suitcase_bomb");
  175. precacheShader("waypoint_target");
  176. precacheShader("waypoint_target_a");
  177. precacheShader("waypoint_target_b");
  178. precacheShader("waypoint_defend");
  179. precacheShader("waypoint_defend_a");
  180. precacheShader("waypoint_defend_b");
  181. precacheShader("waypoint_defuse");
  182. precacheShader("waypoint_defuse_a");
  183. precacheShader("waypoint_defuse_b");
  184. precacheShader("waypoint_escort");
  185. /*
  186. precacheShader("waypoint_target");
  187. precacheShader("waypoint_target_a");
  188. precacheShader("waypoint_target_b");
  189. precacheShader("waypoint_defend");
  190. precacheShader("waypoint_defend_a");
  191. precacheShader("waypoint_defend_b");
  192. precacheShader("waypoint_defuse");
  193. precacheShader("waypoint_defuse_a");
  194. precacheShader("waypoint_defuse_b");
  195. */
  196. precacheString( &"MP_EXPLOSIVES_RECOVERED_BY" );
  197. precacheString( &"MP_EXPLOSIVES_DROPPED_BY" );
  198. precacheString( &"MP_EXPLOSIVES_PLANTED_BY" );
  199. precacheString( &"MP_EXPLOSIVES_DEFUSED_BY" );
  200. precacheString( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
  201. precacheString( &"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
  202. precacheString( &"MP_CANT_PLANT_WITHOUT_BOMB" );
  203. precacheString( &"MP_PLANTING_EXPLOSIVE" );
  204. precacheString( &"MP_DEFUSING_EXPLOSIVE" );
  205. }
  206.  
  207.  
  208. onStartGameType()
  209. {
  210. if ( !isDefined( game["switchedsides"] ) )
  211. game["switchedsides"] = false;
  212.  
  213. if ( game["switchedsides"] )
  214. {
  215. oldAttackers = game["attackers"];
  216. oldDefenders = game["defenders"];
  217. game["attackers"] = oldDefenders;
  218. game["defenders"] = oldAttackers;
  219. }
  220.  
  221. setClientNameMode( "manual_change" );
  222.  
  223. game["strings"]["target_destroyed"] = &"MP_TARGET_DESTROYED";
  224. game["strings"]["bomb_defused"] = &"MP_BOMB_DEFUSED";
  225.  
  226. precacheString( game["strings"]["target_destroyed"] );
  227. precacheString( game["strings"]["bomb_defused"] );
  228.  
  229. level._effect["bombexplosion"] = loadfx("explosions/tanker_explosion");
  230.  
  231. setObjectiveText( game["attackers"], &"OBJECTIVES_SD_ATTACKER" );
  232. setObjectiveText( game["defenders"], &"OBJECTIVES_SD_DEFENDER" );
  233.  
  234. if ( level.splitscreen )
  235. {
  236. setObjectiveScoreText( game["attackers"], &"OBJECTIVES_SD_ATTACKER" );
  237. setObjectiveScoreText( game["defenders"], &"OBJECTIVES_SD_DEFENDER" );
  238. }
  239. else
  240. {
  241. setObjectiveScoreText( game["attackers"], &"OBJECTIVES_SD_ATTACKER_SCORE" );
  242. setObjectiveScoreText( game["defenders"], &"OBJECTIVES_SD_DEFENDER_SCORE" );
  243. }
  244. setObjectiveHintText( game["attackers"], &"OBJECTIVES_SD_ATTACKER_HINT" );
  245. setObjectiveHintText( game["defenders"], &"OBJECTIVES_SD_DEFENDER_HINT" );
  246.  
  247. level.spawnMins = ( 0, 0, 0 );
  248. level.spawnMaxs = ( 0, 0, 0 );
  249. maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_sd_spawn_attacker" );
  250. maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_sd_spawn_defender" );
  251.  
  252. level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
  253. setMapCenter( level.mapCenter );
  254.  
  255. allowed[0] = "sd";
  256. allowed[1] = "bombzone";
  257. allowed[2] = "blocker";
  258. maps\mp\gametypes\_gameobjects::main(allowed);
  259.  
  260. maps\mp\gametypes\_rank::registerScoreInfo( "win", 2 );
  261. maps\mp\gametypes\_rank::registerScoreInfo( "loss", 1 );
  262. maps\mp\gametypes\_rank::registerScoreInfo( "tie", 1.5 );
  263.  
  264. maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
  265. maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 50 );
  266. maps\mp\gametypes\_rank::registerScoreInfo( "assist", 20 );
  267. maps\mp\gametypes\_rank::registerScoreInfo( "plant", 100 );
  268. maps\mp\gametypes\_rank::registerScoreInfo( "defuse", 100 );
  269.  
  270. thread updateGametypeDvars();
  271.  
  272. // because axis or allies may be attackers, special loadout has to be created on game start for this mode
  273. setSpecialLoadout();
  274.  
  275. thread bombs();
  276. }
  277.  
  278.  
  279. getSpawnPoint()
  280. {
  281. if(self.pers["team"] == game["attackers"])
  282. spawnPointName = "mp_sd_spawn_attacker";
  283. else
  284. spawnPointName = "mp_sd_spawn_defender";
  285.  
  286. spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( spawnPointName );
  287. assert( spawnPoints.size );
  288. spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
  289.  
  290. return spawnpoint;
  291. }
  292.  
  293. onSpawnPlayer()
  294. {
  295. self.isPlanting = false;
  296. self.isDefusing = false;
  297. self.isBombCarrier = false;
  298.  
  299. if ( level.multiBomb && !isDefined( self.carryIcon ) && self.pers["team"] == game["attackers"] && !level.bombPlanted )
  300. {
  301. if ( level.splitscreen )
  302. {
  303. self.carryIcon = createIcon( "hud_suitcase_bomb", 33, 33 );
  304. self.carryIcon setPoint( "BOTTOM RIGHT", "BOTTOM RIGHT", 0, -78 );
  305. self.carryIcon.alpha = 0.75;
  306. }
  307. else
  308. {
  309. self.carryIcon = createIcon( "hud_suitcase_bomb", 50, 50 );
  310. self.carryIcon setPoint( "BOTTOM RIGHT", "BOTTOM RIGHT", -90, -65 );
  311. self.carryIcon.alpha = 0.75;
  312. }
  313. self.carryIcon.hidewheninmenu = true;
  314. self thread hideCarryIconOnGameEnd();
  315. }
  316.  
  317. // bomb carrier class? clear this regardless if they were carrier
  318. if ( isDefined( level.sd_loadout ) && isDefined( level.sd_loadout[self.team] ) )
  319. self.pers["gamemodeLoadout"] = undefined;
  320.  
  321. level notify ( "spawned_player" );
  322. }
  323.  
  324.  
  325. hideCarryIconOnGameEnd()
  326. {
  327. self endon( "disconnect" );
  328.  
  329. level waittill( "game_ended" );
  330.  
  331. if ( isDefined( self.carryIcon ) )
  332. self.carryIcon.alpha = 0;
  333. }
  334.  
  335.  
  336. onPlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, killId)
  337. {
  338. thread checkAllowSpectating();
  339. }
  340.  
  341.  
  342. checkAllowSpectating()
  343. {
  344. wait ( 0.05 );
  345.  
  346. update = false;
  347. if ( !level.aliveCount[ game["attackers"] ] )
  348. {
  349. level.spectateOverride[game["attackers"]].allowEnemySpectate = 1;
  350. update = true;
  351. }
  352. if ( !level.aliveCount[ game["defenders"] ] )
  353. {
  354. level.spectateOverride[game["defenders"]].allowEnemySpectate = 1;
  355. update = true;
  356. }
  357. if ( update )
  358. maps\mp\gametypes\_spectating::updateSpectateSettings();
  359. }
  360.  
  361.  
  362. sd_endGame( winningTeam, endReasonText )
  363. {
  364. level.finalKillCam_winner = winningTeam;
  365. // don't show the final killcam if the game ends with the bomb blowing up or bomb being defused, unless the bomb kills someone
  366. if( endReasonText == game["strings"]["target_destroyed"] || endReasonText == game["strings"]["bomb_defused"] )
  367. {
  368. eraseKillCam = true;
  369. foreach( bombZone in level.bombZones )
  370. {
  371. if( IsDefined( level.finalKillCam_killCamEntityIndex[ winningTeam ] ) && level.finalKillCam_killCamEntityIndex[ winningTeam ] == bombZone.killCamEntNum )
  372. {
  373. eraseKillCam = false;
  374. break;
  375. }
  376. }
  377.  
  378. if( eraseKillCam )
  379. maps\mp\gametypes\_damage::eraseFinalKillCam();
  380. }
  381.  
  382. thread maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
  383. }
  384.  
  385.  
  386. onDeadEvent( team )
  387. {
  388. if ( level.bombExploded || level.bombDefused )
  389. return;
  390.  
  391. if ( team == "all" )
  392. {
  393. if ( level.bombPlanted )
  394. sd_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
  395. else
  396. sd_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
  397. }
  398. else if ( team == game["attackers"] )
  399. {
  400. if ( level.bombPlanted )
  401. return;
  402.  
  403. level thread sd_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
  404. }
  405. else if ( team == game["defenders"] )
  406. {
  407. level thread sd_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
  408. }
  409. }
  410.  
  411.  
  412. onOneLeftEvent( team )
  413. {
  414. if ( level.bombExploded || level.bombDefused )
  415. return;
  416.  
  417. lastPlayer = getLastLivingPlayer( team );
  418.  
  419. lastPlayer thread giveLastOnTeamWarning();
  420. }
  421.  
  422.  
  423. onNormalDeath( victim, attacker, lifeId )
  424. {
  425. score = maps\mp\gametypes\_rank::getScoreInfoValue( "kill" );
  426. assert( isDefined( score ) );
  427.  
  428. team = victim.team;
  429.  
  430. if ( game["state"] == "postgame" && (victim.team == game["defenders"] || !level.bombPlanted) )
  431. attacker.finalKill = true;
  432.  
  433. if ( victim.isPlanting )
  434. {
  435. thread maps\mp\_matchdata::logKillEvent( lifeId, "planting" );
  436.  
  437. //playerstats used for accolades
  438. //attacker incPlayerStat( "defends", 1 );
  439.  
  440. attacker incPersStat( "defends", 1 );
  441. attacker maps\mp\gametypes\_persistence::statSetChild( "round", "defends", attacker.pers["defends"] );
  442.  
  443. }
  444. else if ( victim.isBombCarrier )
  445. {
  446. attacker incPlayerStat( "bombcarrierkills", 1 );
  447. thread maps\mp\_matchdata::logKillEvent( lifeId, "carrying" );
  448. }
  449. else if ( victim.isDefusing )
  450. {
  451. thread maps\mp\_matchdata::logKillEvent( lifeId, "defusing" );
  452.  
  453. //playerstats used for accolades
  454. //attacker incPlayerStat( "defends", 1 );
  455.  
  456. attacker incPersStat( "defends", 1 );
  457. attacker maps\mp\gametypes\_persistence::statSetChild( "round", "defends", attacker.pers["defends"] );
  458. }
  459.  
  460. if ( attacker.isBombCarrier )
  461. attacker incPlayerStat( "killsasbombcarrier", 1 );
  462. }
  463.  
  464.  
  465. giveLastOnTeamWarning()
  466. {
  467. self endon("death");
  468. self endon("disconnect");
  469. level endon( "game_ended" );
  470.  
  471. self waitTillRecoveredHealth( 3 );
  472.  
  473. otherTeam = getOtherTeam( self.pers["team"] );
  474. level thread teamPlayerCardSplash( "callout_lastteammemberalive", self, self.pers["team"] );
  475. level thread teamPlayerCardSplash( "callout_lastenemyalive", self, otherTeam );
  476. level notify ( "last_alive", self );
  477. self maps\mp\gametypes\_missions::lastManSD();
  478. }
  479.  
  480.  
  481. onTimeLimit()
  482. {
  483. sd_endGame( game["defenders"], game["strings"]["time_limit_reached"] );
  484. }
  485.  
  486.  
  487. updateGametypeDvars()
  488. {
  489. level.plantTime = dvarFloatValue( "planttime", 5, 0, 20 );
  490. level.defuseTime = dvarFloatValue( "defusetime", 5, 0, 20 );
  491. level.bombTimer = dvarFloatValue( "bombtimer", 45, 1, 300 );
  492. level.multiBomb = dvarIntValue( "multibomb", 0, 0, 1 );
  493. }
  494.  
  495.  
  496. // to remove Dem overtime bombzone
  497. removeBombZoneC( bombZones )
  498. {
  499. cZones = [];
  500. brushModels = getEntArray( "script_brushmodel", "classname" );
  501. foreach ( brushModel in BrushModels )
  502. {
  503. if ( isDefined( brushModel.script_gameobjectname ) && brushModel.script_gameobjectname == "bombzone" )
  504. {
  505. foreach ( bombZone in bombZones )
  506. {
  507. if ( distance( brushModel.origin, bombZone.origin ) < 100 && isSubStr( toLower( bombZone.script_label ), "c" ) )
  508. {
  509. // track which bombzones need to be removed (2 in mogadishu?)
  510. bombZone.relatedBrushModel = brushModel;
  511. cZones[cZones.size] = bombZone;
  512. break;
  513. }
  514. }
  515. }
  516. }
  517.  
  518. foreach ( cZone in cZones )
  519. {
  520. cZone.relatedBrushModel delete();
  521. visuals = getEntArray( cZone.target, "targetname" );
  522. foreach ( visual in visuals )
  523. visual delete();
  524. cZone delete();
  525. }
  526.  
  527. return array_removeUndefined( bombZones );
  528. }
  529.  
  530.  
  531. bombs()
  532. {
  533. level.bombPlanted = false;
  534. level.bombDefused = false;
  535. level.bombExploded = false;
  536.  
  537. trigger = getEnt( "sd_bomb_pickup_trig", "targetname" );
  538. if ( !isDefined( trigger ) )
  539. {
  540. error("No sd_bomb_pickup_trig trigger found in map.");
  541. return;
  542. }
  543.  
  544. visuals[0] = getEnt( "sd_bomb", "targetname" );
  545. if ( !isDefined( visuals[0] ) )
  546. {
  547. error("No sd_bomb script_model found in map.");
  548. return;
  549. }
  550.  
  551. precacheModel( "prop_suitcase_bomb" );
  552. visuals[0] setModel( "prop_suitcase_bomb" );
  553.  
  554. if ( !level.multiBomb )
  555. {
  556. level.sdBomb = maps\mp\gametypes\_gameobjects::createCarryObject( game["attackers"], trigger, visuals, (0,0,32) );
  557. level.sdBomb maps\mp\gametypes\_gameobjects::allowCarry( "friendly" );
  558. level.sdBomb maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_bomb" );
  559. level.sdBomb maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_bomb" );
  560. level.sdBomb maps\mp\gametypes\_gameobjects::setVisibleTeam( "friendly" );
  561. level.sdBomb maps\mp\gametypes\_gameobjects::setCarryIcon( "hud_suitcase_bomb" );
  562. level.sdBomb.allowWeapons = true;
  563. level.sdBomb.onPickup = ::onPickup;
  564. level.sdBomb.onDrop = ::onDrop;
  565. }
  566. else
  567. {
  568. trigger delete();
  569. visuals[0] delete();
  570. }
  571.  
  572.  
  573. level.bombZones = [];
  574.  
  575. bombZones = getEntArray( "bombzone", "targetname" );
  576. bombZones = removeBombZoneC( bombZones );
  577.  
  578. for ( index = 0; index < bombZones.size; index++ )
  579. {
  580. trigger = bombZones[index];
  581. visuals = getEntArray( bombZones[index].target, "targetname" );
  582.  
  583. bombZone = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, (0,0,64) );
  584. bombZone maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
  585. bombZone maps\mp\gametypes\_gameobjects::setUseTime( level.plantTime );
  586. bombZone maps\mp\gametypes\_gameobjects::setUseText( &"MP_PLANTING_EXPLOSIVE" );
  587. bombZone maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
  588. if ( !level.multiBomb )
  589. bombZone maps\mp\gametypes\_gameobjects::setKeyObject( level.sdBomb );
  590. label = bombZone maps\mp\gametypes\_gameobjects::getLabel();
  591. bombZone.label = label;
  592. bombZone maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defend" + label );
  593. bombZone maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" + label );
  594. bombZone maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_target" + label );
  595. bombZone maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_target" + label );
  596. bombZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
  597. bombZone.onBeginUse = ::onBeginUse;
  598. bombZone.onEndUse = ::onEndUse;
  599. bombZone.onUse = ::onUsePlantObject;
  600. bombZone.onCantUse = ::onCantUse;
  601. bombZone.useWeapon = "briefcase_bomb_mp";
  602.  
  603. for ( i = 0; i < visuals.size; i++ )
  604. {
  605. if ( isDefined( visuals[i].script_exploder ) )
  606. {
  607. bombZone.exploderIndex = visuals[i].script_exploder;
  608.  
  609. visuals[i] thread setupKillCamEnt( bombZone );
  610. break;
  611. }
  612. }
  613.  
  614. level.bombZones[level.bombZones.size] = bombZone;
  615.  
  616. bombZone.bombDefuseTrig = getent( visuals[0].target, "targetname" );
  617. assert( isdefined( bombZone.bombDefuseTrig ) );
  618. bombZone.bombDefuseTrig.origin += (0,0,-10000);
  619. bombZone.bombDefuseTrig.label = label;
  620. }
  621.  
  622. for ( index = 0; index < level.bombZones.size; index++ )
  623. {
  624. array = [];
  625. for ( otherindex = 0; otherindex < level.bombZones.size; otherindex++ )
  626. {
  627. if ( otherindex != index )
  628. array[ array.size ] = level.bombZones[otherindex];
  629. }
  630. level.bombZones[index].otherBombZones = array;
  631. }
  632. }
  633.  
  634. setupKillCamEnt( bombZone ) // self == visuals[i]
  635. {
  636. tempOrg = Spawn( "script_origin", self.origin );
  637. tempOrg.angles = self.angles;
  638. tempOrg RotateYaw( -45, 0.05 );
  639. wait( 0.05 );
  640. bulletStart = self.origin + ( 0, 0, 5 );
  641. bulletEnd = ( self.origin + ( AnglesToForward( tempOrg.angles ) * 100 ) ) + ( 0, 0, 128 );
  642. result = BulletTrace( bulletStart, bulletEnd, false, self );
  643. self.killCamEnt = Spawn( "script_model", result[ "position" ] );
  644. bombZone.killCamEntNum = self.killCamEnt GetEntityNumber();
  645. tempOrg delete();
  646. /#
  647. self.killCamEnt thread debugKillCamEnt( self );
  648. #/
  649. }
  650.  
  651. /#
  652. debugKillCamEnt( visual ) // self == visuals[i].killCamEnt
  653. {
  654. self endon( "death" );
  655. level endon( "game_ended" );
  656. visual endon( "death" );
  657.  
  658. while( true )
  659. {
  660. if( GetDvarInt( "scr_sd_debugBombKillCamEnt" ) > 0 )
  661. {
  662. // show the kill cam ent
  663. Line( self.origin, self.origin + ( AnglesToForward( self.angles ) * 10 ), ( 1, 0, 0 ) );
  664. Line( self.origin, self.origin + ( AnglesToRight( self.angles ) * 10 ), ( 0, 1, 0 ) );
  665. Line( self.origin, self.origin + ( AnglesToUp( self.angles ) * 10 ), ( 0, 0, 1 ) );
  666.  
  667. // line from bomb site to kill cam ent
  668. Line( visual.origin + ( 0, 0, 5 ), self.origin, ( 0, 0, 1 ) );
  669.  
  670. // bomb site angles
  671. Line( visual.origin, visual.origin + ( AnglesToForward( visual.angles ) * 10 ), ( 1, 0, 0 ) );
  672. Line( visual.origin, visual.origin + ( AnglesToRight( visual.angles ) * 10 ), ( 0, 1, 0 ) );
  673. Line( visual.origin, visual.origin + ( AnglesToUp( visual.angles ) * 10 ), ( 0, 0, 1 ) );
  674. }
  675. wait( 0.05 );
  676. }
  677. }
  678. #/
  679.  
  680. onBeginUse( player )
  681. {
  682. if ( self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
  683. {
  684. player playSound( "mp_bomb_defuse" );
  685. player.isDefusing = true;
  686.  
  687. if ( isDefined( level.sdBombModel ) )
  688. level.sdBombModel hide();
  689. }
  690. else
  691. {
  692. player.isPlanting = true;
  693.  
  694. if ( level.multibomb )
  695. {
  696. for ( i = 0; i < self.otherBombZones.size; i++ )
  697. {
  698. //self.otherBombZones[i] maps\mp\gametypes\_gameobjects::disableObject();
  699. self.otherBombZones[i] maps\mp\gametypes\_gameobjects::allowUse( "none" );
  700. self.otherBombZones[i] maps\mp\gametypes\_gameobjects::setVisibleTeam( "friendly" );
  701. }
  702. }
  703. }
  704. }
  705.  
  706. onEndUse( team, player, result )
  707. {
  708. if ( !isDefined( player ) )
  709. return;
  710.  
  711. if ( isAlive( player ) )
  712. {
  713. player.isDefusing = false;
  714. player.isPlanting = false;
  715. }
  716.  
  717. if ( self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
  718. {
  719. if ( isDefined( level.sdBombModel ) && !result )
  720. {
  721. level.sdBombModel show();
  722. }
  723. }
  724. else
  725. {
  726. if ( level.multibomb && !result )
  727. {
  728. for ( i = 0; i < self.otherBombZones.size; i++ )
  729. {
  730. //self.otherBombZones[i] maps\mp\gametypes\_gameobjects::enableObject();
  731. self.otherBombZones[i] maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
  732. self.otherBombZones[i] maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
  733. }
  734. }
  735. }
  736. }
  737.  
  738. onCantUse( player )
  739. {
  740. player iPrintLnBold( &"MP_CANT_PLANT_WITHOUT_BOMB" );
  741. }
  742.  
  743. onUsePlantObject( player )
  744. {
  745. // planted the bomb
  746. if ( !self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
  747. {
  748. level thread bombPlanted( self, player );
  749. //player logString( "bomb planted: " + self.label );
  750.  
  751. // disable all bomb zones except this one
  752. for ( index = 0; index < level.bombZones.size; index++ )
  753. {
  754. if ( level.bombZones[index] == self )
  755. continue;
  756.  
  757. level.bombZones[index] maps\mp\gametypes\_gameobjects::disableObject();
  758. }
  759.  
  760. player playSound( "mp_bomb_plant" );
  761. player notify ( "bomb_planted" );
  762. player notify ( "objective", "plant" ); // gives adrenaline for killstreaks
  763.  
  764. player incPersStat( "plants", 1 );
  765. player maps\mp\gametypes\_persistence::statSetChild( "round", "plants", player.pers["plants"] );
  766.  
  767. //if ( !level.hardcoreMode )
  768. // iPrintLn( &"MP_EXPLOSIVES_PLANTED_BY", player );
  769.  
  770. // bomb carrier class?
  771. if ( isDefined( level.sd_loadout ) && isDefined( level.sd_loadout[player.team] ) )
  772. player thread removeBombCarrierClass();
  773.  
  774. leaderDialog( "bomb_planted" );
  775.  
  776. level thread teamPlayerCardSplash( "callout_bombplanted", player );
  777.  
  778. level.bombOwner = player;
  779. player thread maps\mp\gametypes\_hud_message::SplashNotify( "plant", maps\mp\gametypes\_rank::getScoreInfoValue( "plant" ) );
  780. player thread maps\mp\gametypes\_rank::giveRankXP( "plant" );
  781. player.bombPlantedTime = getTime();
  782. maps\mp\gametypes\_gamescore::givePlayerScore( "plant", player );
  783.  
  784. player thread maps\mp\_matchdata::logGameEvent( "plant", player.origin );
  785. }
  786. }
  787.  
  788.  
  789. applyBombCarrierClass()
  790. {
  791. self endon( "death" );
  792. self endon( "disconnect" );
  793. level endon( "game_ended" );
  794.  
  795. if ( self isJuggernaut() )
  796. {
  797. self notify( "lost_juggernaut" );
  798. wait( 0.05 );
  799. }
  800.  
  801. self.pers["gamemodeLoadout"] = level.sd_loadout[self.team];
  802. self maps\mp\gametypes\_class::giveLoadout( self.team, "gamemode", false, false );
  803. }
  804.  
  805.  
  806. removeBombCarrierClass()
  807. {
  808. self endon( "death" );
  809. self endon( "disconnect" );
  810. level endon( "game_ended" );
  811.  
  812. if ( self isJuggernaut() )
  813. {
  814. self notify( "lost_juggernaut" );
  815. wait( 0.05 );
  816. }
  817.  
  818. self.pers["gamemodeLoadout"] = undefined;
  819. self maps\mp\gametypes\_class::giveLoadout( self.team, self.class, undefined, false );
  820. }
  821.  
  822.  
  823. onUseDefuseObject( player )
  824. {
  825. player notify ( "bomb_defused" );
  826. player notify ( "objective", "defuse" ); // gives adrenaline for killstreaks
  827. //player logString( "bomb defused: " + self.label );
  828. level thread bombDefused();
  829.  
  830. // disable this bomb zone
  831. self maps\mp\gametypes\_gameobjects::disableObject();
  832.  
  833. //if ( !level.hardcoreMode )
  834. // iPrintLn( &"MP_EXPLOSIVES_DEFUSED_BY", player );
  835. leaderDialog( "bomb_defused" );
  836.  
  837. level thread teamPlayerCardSplash( "callout_bombdefused", player );
  838.  
  839. if ( isDefined( level.bombOwner ) && ( level.bombOwner.bombPlantedTime + 3000 + (level.defuseTime*1000) ) > getTime() && isReallyAlive( level.bombOwner ) )
  840. player thread maps\mp\gametypes\_hud_message::SplashNotify( "ninja_defuse", ( maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) ) );
  841. else
  842. player thread maps\mp\gametypes\_hud_message::SplashNotify( "defuse", maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) );
  843.  
  844. player thread maps\mp\gametypes\_rank::giveRankXP( "defuse" );
  845. maps\mp\gametypes\_gamescore::givePlayerScore( "defuse", player );
  846.  
  847. player incPersStat( "defuses", 1 );
  848. player maps\mp\gametypes\_persistence::statSetChild( "round", "defuses", player.pers["defuses"] );
  849.  
  850. player thread maps\mp\_matchdata::logGameEvent( "defuse", player.origin );
  851. }
  852.  
  853.  
  854. onDrop( player )
  855. {
  856. self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_bomb" );
  857. self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_bomb" );
  858.  
  859. maps\mp\_utility::playSoundOnPlayers( game["bomb_dropped_sound"], game["attackers"] );
  860. }
  861.  
  862.  
  863. onPickup( player )
  864. {
  865. player.isBombCarrier = true;
  866. player incPlayerStat( "bombscarried", 1 );
  867. player thread maps\mp\_matchdata::logGameEvent( "pickup", player.origin );
  868.  
  869. self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_escort" );
  870. self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_escort" );
  871.  
  872. // bomb carrier class?
  873. if ( isDefined( level.sd_loadout ) && isDefined( level.sd_loadout[player.team] ) )
  874. player thread applyBombCarrierClass();
  875.  
  876. if ( !level.bombDefused )
  877. {
  878. teamPlayerCardSplash( "callout_bombtaken", player, player.team );
  879. leaderDialog( "bomb_taken", player.pers["team"] );
  880. }
  881. maps\mp\_utility::playSoundOnPlayers( game["bomb_recovered_sound"], game["attackers"] );
  882. }
  883.  
  884.  
  885. onReset()
  886. {
  887. }
  888.  
  889.  
  890. bombPlanted( destroyedObj, player )
  891. {
  892. maps\mp\gametypes\_gamelogic::pauseTimer();
  893. level.bombPlanted = true;
  894.  
  895. destroyedObj.visuals[0] thread maps\mp\gametypes\_gamelogic::playTickingSound();
  896. level.tickingObject = destroyedObj.visuals[0];
  897.  
  898. level.timeLimitOverride = true;
  899. setGameEndTime( int( gettime() + (level.bombTimer * 1000) ) );
  900. setDvar( "ui_bomb_timer", 1 );
  901.  
  902. if ( !level.multiBomb )
  903. {
  904. level.sdBomb maps\mp\gametypes\_gameobjects::allowCarry( "none" );
  905. level.sdBomb maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
  906. level.sdBomb maps\mp\gametypes\_gameobjects::setDropped();
  907. level.sdBombModel = level.sdBomb.visuals[0];
  908. }
  909. else
  910. {
  911.  
  912. for ( index = 0; index < level.players.size; index++ )
  913. {
  914. if ( isDefined( level.players[index].carryIcon ) )
  915. level.players[index].carryIcon destroyElem();
  916. }
  917.  
  918. trace = bulletTrace( player.origin + (0,0,20), player.origin - (0,0,2000), false, player );
  919.  
  920. tempAngle = randomfloat( 360 );
  921. forward = (cos( tempAngle ), sin( tempAngle ), 0);
  922. forward = vectornormalize( forward - ( trace["normal"] * vectordot( forward, trace["normal"] ) ) );
  923. dropAngles = vectortoangles( forward );
  924.  
  925. level.sdBombModel = spawn( "script_model", trace["position"] );
  926. level.sdBombModel.angles = dropAngles;
  927. level.sdBombModel setModel( "prop_suitcase_bomb" );
  928. }
  929. destroyedObj maps\mp\gametypes\_gameobjects::allowUse( "none" );
  930. destroyedObj maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
  931. /*
  932. destroyedObj maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", undefined );
  933. destroyedObj maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", undefined );
  934. destroyedObj maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", undefined );
  935. destroyedObj maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", undefined );
  936. */
  937. label = destroyedObj maps\mp\gametypes\_gameobjects::getLabel();
  938.  
  939. // create a new object to defuse with.
  940. trigger = destroyedObj.bombDefuseTrig;
  941. trigger.origin = level.sdBombModel.origin;
  942. visuals = [];
  943. defuseObject = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, (0,0,32) );
  944. defuseObject maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
  945. defuseObject maps\mp\gametypes\_gameobjects::setUseTime( level.defuseTime );
  946. defuseObject maps\mp\gametypes\_gameobjects::setUseText( &"MP_DEFUSING_EXPLOSIVE" );
  947. defuseObject maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
  948. defuseObject maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
  949. defuseObject maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defuse" + label );
  950. defuseObject maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_defend" + label );
  951. defuseObject maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defuse" + label );
  952. defuseObject maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_defend" + label );
  953. defuseObject.label = label;
  954. defuseObject.onBeginUse = ::onBeginUse;
  955. defuseObject.onEndUse = ::onEndUse;
  956. defuseObject.onUse = ::onUseDefuseObject;
  957. defuseObject.useWeapon = "briefcase_bomb_defuse_mp";
  958.  
  959. BombTimerWait();
  960. setDvar( "ui_bomb_timer", 0 );
  961.  
  962. destroyedObj.visuals[0] maps\mp\gametypes\_gamelogic::stopTickingSound();
  963.  
  964. if ( level.gameEnded || level.bombDefused )
  965. return;
  966.  
  967. level.bombExploded = true;
  968.  
  969. explosionOrigin = level.sdBombModel.origin;
  970. level.sdBombModel hide();
  971.  
  972. if ( isdefined( player ) )
  973. {
  974. destroyedObj.visuals[0] RadiusDamage( explosionOrigin, 512, 200, 20, player, "MOD_EXPLOSIVE", "bomb_site_mp" );
  975. player incPersStat( "destructions", 1 );
  976. player maps\mp\gametypes\_persistence::statSetChild( "round", "destructions", player.pers["destructions"] );
  977. }
  978. else
  979. destroyedObj.visuals[0] RadiusDamage( explosionOrigin, 512, 200, 20, undefined, "MOD_EXPLOSIVE", "bomb_site_mp" );
  980.  
  981. rot = randomfloat(360);
  982. explosionEffect = spawnFx( level._effect["bombexplosion"], explosionOrigin + (0,0,50), (0,0,1), (cos(rot),sin(rot),0) );
  983. triggerFx( explosionEffect );
  984.  
  985. PlayRumbleOnPosition( "grenade_rumble", explosionOrigin );
  986. earthquake( 0.75, 2.0, explosionOrigin, 2000 );
  987. wii_play_grenade_rumble( explosionOrigin );
  988.  
  989. thread playSoundinSpace( "exp_suitcase_bomb_main", explosionOrigin );
  990.  
  991. if ( isDefined( destroyedObj.exploderIndex ) )
  992. exploder( destroyedObj.exploderIndex );
  993.  
  994. for ( index = 0; index < level.bombZones.size; index++ )
  995. level.bombZones[index] maps\mp\gametypes\_gameobjects::disableObject();
  996. defuseObject maps\mp\gametypes\_gameobjects::disableObject();
  997.  
  998. setGameEndTime( 0 );
  999.  
  1000. wait 3;
  1001.  
  1002. sd_endGame( game["attackers"], game["strings"]["target_destroyed"] );
  1003. }
  1004.  
  1005.  
  1006. BombTimerWait()
  1007. {
  1008. level endon( "game_ended" );
  1009. level endon( "bomb_defused" );
  1010.  
  1011. bombEndMilliseconds = (level.bombTimer * 1000) + gettime();
  1012. SetDvar( "ui_bomb_timer_endtime", bombEndMilliseconds );
  1013.  
  1014. level thread handleHostMigration( bombEndMilliseconds );
  1015. maps\mp\gametypes\_hostmigration::waitLongDurationWithGameEndTimeUpdate( level.bombTimer );
  1016. }
  1017.  
  1018.  
  1019. handleHostMigration( bombEndMilliseconds )
  1020. {
  1021. level endon( "game_ended" );
  1022. level endon( "bomb_defused" );
  1023. level endon( "game_ended" );
  1024. level endon( "disconnect" );
  1025.  
  1026. level waittill( "host_migration_begin" );
  1027.  
  1028. timePassed = maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
  1029.  
  1030. if ( timePassed > 0 )
  1031. {
  1032. SetDvar( "ui_bomb_timer_endtime", bombEndMilliseconds + timePassed );
  1033. }
  1034. }
  1035.  
  1036.  
  1037. bombDefused()
  1038. {
  1039. level.tickingObject maps\mp\gametypes\_gamelogic::stopTickingSound();
  1040. level.bombDefused = true;
  1041. setDvar( "ui_bomb_timer", 0 );
  1042.  
  1043. level notify("bomb_defused");
  1044.  
  1045. wait 1.5;
  1046.  
  1047. setGameEndTime( 0 );
  1048.  
  1049. sd_endGame( game["defenders"], game["strings"]["bomb_defused"] );
  1050. }
  1051.  
  1052. initGametypeAwards()
  1053. {
  1054. maps\mp\_awards::initStatAward( "targetsdestroyed", 0, maps\mp\_awards::highestWins );
  1055. maps\mp\_awards::initStatAward( "bombsplanted", 0, maps\mp\_awards::highestWins );
  1056. maps\mp\_awards::initStatAward( "bombsdefused", 0, maps\mp\_awards::highestWins );
  1057. maps\mp\_awards::initStatAward( "bombcarrierkills", 0, maps\mp\_awards::highestWins );
  1058. maps\mp\_awards::initStatAward( "bombscarried", 0, maps\mp\_awards::highestWins );
  1059. maps\mp\_awards::initStatAward( "killsasbombcarrier", 0, maps\mp\_awards::highestWins );
  1060. }
  1061.  
  1062.  
  1063. setSpecialLoadout()
  1064. {
  1065. // attacker bomb carrier
  1066. if ( isUsingMatchRulesData() && GetMatchRulesData( "defaultClasses", "axis", 5, "class", "inUse" ) )
  1067. {
  1068. level.sd_loadout[game["attackers"]] = getMatchRulesSpecialClass( "axis", 5 );
  1069. }
  1070. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement