CSHARP 202
Sd.gsc Guest on 18th April 2021 07:28:56 PM
  1. #include maps\mp\_utility;
  2. #include maps\mp\gametypes\_hud_util;
  3. // Rallypoints should be destroyed on leaving your team/getting killed
  4. // Compass icons need to be looked at
  5. // Doesn't seem to be setting angle on spawn so that you are facing your rallypoint
  6.  
  7. /*
  8.     Search and Destroy
  9.     Attackers objective: Bomb one of 2 positions
  10.     Defenders objective: Defend these 2 positions / Defuse planted bombs
  11.     Round ends: When one team is eliminated, bomb explodes, bomb is defused, or roundlength time is reached
  12.     Map ends:   When one team reaches the score limit, or time limit or round limit is reached
  13.     Respawning: Players remain dead for the round and will respawn at the beginning of the next round
  14.  
  15.     Level requirements
  16.     ------------------
  17.         Allied Spawnpoints:
  18.             classname       mp_sd_spawn_attacker
  19.             Allied players spawn from these. Place at least 16 of these relatively close together.
  20.  
  21.         Axis Spawnpoints:
  22.             classname       mp_sd_spawn_defender
  23.             Axis players spawn from these. Place at least 16 of these relatively close together.
  24.  
  25.         Spectator Spawnpoints:
  26.             classname       mp_global_intermission
  27.             Spectators spawn from these and intermission is viewed from these positions.
  28.             Atleast one is required, any more and they are randomly chosen between.
  29.  
  30.         Bombzones:
  31.             classname                   trigger_multiple
  32.             targetname                  bombzone
  33.             script_gameobjectname       bombzone
  34.             script_bombmode_original    <if defined this bombzone will be used in the original bomb mode>
  35.             script_bombmode_single      <if defined this bombzone will be used in the single bomb mode>
  36.             script_bombmode_dual        <if defined this bombzone will be used in the dual bomb mode>
  37.             script_team                 Set to allies or axis. This is used to set which team a bombzone is used by in dual bomb mode.
  38.             script_label                Set to A or B. This sets the letter shown on the compass in original mode.
  39.             This is a volume of space in which the bomb can planted. Must contain an origin brush.
  40.  
  41.         Bomb:
  42.             classname               trigger_lookat
  43.             targetname              bombtrigger
  44.             script_gameobjectname   bombzone
  45.             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.
  46.             Must be in the level somewhere. This is the trigger that is used when defusing a bomb.
  47.             It gets moved to the position of the planted bomb model.
  48.  
  49.     Level script requirements
  50.     -------------------------
  51.         Team Definitions:
  52.             game["allies"] = "marines";
  53.             game["axis"] = "opfor";
  54.             This sets the nationalities of the teams. Allies can be american, british, or russian. Axis can be german.
  55.  
  56.             game["attackers"] = "allies";
  57.             game["defenders"] = "axis";
  58.             This sets which team is attacking and which team is defending. Attackers plant the bombs. Defenders protect the targets.
  59.  
  60.         If using minefields or exploders:
  61.             maps\mp\_load::main();
  62.  
  63.     Optional level script settings
  64.     ------------------------------
  65.         Soldier Type and Variation:
  66.             game["american_soldiertype"] = "normandy";
  67.             game["german_soldiertype"] = "normandy";
  68.             This sets what character models are used for each nationality on a particular map.
  69.  
  70.             Valid settings:
  71.                 american_soldiertype    normandy
  72.                 british_soldiertype     normandy, africa
  73.                 russian_soldiertype     coats, padded
  74.                 german_soldiertype      normandy, africa, winterlight, winterdark
  75.  
  76.         Exploder Effects:
  77.             Setting script_noteworthy on a bombzone trigger to an exploder group can be used to trigger additional effects.
  78. */
  79.  
  80. /*QUAKED mp_sd_spawn_attacker (0.0 1.0 0.0) (-16 -16 0) (16 16 72)
  81. Attacking players spawn randomly at one of these positions at the beginning of a round.*/
  82.  
  83. /*QUAKED mp_sd_spawn_defender (1.0 0.0 0.0) (-16 -16 0) (16 16 72)
  84. Defending players spawn randomly at one of these positions at the beginning of a round.*/
  85.  
  86. main()
  87. {
  88.     if(getdvar("mapname") == "mp_background")
  89.         return;
  90.    
  91.     maps\mp\gametypes\_globallogic::init();
  92.     maps\mp\gametypes\_callbacksetup::SetupCallbacks();
  93.     maps\mp\gametypes\_globallogic::SetupCallbacks();
  94.     if(level.ex_blackscreen) maps\mp\gametypes\_blackscreen::init();
  95.    
  96.     maps\mp\gametypes\_globallogic::registerRoundSwitchDvar( level.gameType, 3, 0, 999 );
  97.     maps\mp\gametypes\_globallogic::registerTimeLimitDvar( level.gameType, 2.5, 0, 1440 );
  98.     maps\mp\gametypes\_globallogic::registerScoreLimitDvar( level.gameType, 4, 0, 500 );
  99.     maps\mp\gametypes\_globallogic::registerRoundLimitDvar( level.gameType, 0, 0, 999 );
  100.     maps\mp\gametypes\_globallogic::registerNumLivesDvar( level.gameType, 1, 0, 10 );
  101.    
  102.     level.teamBased = true;
  103.     level.overrideTeamScore = true;
  104.     level.onPrecacheGameType = ::onPrecacheGameType;
  105.     level.onStartGameType = ::onStartGameType;
  106.     level.onSpawnPlayer = ::onSpawnPlayer;
  107.     level.onPlayerKilled = ::onPlayerKilled;
  108.     level.onDeadEvent = ::onDeadEvent;
  109.     level.onOneLeftEvent = ::onOneLeftEvent;
  110.     level.onTimeLimit = ::onTimeLimit;
  111.     level.onRoundSwitch = ::onRoundSwitch;
  112.    
  113.     level.endGameOnScoreLimit = false;
  114.    
  115.     game["dialog"]["gametype"] = "searchdestroy";
  116.     game["dialog"]["offense_obj"] = "obj_destroy";
  117.     game["dialog"]["defense_obj"] = "obj_defend";
  118. }
  119.  
  120.  
  121. onPrecacheGameType()
  122. {
  123.     game["bombmodelname"] = "mil_tntbomb_mp";
  124.     game["bombmodelnameobj"] = "mil_tntbomb_mp";
  125.     game["bomb_dropped_sound"] = "mp_war_objective_lost";
  126.     game["bomb_recovered_sound"] = "mp_war_objective_taken";
  127.     precacheModel(game["bombmodelname"]);
  128.     precacheModel(game["bombmodelnameobj"]);
  129.  
  130.     precacheShader("waypoint_bomb");
  131.     precacheShader("hud_suitcase_bomb");
  132.     precacheShader("waypoint_target");
  133.     precacheShader("waypoint_target_a");
  134.     precacheShader("waypoint_target_b");
  135.     precacheShader("waypoint_defend");
  136.     precacheShader("waypoint_defend_a");
  137.     precacheShader("waypoint_defend_b");
  138.     precacheShader("waypoint_defuse");
  139.     precacheShader("waypoint_defuse_a");
  140.     precacheShader("waypoint_defuse_b");
  141.     precacheShader("compass_waypoint_target");
  142.     precacheShader("compass_waypoint_target_a");
  143.     precacheShader("compass_waypoint_target_b");
  144.     precacheShader("compass_waypoint_defend");
  145.     precacheShader("compass_waypoint_defend_a");
  146.     precacheShader("compass_waypoint_defend_b");
  147.     precacheShader("compass_waypoint_defuse");
  148.     precacheShader("compass_waypoint_defuse_a");
  149.     precacheShader("compass_waypoint_defuse_b");
  150. }
  151.  
  152. onRoundSwitch()
  153. {
  154.     if ( !isdefined( game["switchedsides"] ) )
  155.         game["switchedsides"] = false;
  156.    
  157.     if ( game["teamScores"]["allies"] == level.scorelimit - 1 && game["teamScores"]["axis"] == level.scorelimit - 1 )
  158.     {
  159.         // overtime! team that's ahead in kills gets to defend.
  160.         aheadTeam = getBetterTeam();
  161.         if ( aheadTeam != game["defenders"] )
  162.         {
  163.             game["switchedsides"] = !game["switchedsides"];
  164.         }
  165.         else
  166.         {
  167.             level.halftimeSubCaption = "";
  168.         }
  169.         level.halftimeType = "overtime";
  170.     }
  171.     else
  172.     {
  173.         level.halftimeType = "halftime";
  174.         game["switchedsides"] = !game["switchedsides"];
  175.     }
  176. }
  177.  
  178. getBetterTeam()
  179. {
  180.     kills["allies"] = 0;
  181.     kills["axis"] = 0;
  182.     deaths["allies"] = 0;
  183.     deaths["axis"] = 0;
  184.    
  185.     for ( i = 0; i < level.players.size; i++ )
  186.     {
  187.         player = level.players[i];
  188.         team = player.pers["team"];
  189.         if ( isDefined( team ) && (team == "allies" || team == "axis") )
  190.         {
  191.             kills[ team ] += player.kills;
  192.             deaths[ team ] += player.deaths;
  193.         }
  194.     }
  195.    
  196.     if ( kills["allies"] > kills["axis"] )
  197.         return "allies";
  198.     else if ( kills["axis"] > kills["allies"] )
  199.         return "axis";
  200.    
  201.     // same number of kills
  202.  
  203.     if ( deaths["allies"] < deaths["axis"] )
  204.         return "allies";
  205.     else if ( deaths["axis"] < deaths["allies"] )
  206.         return "axis";
  207.    
  208.     // same number of deaths
  209.    
  210.     if ( randomint(2) == 0 )
  211.         return "allies";
  212.     return "axis";
  213. }
  214.  
  215. onStartGameType()
  216. {
  217.     if ( !isDefined( game["switchedsides"] ) )
  218.         game["switchedsides"] = false;
  219.    
  220.     if ( game["switchedsides"] )
  221.     {
  222.         oldAttackers = game["attackers"];
  223.         oldDefenders = game["defenders"];
  224.         game["attackers"] = oldDefenders;
  225.         game["defenders"] = oldAttackers;
  226.     }
  227.    
  228.     setClientNameMode( "manual_change" );
  229.    
  230.     game["strings"]["target_destroyed"] = &"MP_TARGET_DESTROYED";
  231.     game["strings"]["bomb_defused"] = &"MP_BOMB_DEFUSED";
  232.    
  233.     precacheString( game["strings"]["target_destroyed"] );
  234.     precacheString( game["strings"]["bomb_defused"] );
  235.  
  236.     level._effect["bombexplosion"] = loadfx("explosions/tanker_explosion");
  237.    
  238.     maps\mp\gametypes\_globallogic::setObjectiveText( game["attackers"], &"OBJECTIVES_SD_ATTACKER" );
  239.     maps\mp\gametypes\_globallogic::setObjectiveText( game["defenders"], &"OBJECTIVES_SD_DEFENDER" );
  240.  
  241.     if ( level.splitscreen )
  242.     {
  243.         maps\mp\gametypes\_globallogic::setObjectiveScoreText( game["attackers"], &"OBJECTIVES_SD_ATTACKER" );
  244.         maps\mp\gametypes\_globallogic::setObjectiveScoreText( game["defenders"], &"OBJECTIVES_SD_DEFENDER" );
  245.     }
  246.     else
  247.     {
  248.         maps\mp\gametypes\_globallogic::setObjectiveScoreText( game["attackers"], &"OBJECTIVES_SD_ATTACKER_SCORE" );
  249.         maps\mp\gametypes\_globallogic::setObjectiveScoreText( game["defenders"], &"OBJECTIVES_SD_DEFENDER_SCORE" );
  250.     }
  251.     maps\mp\gametypes\_globallogic::setObjectiveHintText( game["attackers"], &"OBJECTIVES_SD_ATTACKER_HINT" );
  252.     maps\mp\gametypes\_globallogic::setObjectiveHintText( game["defenders"], &"OBJECTIVES_SD_DEFENDER_HINT" );
  253.  
  254.     level.spawnMins = ( 0, 0, 0 );
  255.     level.spawnMaxs = ( 0, 0, 0 ); 
  256.     maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_sd_spawn_attacker" );
  257.     maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_sd_spawn_defender" );
  258.    
  259.     level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
  260.     setMapCenter( level.mapCenter );
  261.    
  262.     allowed[0] = "sd";
  263.     allowed[1] = "bombzone";
  264.     allowed[2] = "blocker";
  265.     maps\mp\gametypes\_gameobjects::main(allowed);
  266.    
  267.     maps\mp\gametypes\_rank::registerScoreInfo( "win", 2 );
  268.     maps\mp\gametypes\_rank::registerScoreInfo( "loss", 1 );
  269.     maps\mp\gametypes\_rank::registerScoreInfo( "tie", 1.5 );
  270.    
  271.     maps\mp\gametypes\_rank::registerScoreInfo( "kill", 5 );
  272.     maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 5 );
  273.     maps\mp\gametypes\_rank::registerScoreInfo( "assist", 2 );
  274.     maps\mp\gametypes\_rank::registerScoreInfo( "plant", 10 );
  275.     maps\mp\gametypes\_rank::registerScoreInfo( "defuse", 10 );
  276.  
  277.     thread updateGametypeDvars();
  278.    
  279.     thread bombs();
  280. }
  281.  
  282.  
  283. onSpawnPlayer()
  284. {
  285.     self.isPlanting = false;
  286.     self.isDefusing = false;
  287.     self.isBombCarrier = false;
  288.  
  289.     if(self.pers["team"] == game["attackers"])
  290.         spawnPointName = "mp_sd_spawn_attacker";
  291.     else
  292.         spawnPointName = "mp_sd_spawn_defender";
  293.  
  294.     if ( level.multiBomb && !isDefined( self.carryIcon ) && self.pers["team"] == game["attackers"] && !level.bombPlanted )
  295.     {
  296.         if ( level.splitscreen )
  297.         {
  298.             self.carryIcon = createIcon( "hud_suitcase_bomb", 35, 35 );
  299.             self.carryIcon setPoint( "BOTTOM RIGHT", "BOTTOM RIGHT", -10, -50 );
  300.             self.carryIcon.alpha = 0.75;
  301.         }
  302.         else
  303.         {
  304.             self.carryIcon = createIcon( "hud_suitcase_bomb", 50, 50 );
  305.             self.carryIcon setPoint( "CENTER", "CENTER", 220, 140 );
  306.             self.carryIcon.alpha = 0.75;
  307.         }
  308.     }
  309.  
  310.     spawnPoints = getEntArray( spawnPointName, "classname" );
  311.     assert( spawnPoints.size );
  312.     spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
  313.  
  314.     self spawn( spawnpoint.origin, spawnpoint.angles );
  315.  
  316.     level notify ( "spawned_player" );
  317. }
  318.  
  319.  
  320. onPlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration)
  321. {
  322.     thread checkAllowSpectating();
  323. }
  324.  
  325.  
  326. checkAllowSpectating()
  327. {
  328.     wait ( 0.05 * level.fps_multiplier );
  329.    
  330.     update = false;
  331.     if ( !level.aliveCount[ game["attackers"] ] )
  332.     {
  333.         level.spectateOverride[game["attackers"]].allowEnemySpectate = 1;
  334.         update = true;
  335.     }
  336.     if ( !level.aliveCount[ game["defenders"] ] )
  337.     {
  338.         level.spectateOverride[game["defenders"]].allowEnemySpectate = 1;
  339.         update = true;
  340.     }
  341.     if ( update )
  342.         maps\mp\gametypes\_spectating::updateSpectateSettings();
  343. }
  344.  
  345.  
  346. sd_endGame( winningTeam, endReasonText )
  347. {
  348.     if ( isdefined( winningTeam ) )
  349.         [[level._setTeamScore]]( winningTeam, [[level._getTeamScore]]( winningTeam ) + 1 );
  350.    
  351.     thread maps\mp\gametypes\_globallogic::endGame( winningTeam, endReasonText );
  352. }
  353.  
  354.  
  355. onDeadEvent( team )
  356. {
  357.     if ( level.bombExploded || level.bombDefused )
  358.         return;
  359.    
  360.     if ( team == "all" )
  361.     {
  362.         if ( level.bombPlanted )
  363.             sd_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
  364.         else
  365.             sd_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
  366.     }
  367.     else if ( team == game["attackers"] )
  368.     {
  369.         if ( level.bombPlanted )
  370.             return;
  371.        
  372.         sd_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
  373.     }
  374.     else if ( team == game["defenders"] )
  375.     {
  376.         sd_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
  377.     }
  378. }
  379.  
  380.  
  381. onOneLeftEvent( team )
  382. {
  383.     if ( level.bombExploded || level.bombDefused )
  384.         return;
  385.    
  386.     //if ( team == game["attackers"] )
  387.     warnLastPlayer( team );
  388. }
  389.  
  390.  
  391. onTimeLimit()
  392. {
  393.     if ( level.teamBased )
  394.         sd_endGame( game["defenders"], game["strings"]["time_limit_reached"] );
  395.     else
  396.         sd_endGame( undefined, game["strings"]["time_limit_reached"] );
  397. }
  398.  
  399.  
  400. warnLastPlayer( team )
  401. {
  402.     if ( !isdefined( level.warnedLastPlayer ) )
  403.         level.warnedLastPlayer = [];
  404.    
  405.     if ( isDefined( level.warnedLastPlayer[team] ) )
  406.         return;
  407.        
  408.     level.warnedLastPlayer[team] = true;
  409.  
  410.     players = level.players;
  411.     for ( i = 0; i < players.size; i++ )
  412.     {
  413.         player = players[i];
  414.  
  415.         if ( isDefined( player.pers["team"] ) && player.pers["team"] == team && isdefined( player.pers["class"] ) )
  416.         {
  417.             if ( player.sessionstate == "playing" && !player.afk )
  418.                 break;
  419.         }
  420.     }
  421.    
  422.     if ( i == players.size )
  423.         return;
  424.    
  425.     players[i] thread giveLastAttackerWarning();
  426. }
  427.  
  428.  
  429. giveLastAttackerWarning()
  430. {
  431.     self endon("death");
  432.     self endon("disconnect");
  433.    
  434.     fullHealthTime = 0;
  435.     interval = .05;
  436.    
  437.     while(1)
  438.     {
  439.         if ( self.health != self.maxhealth )
  440.             fullHealthTime = 0;
  441.         else
  442.             fullHealthTime += interval;
  443.        
  444.         wait (interval * level.fps_multiplier );
  445.        
  446.         if (self.health == self.maxhealth && fullHealthTime >= 3)
  447.             break;
  448.     }
  449.    
  450.     //self iprintlnbold(&"MP_YOU_ARE_THE_ONLY_REMAINING_PLAYER");
  451.     self maps\mp\gametypes\_globallogic::leaderDialogOnPlayer( "last_alive" );
  452.    
  453.     self maps\mp\gametypes\_missions::lastManSD();
  454. }
  455.  
  456.  
  457. updateGametypeDvars()
  458. {
  459.     level.plantTime = dvarFloatValue( "planttime", 5, 0, 20 );
  460.     level.defuseTime = dvarFloatValue( "defusetime", 5, 0, 20 );
  461.     level.bombTimer = dvarFloatValue( "bombtimer", 45, 1, 300 );
  462.     level.multiBomb = dvarIntValue( "multibomb", 0, 0, 1 );
  463. }
  464.  
  465.  
  466. bombs()
  467. {
  468.     level.bombPlanted = false;
  469.     level.bombDefused = false;
  470.     level.bombExploded = false;
  471.  
  472.     trigger = getEnt( "sd_bomb_pickup_trig", "targetname" );
  473.     if ( !isDefined( trigger ) )
  474.     {
  475.         maps\mp\_utility::error("No sd_bomb_pickup_trig trigger found in map.");
  476.         return;
  477.     }
  478.    
  479.     visuals[0] = getEnt( "sd_bomb", "targetname" );
  480.     if ( !isDefined( visuals[0] ) )
  481.     {
  482.         maps\mp\_utility::error("No sd_bomb script_model found in map.");
  483.         return;
  484.     }
  485.  
  486.     precacheModel( "prop_suitcase_bomb" ); 
  487.     visuals[0] setModel( "prop_suitcase_bomb" );
  488.    
  489.     if ( !level.multiBomb )
  490.     {
  491.         level.sdBomb = maps\mp\gametypes\_gameobjects::createCarryObject( game["attackers"], trigger, visuals, (0,0,32) );
  492.         level.sdBomb maps\mp\gametypes\_gameobjects::allowCarry( "friendly" );
  493.         level.sdBomb maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "compass_waypoint_bomb" );
  494.         level.sdBomb maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_bomb" );
  495.         level.sdBomb maps\mp\gametypes\_gameobjects::setVisibleTeam( "friendly" );
  496.         level.sdBomb maps\mp\gametypes\_gameobjects::setCarryIcon( "hud_suitcase_bomb" );
  497.         level.sdBomb.allowWeapons = true;
  498.         level.sdBomb.onPickup = ::onPickup;
  499.         level.sdBomb.onDrop = ::onDrop;
  500.     }
  501.     else
  502.     {
  503.         trigger delete();
  504.         visuals[0] delete();
  505.     }
  506.    
  507.    
  508.     level.bombZones = [];
  509.    
  510.     bombZones = getEntArray( "bombzone", "targetname" );
  511.    
  512.     for ( index = 0; index < bombZones.size; index++ )
  513.     {
  514.         trigger = bombZones[index];
  515.         visuals = getEntArray( bombZones[index].target, "targetname" );
  516.        
  517.         bombZone = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, (0,0,64) );
  518.         bombZone maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
  519.         bombZone maps\mp\gametypes\_gameobjects::setUseTime( level.plantTime * level.fps_multiplier );
  520.         bombZone maps\mp\gametypes\_gameobjects::setUseText( &"MP_PLANTING_EXPLOSIVE" );
  521.         bombZone maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
  522.         if ( !level.multiBomb )
  523.             bombZone maps\mp\gametypes\_gameobjects::setKeyObject( level.sdBomb );
  524.         label = bombZone maps\mp\gametypes\_gameobjects::getLabel();
  525.         bombZone.label = label;
  526.         bombZone maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "compass_waypoint_defend" + label );
  527.         bombZone maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" + label );
  528.         bombZone maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "compass_waypoint_target" + label );
  529.         bombZone maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_target" + label );
  530.         bombZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
  531.         bombZone.onBeginUse = ::onBeginUse;
  532.         bombZone.onEndUse = ::onEndUse;
  533.         bombZone.onUse = ::onUsePlantObject;
  534.         bombZone.onCantUse = ::onCantUse;
  535.         bombZone.useWeapon = "briefcase_bomb_mp";
  536.        
  537.         for ( i = 0; i < visuals.size; i++ )
  538.         {
  539.             if ( isDefined( visuals[i].script_exploder ) )
  540.             {
  541.                 bombZone.exploderIndex = visuals[i].script_exploder;
  542.                 break;
  543.             }
  544.         }
  545.        
  546.         level.bombZones[level.bombZones.size] = bombZone;
  547.        
  548.         bombZone.bombDefuseTrig = getent( visuals[0].target, "targetname" );
  549.         assert( isdefined( bombZone.bombDefuseTrig ) );
  550.         bombZone.bombDefuseTrig.origin += (0,0,-10000);
  551.         bombZone.bombDefuseTrig.label = label;
  552.     }
  553.    
  554.     for ( index = 0; index < level.bombZones.size; index++ )
  555.     {
  556.         array = [];
  557.         for ( otherindex = 0; otherindex < level.bombZones.size; otherindex++ )
  558.         {
  559.             if ( otherindex != index )
  560.                 array[ array.size ] = level.bombZones[otherindex];
  561.         }
  562.         level.bombZones[index].otherBombZones = array;
  563.     }
  564. }
  565.  
  566. onBeginUse( player )
  567. {
  568.     if ( self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
  569.     {
  570.         player playSound( "mp_bomb_defuse" );
  571.         player.isDefusing = true;
  572.        
  573.         if ( isDefined( level.sdBombModel ) )
  574.             level.sdBombModel hide();
  575.     }
  576.     else
  577.     {
  578.         player.isPlanting = true;
  579.  
  580.         if ( level.multibomb )
  581.         {
  582.             for ( i = 0; i < self.otherBombZones.size; i++ )
  583.             {
  584.                 self.otherBombZones[i] maps\mp\gametypes\_gameobjects::disableObject();
  585.             }
  586.         }
  587.     }
  588. }
  589.  
  590. onEndUse( team, player, result )
  591. {
  592.     if ( !isAlive( player ) )
  593.         return;
  594.        
  595.     player.isDefusing = false;
  596.     player.isPlanting = false;
  597.  
  598.     if ( self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
  599.     {
  600.         if ( isDefined( level.sdBombModel ) && !result )
  601.         {
  602.             level.sdBombModel show();
  603.         }
  604.     }
  605.     else
  606.     {
  607.         if ( level.multibomb && !result )
  608.         {
  609.             for ( i = 0; i < self.otherBombZones.size; i++ )
  610.             {
  611.                 self.otherBombZones[i] maps\mp\gametypes\_gameobjects::enableObject();
  612.             }
  613.         }
  614.     }
  615. }
  616.  
  617. onCantUse( player )
  618. {
  619.     player iPrintLnBold( &"MP_CANT_PLANT_WITHOUT_BOMB" );
  620. }
  621.  
  622. onUsePlantObject( player )
  623. {
  624.     // planted the bomb
  625.     if ( !self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
  626.     {
  627.         level thread bombPlanted( self, player );
  628.         player logString( "bomb planted: " + self.label );
  629.        
  630.         // disable all bomb zones except this one
  631.         for ( index = 0; index < level.bombZones.size; index++ )
  632.         {
  633.             if ( level.bombZones[index] == self )
  634.                 continue;
  635.                
  636.             level.bombZones[index] maps\mp\gametypes\_gameobjects::disableObject();
  637.         }
  638.        
  639.         player playSound( "mp_bomb_plant" );
  640.         player notify ( "bomb_planted" );
  641.         if ( !level.hardcoreMode )
  642.             iPrintLn( &"MP_EXPLOSIVES_PLANTED_BY", player );
  643.         maps\mp\gametypes\_globallogic::leaderDialog( "bomb_planted" );
  644.  
  645.         maps\mp\gametypes\_globallogic::givePlayerScore( "plant", player );
  646.         player thread [[level.onXPEvent]]( "plant" );
  647.     }
  648. }
  649.  
  650. onUseDefuseObject( player )
  651. {
  652.     wait (.05 * level.fps_multiplier );
  653.    
  654.     player notify ( "bomb_defused" );
  655.     player logString( "bomb defused: " + self.label );
  656.     level thread bombDefused();
  657.    
  658.     // disable this bomb zone
  659.     self maps\mp\gametypes\_gameobjects::disableObject();
  660.    
  661.     if ( !level.hardcoreMode )
  662.         iPrintLn( &"MP_EXPLOSIVES_DEFUSED_BY", player );
  663.     maps\mp\gametypes\_globallogic::leaderDialog( "bomb_defused" );
  664.  
  665.     maps\mp\gametypes\_globallogic::givePlayerScore( "defuse", player );
  666.     player thread [[level.onXPEvent]]( "defuse" );
  667. }
  668.  
  669.  
  670. onDrop( player )
  671. {
  672.     if ( !level.bombPlanted )
  673.     {
  674.         if ( isDefined( player ) && isDefined( player.name ) )
  675.             printOnTeamArg( &"MP_EXPLOSIVES_DROPPED_BY", game["attackers"], player );
  676.  
  677. //      maps\mp\gametypes\_globallogic::leaderDialog( "bomb_lost", player.pers["team"] );
  678.         if ( isDefined( player ) )
  679.             player logString( "bomb dropped" );
  680.          else
  681.             logString( "bomb dropped" );
  682.     }
  683.  
  684.     self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_bomb" );
  685.    
  686.     maps\mp\_utility::playSoundOnPlayers( game["bomb_dropped_sound"], game["attackers"] );
  687. }
  688.  
  689.  
  690. onPickup( player )
  691. {
  692.     player.isBombCarrier = true;
  693.  
  694.     self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" );
  695.  
  696.     if ( !level.bombDefused )
  697.     {
  698.         if ( isDefined( player ) && isDefined( player.name ) )
  699.             printOnTeamArg( &"MP_EXPLOSIVES_RECOVERED_BY", game["attackers"], player );
  700.            
  701.         maps\mp\gametypes\_globallogic::leaderDialog( "bomb_taken", player.pers["team"] );
  702.         player logString( "bomb taken" );
  703.     }      
  704.     maps\mp\_utility::playSoundOnPlayers( game["bomb_recovered_sound"], game["attackers"] );
  705. }
  706.  
  707.  
  708. onReset()
  709. {
  710. }
  711.  
  712.  
  713. bombPlanted( destroyedObj, player )
  714. {
  715.     maps\mp\gametypes\_globallogic::pauseTimer();
  716.     level.bombPlanted = true;
  717.    
  718.     destroyedObj.visuals[0] thread maps\mp\gametypes\_globallogic::playTickingSound();
  719.     level.tickingObject = destroyedObj.visuals[0];
  720.  
  721.     level.timeLimitOverride = true;
  722.     setGameEndTime( int( gettime() + (level.bombTimer * 1000) ) );
  723.     setDvar( "ui_bomb_timer", 1 );
  724.    
  725.     if ( !level.multiBomb )
  726.     {
  727.         level.sdBomb maps\mp\gametypes\_gameobjects::allowCarry( "none" );
  728.         level.sdBomb maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
  729.         level.sdBomb maps\mp\gametypes\_gameobjects::setDropped();
  730.         level.sdBombModel = level.sdBomb.visuals[0];
  731.     }
  732.     else
  733.     {
  734.        
  735.         for ( index = 0; index < level.players.size; index++ )
  736.         {
  737.             if ( isDefined( level.players[index].carryIcon ) )
  738.                 level.players[index].carryIcon destroyElem();
  739.         }
  740.  
  741.         trace = bulletTrace( player.origin + (0,0,20), player.origin - (0,0,2000), false, player );
  742.        
  743.         tempAngle = randomfloat( 360 );
  744.         forward = (cos( tempAngle ), sin( tempAngle ), 0);
  745.         forward = vectornormalize( forward - vector_scale( trace["normal"], vectordot( forward, trace["normal"] ) ) );
  746.         dropAngles = vectortoangles( forward );
  747.        
  748.         level.sdBombModel = spawn( "script_model", trace["position"] );
  749.         level.sdBombModel.angles = dropAngles;
  750.         level.sdBombModel setModel( "prop_suitcase_bomb" );
  751.     }
  752.     destroyedObj maps\mp\gametypes\_gameobjects::allowUse( "none" );
  753.     destroyedObj maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
  754.     /*
  755.     destroyedObj maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", undefined );
  756.     destroyedObj maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", undefined );
  757.     destroyedObj maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", undefined );
  758.     destroyedObj maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", undefined );
  759.     */
  760.     label = destroyedObj maps\mp\gametypes\_gameobjects::getLabel();
  761.    
  762.     // create a new object to defuse with.
  763.     trigger = destroyedObj.bombDefuseTrig;
  764.     trigger.origin = level.sdBombModel.origin;
  765.     visuals = [];
  766.     defuseObject = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, (0,0,32) );
  767.     defuseObject maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
  768.     defuseObject maps\mp\gametypes\_gameobjects::setUseTime( level.defuseTime * level.fps_multiplier );
  769.     defuseObject maps\mp\gametypes\_gameobjects::setUseText( &"MP_DEFUSING_EXPLOSIVE" );
  770.     defuseObject maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
  771.     defuseObject maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
  772.     defuseObject maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "compass_waypoint_defuse" + label );
  773.     defuseObject maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "compass_waypoint_defend" + label );
  774.     defuseObject maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defuse" + label );
  775.     defuseObject maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_defend" + label );
  776.     defuseObject.label = label;
  777.     defuseObject.onBeginUse = ::onBeginUse;
  778.     defuseObject.onEndUse = ::onEndUse;
  779.     defuseObject.onUse = ::onUseDefuseObject;
  780.     defuseObject.useWeapon = "briefcase_bomb_defuse_mp";
  781.    
  782.     BombTimerWait();
  783.     setDvar( "ui_bomb_timer", 0 );
  784.    
  785.     destroyedObj.visuals[0] maps\mp\gametypes\_globallogic::stopTickingSound();
  786.    
  787.     if ( level.gameEnded || level.bombDefused )
  788.         return;
  789.    
  790.     level.bombExploded = true;
  791.    
  792.     explosionOrigin = level.sdBombModel.origin;
  793.     level.sdBombModel hide();
  794.    
  795.     if ( isdefined( player ) )
  796.         destroyedObj.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20, player );
  797.     else
  798.         destroyedObj.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20 );
  799.    
  800.     rot = randomfloat(360);
  801.     explosionEffect = spawnFx( level._effect["bombexplosion"], explosionOrigin + (0,0,50), (0,0,1), (cos(rot),sin(rot),0) );
  802.     triggerFx( explosionEffect );
  803.    
  804.     thread playSoundinSpace( "exp_suitcase_bomb_main", explosionOrigin );
  805.    
  806.     if ( isDefined( destroyedObj.exploderIndex ) )
  807.         exploder( destroyedObj.exploderIndex );
  808.    
  809.     for ( index = 0; index < level.bombZones.size; index++ )
  810.         level.bombZones[index] maps\mp\gametypes\_gameobjects::disableObject();
  811.     defuseObject maps\mp\gametypes\_gameobjects::disableObject();
  812.    
  813.     setGameEndTime( 0 );
  814.    
  815.     wait (3 * level.fps_multiplier );
  816.    
  817.     sd_endGame( game["attackers"], game["strings"]["target_destroyed"] );
  818. }
  819.  
  820. BombTimerWait()
  821. {
  822.     level endon("game_ended");
  823.     level endon("bomb_defused");
  824.     wait (level.bombTimer * level.fps_multiplier ) ;
  825. }
  826.  
  827. playSoundinSpace( alias, origin )
  828. {
  829.     org = spawn( "script_origin", origin );
  830.     org.origin = origin;
  831.     org playSound( alias  );
  832.     wait (10 * level.fps_multiplier );  // MP doesn't have "sounddone" notifies =(
  833.     org delete();
  834. }
  835.  
  836. bombDefused()
  837. {
  838.     level.tickingObject maps\mp\gametypes\_globallogic::stopTickingSound();
  839.     level.bombDefused = true;
  840.     setDvar( "ui_bomb_timer", 0 );
  841.    
  842.     level notify("bomb_defused");
  843.    
  844.     wait (1.5 * level.fps_multiplier );
  845.    
  846.     setGameEndTime( 0 );
  847.    
  848.     sd_endGame( game["defenders"], game["strings"]["bomb_defused"] );
  849. }

Paste-bin is for source code and general debugging text.

Login or Register to edit, delete and keep track of your pastes and more.

Raw Paste

Login or Register to edit or fork this paste. It's free.