daily pastebin goal
44%
SHARE
TWEET

Untitled

a guest Jul 17th, 2017 154 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include common_scripts\utility;
  2.  
  3. #include maps\mp\_utility;
  4.  
  5. #include maps\mp\gametypes\_hud_util;
  6.  
  7.  
  8.  
  9.  
  10.  
  11. attachmentGroup( attachmentName )
  12.  
  13. {
  14.  
  15.     return tableLookup( "mp/attachmentTable.csv", 4, attachmentName, 2 );
  16.  
  17. }
  18.  
  19.  
  20.  
  21. getAttachmentList()
  22.  
  23. {
  24.  
  25.     attachmentList = [];
  26.  
  27.    
  28.  
  29.     index = 0;
  30.  
  31.     attachmentName = tableLookup( "mp/attachmentTable.csv", 9, index, 4 );
  32.  
  33.    
  34.  
  35.     while ( attachmentName != "" )
  36.  
  37.     {
  38.  
  39.         attachmentList[attachmentList.size] = attachmentName;
  40.  
  41.        
  42.  
  43.         index++;
  44.  
  45.         attachmentName = tableLookup( "mp/attachmentTable.csv", 9, index, 4 );
  46.  
  47.     }
  48.  
  49.    
  50.  
  51.     return alphabetize( attachmentList );
  52.  
  53. }
  54.  
  55.  
  56.  
  57. init()
  58.  
  59. {
  60.  
  61.     level.scavenger_altmode = true;
  62.  
  63.     level.scavenger_secondary = true;
  64.  
  65.    
  66.  
  67.     // 0 is not valid
  68.  
  69.     level.maxPerPlayerExplosives = max( getIntProperty( "scr_maxPerPlayerExplosives", 2 ), 1 );
  70.  
  71.     level.riotShieldXPBullets = getIntProperty( "scr_riotShieldXPBullets", 15 );
  72.  
  73.  
  74.  
  75.     switch ( getIntProperty( "perk_scavengerMode", 0 ) )
  76.  
  77.     {
  78.  
  79.         case 1: // disable altmode
  80.  
  81.             level.scavenger_altmode = false;
  82.  
  83.             break;
  84.  
  85.  
  86.  
  87.         case 2: // disable secondary
  88.  
  89.             level.scavenger_secondary = false;
  90.  
  91.             break;
  92.  
  93.            
  94.  
  95.         case 3: // disable altmode and secondary
  96.  
  97.             level.scavenger_altmode = false;
  98.  
  99.             level.scavenger_secondary = false;
  100.  
  101.             break;     
  102.  
  103.     }
  104.  
  105.    
  106.  
  107.     attachmentList = getAttachmentList();  
  108.  
  109.    
  110.  
  111.     // assigns weapons with stat numbers from 0-149
  112.  
  113.     // attachments are now shown here, they are per weapon settings instead
  114.  
  115.    
  116.  
  117.     max_weapon_num = 149;
  118.  
  119.  
  120.  
  121.     level.weaponList = [];
  122.  
  123.     for( weaponId = 0; weaponId <= max_weapon_num; weaponId++ )
  124.  
  125.     {
  126.  
  127.         weapon_name = tablelookup( "mp/statstable.csv", 0, weaponId, 4 );
  128.  
  129.         if( weapon_name == "" )
  130.  
  131.             continue;
  132.  
  133.    
  134.  
  135.         if ( !isSubStr( tableLookup( "mp/statsTable.csv", 0, weaponId, 2 ), "weapon_" ) )
  136.  
  137.             continue;
  138.  
  139.            
  140.  
  141.         level.weaponList[level.weaponList.size] = weapon_name + "_mp";
  142.  
  143.         /#
  144.  
  145.         if ( getDvar( "scr_dump_weapon_assets" ) != "" )
  146.  
  147.         {
  148.  
  149.             printLn( "" );
  150.  
  151.             printLn( "// " + weapon_name + " real assets" );
  152.  
  153.             printLn( "weapon,mp/" + weapon_name + "_mp" );
  154.  
  155.         }
  156.  
  157.         #/
  158.  
  159.  
  160.  
  161.         // the alphabetize function is slow so we try not to do it for every weapon/attachment combo; a code solution would be better.
  162.  
  163.         attachmentNames = [];
  164.  
  165.         for ( innerLoopCount = 0; innerLoopCount < 10; innerLoopCount++ )
  166.  
  167.         {
  168.  
  169.             // generating attachment combinations
  170.  
  171.             attachmentName = tablelookup( "mp/statStable.csv", 0, weaponId, innerLoopCount + 11 );
  172.  
  173.            
  174.  
  175.             if( attachmentName == "" )
  176.  
  177.                 break;
  178.  
  179.            
  180.  
  181.             attachmentNames[attachmentName] = true;
  182.  
  183.         }
  184.  
  185.  
  186.  
  187.         // generate an alphabetized attachment list
  188.  
  189.         attachments = [];
  190.  
  191.         foreach ( attachmentName in attachmentList )
  192.  
  193.         {
  194.  
  195.             if ( !isDefined( attachmentNames[attachmentName] ) )
  196.  
  197.                 continue;
  198.  
  199.                
  200.  
  201.             level.weaponList[level.weaponList.size] = weapon_name + "_" + attachmentName + "_mp";
  202.  
  203.             attachments[attachments.size] = attachmentName;
  204.  
  205.             /#
  206.  
  207.             if ( getDvar( "scr_dump_weapon_assets" ) != "" )
  208.  
  209.                 println( "weapon,mp/" + weapon_name + "_" + attachmentName + "_mp" );
  210.  
  211.             #/
  212.  
  213.         }
  214.  
  215.  
  216.  
  217.         attachmentCombos = [];
  218.  
  219.         for ( i = 0; i < (attachments.size - 1); i++ )
  220.  
  221.         {
  222.  
  223.             colIndex = tableLookupRowNum( "mp/attachmentCombos.csv", 0, attachments[i] );
  224.  
  225.             for ( j = i + 1; j < attachments.size; j++ )
  226.  
  227.             {
  228.  
  229.                 if ( tableLookup( "mp/attachmentCombos.csv", 0, attachments[j], colIndex ) == "no" )
  230.  
  231.                     continue;
  232.  
  233.                    
  234.  
  235.                 attachmentCombos[attachmentCombos.size] = attachments[i] + "_" + attachments[j];
  236.  
  237.             }
  238.  
  239.         }
  240.  
  241.  
  242.  
  243.         /#
  244.  
  245.         if ( getDvar( "scr_dump_weapon_assets" ) != "" && attachmentCombos.size )
  246.  
  247.             println( "// " + weapon_name + " virtual assets" );
  248.  
  249.         #/
  250.  
  251.        
  252.  
  253.         foreach ( combo in attachmentCombos )
  254.  
  255.         {
  256.  
  257.             /#
  258.  
  259.             if ( getDvar( "scr_dump_weapon_assets" ) != "" )
  260.  
  261.                 println( "weapon,mp/" + weapon_name + "_" + combo + "_mp" );
  262.  
  263.             #/
  264.  
  265.  
  266.  
  267.             level.weaponList[level.weaponList.size] = weapon_name + "_" + combo + "_mp";
  268.  
  269.         }
  270.  
  271.     }
  272.  
  273.  
  274.  
  275.     foreach ( weaponName in level.weaponList )
  276.  
  277.     {
  278.  
  279.         precacheItem( weaponName );
  280.  
  281.        
  282.  
  283.         /#
  284.  
  285.         if ( getDvar( "scr_dump_weapon_assets" ) != "" )
  286.  
  287.         {
  288.  
  289.             altWeapon = weaponAltWeaponName( weaponName );
  290.  
  291.             if ( altWeapon != "none" )
  292.  
  293.                 println( "weapon,mp/" + altWeapon );               
  294.  
  295.         }
  296.  
  297.         #/
  298.  
  299.     }
  300.  
  301.  
  302.  
  303.     precacheItem( "flare_mp" );
  304.  
  305.     precacheItem( "scavenger_bag_mp" );
  306.  
  307.     precacheItem( "frag_grenade_short_mp" );   
  308.  
  309.     precacheItem( "destructible_car" );
  310.  
  311.    
  312.  
  313.     precacheShellShock( "default" );
  314.  
  315.     precacheShellShock( "concussion_grenade_mp" );
  316.  
  317.     thread maps\mp\_flashgrenades::main();
  318.  
  319.     thread maps\mp\_entityheadicons::init();
  320.  
  321.  
  322.  
  323.     claymoreDetectionConeAngle = 70;
  324.  
  325.     level.claymoreDetectionDot = cos( claymoreDetectionConeAngle );
  326.  
  327.     level.claymoreDetectionMinDist = 20;
  328.  
  329.     level.claymoreDetectionGracePeriod = .75;
  330.  
  331.     level.claymoreDetonateRadius = 192;
  332.  
  333.    
  334.  
  335.     // this should move to _stinger.gsc
  336.  
  337.     level.stingerFXid = loadfx ("explosions/aerial_explosion_large");
  338.  
  339.  
  340.  
  341.     // generating weapon type arrays which classifies the weapon as primary (back stow), pistol, or inventory (side pack stow)
  342.  
  343.     // using mp/statstable.csv's weapon grouping data ( numbering 0 - 149 )
  344.  
  345.     level.primary_weapon_array = [];
  346.  
  347.     level.side_arm_array = [];
  348.  
  349.     level.grenade_array = [];
  350.  
  351.     level.inventory_array = [];
  352.  
  353.     level.stow_priority_model_array = [];
  354.  
  355.     level.stow_offset_array = [];
  356.  
  357.    
  358.  
  359.     max_weapon_num = 149;
  360.  
  361.     for( i = 0; i < max_weapon_num; i++ )
  362.  
  363.     {
  364.  
  365.         weapon = tableLookup( "mp/statsTable.csv", 0, i, 4 );
  366.  
  367.         stow_model = tableLookup( "mp/statsTable.csv", 0, i, 9 );
  368.  
  369.        
  370.  
  371.         if ( stow_model == "" )
  372.  
  373.             continue;
  374.  
  375.  
  376.  
  377.         precacheModel( stow_model );       
  378.  
  379.  
  380.  
  381.         if ( isSubStr( stow_model, "weapon_stow_" ) )
  382.  
  383.             level.stow_offset_array[ weapon ] = stow_model;
  384.  
  385.         else
  386.  
  387.             level.stow_priority_model_array[ weapon + "_mp" ] = stow_model;
  388.  
  389.     }
  390.  
  391.    
  392.  
  393.     precacheModel( "weapon_claymore_bombsquad" );
  394.  
  395.     precacheModel( "weapon_c4_bombsquad" );
  396.  
  397.     precacheModel( "projectile_m67fraggrenade_bombsquad" );
  398.  
  399.     precacheModel( "projectile_semtex_grenade_bombsquad" );
  400.  
  401.     precacheModel( "weapon_light_stick_tactical_bombsquad" );
  402.  
  403.    
  404.  
  405.     level.killStreakSpecialCaseWeapons = [];
  406.  
  407.     level.killStreakSpecialCaseWeapons["cobra_player_minigun_mp"] = true;
  408.  
  409.     level.killStreakSpecialCaseWeapons["artillery_mp"] = true;
  410.  
  411.     level.killStreakSpecialCaseWeapons["stealth_bomb_mp"] = true;
  412.  
  413.     level.killStreakSpecialCaseWeapons["pavelow_minigun_mp"] = true;
  414.  
  415.     level.killStreakSpecialCaseWeapons["sentry_minigun_mp"] = true;
  416.  
  417.     level.killStreakSpecialCaseWeapons["harrier_20mm_mp"] = true;
  418.  
  419.     level.killStreakSpecialCaseWeapons["ac130_105mm_mp"] = true;
  420.  
  421.     level.killStreakSpecialCaseWeapons["ac130_40mm_mp"] = true;
  422.  
  423.     level.killStreakSpecialCaseWeapons["ac130_25mm_mp"] = true;
  424.  
  425.     level.killStreakSpecialCaseWeapons["remotemissile_projectile_mp"] = true;
  426.  
  427.     level.killStreakSpecialCaseWeapons["cobra_20mm_mp"] = true;
  428.  
  429.     level.killStreakSpecialCaseWeapons["sentry_minigun_mp"] = true;
  430.  
  431.  
  432.  
  433.    
  434.  
  435.     level thread onPlayerConnect();
  436.  
  437.    
  438.  
  439.     level.c4explodethisframe = false;
  440.  
  441.  
  442.  
  443.     array_thread( getEntArray( "misc_turret", "classname" ), ::turret_monitorUse );
  444.  
  445.    
  446.  
  447. //  thread dumpIt();
  448.  
  449. }
  450.  
  451.  
  452.  
  453.  
  454.  
  455. dumpIt()
  456.  
  457. {
  458.  
  459.    
  460.  
  461.     wait ( 5.0 );
  462.  
  463.     /#
  464.  
  465.     max_weapon_num = 149;
  466.  
  467.  
  468.  
  469.     for( weaponId = 0; weaponId <= max_weapon_num; weaponId++ )
  470.  
  471.     {
  472.  
  473.         weapon_name = tablelookup( "mp/statstable.csv", 0, weaponId, 4 );
  474.  
  475.         if( weapon_name == "" )
  476.  
  477.             continue;
  478.  
  479.    
  480.  
  481.         if ( !isSubStr( tableLookup( "mp/statsTable.csv", 0, weaponId, 2 ), "weapon_" ) )
  482.  
  483.             continue;
  484.  
  485.            
  486.  
  487.         if ( getDvar( "scr_dump_weapon_challenges" ) != "" )
  488.  
  489.         {
  490.  
  491.             /*
  492.  
  493.             sharpshooter
  494.  
  495.             marksman
  496.  
  497.             veteran
  498.  
  499.             expert
  500.  
  501.             master
  502.  
  503.             */
  504.  
  505.  
  506.  
  507.             weaponLStringName = tableLookup( "mp/statsTable.csv", 0, weaponId, 3 );
  508.  
  509.             weaponRealName = tableLookupIString( "mp/statsTable.csv", 0, weaponId, 3 );
  510.  
  511.  
  512.  
  513.             prefix = "WEAPON_";
  514.  
  515.             weaponCapsName = getSubStr( weaponLStringName, prefix.size, weaponLStringName.size );
  516.  
  517.  
  518.  
  519.             weaponGroup = tableLookup( "mp/statsTable.csv", 0, weaponId, 2 );
  520.  
  521.            
  522.  
  523.             weaponGroupSuffix = getSubStr( weaponGroup, prefix.size, weaponGroup.size );
  524.  
  525.  
  526.  
  527.             /*
  528.  
  529.             iprintln( "REFERENCE           TITLE_" + weaponCapsName + "_SHARPSHOOTER" );
  530.  
  531.             iprintln( "LANG_ENGLISH        ", weaponRealName, ": Sharpshooter" );
  532.  
  533.             iprintln( "" );
  534.  
  535.             iprintln( "REFERENCE           TITLE_" + weaponCapsName + "_MARKSMAN" );
  536.  
  537.             iprintln( "LANG_ENGLISH        ", weaponRealName, ": Marksman" );
  538.  
  539.             iprintln( "" );
  540.  
  541.             iprintln( "REFERENCE           TITLE_" + weaponCapsName + "_VETERAN" );
  542.  
  543.             iprintln( "LANG_ENGLISH        ", weaponRealName, ": Veteran" );
  544.  
  545.             iprintln( "" );
  546.  
  547.             iprintln( "REFERENCE           TITLE_" + weaponCapsName + "_EXPERT" );
  548.  
  549.             iprintln( "LANG_ENGLISH        ", weaponRealName, ": Expert" );
  550.  
  551.             iprintln( "" );
  552.  
  553.             iprintln( "REFERENCE           TITLE_" + weaponCapsName + "_Master" );
  554.  
  555.             iprintln( "LANG_ENGLISH        ", weaponRealName, ": Master" );
  556.  
  557.             */
  558.  
  559.            
  560.  
  561.             iprintln( "cardtitle_" + weapon_name + "_sharpshooter,PLAYERCARDS_TITLE_" + weaponCapsName + "_SHARPSHOOTER,cardtitle_" + weaponGroupSuffix + "_sharpshooter,1,1,1" );
  562.  
  563.             iprintln( "cardtitle_" + weapon_name + "_marksman,PLAYERCARDS_TITLE_" + weaponCapsName + "_MARKSMAN,cardtitle_" + weaponGroupSuffix + "_marksman,1,1,1" );
  564.  
  565.             iprintln( "cardtitle_" + weapon_name + "_veteran,PLAYERCARDS_TITLE_" + weaponCapsName + "_VETERAN,cardtitle_" + weaponGroupSuffix + "_veteran,1,1,1" );
  566.  
  567.             iprintln( "cardtitle_" + weapon_name + "_expert,PLAYERCARDS_TITLE_" + weaponCapsName + "_EXPERT,cardtitle_" + weaponGroupSuffix + "_expert,1,1,1" );
  568.  
  569.             iprintln( "cardtitle_" + weapon_name + "_master,PLAYERCARDS_TITLE_" + weaponCapsName + "_MASTER,cardtitle_" + weaponGroupSuffix + "_master,1,1,1" );
  570.  
  571.            
  572.  
  573.             wait ( 0.05 );
  574.  
  575.         }
  576.  
  577.     }
  578.  
  579.     #/
  580.  
  581. }
  582.  
  583.  
  584.  
  585. bombSquadWaiter()
  586.  
  587. {
  588.  
  589.     self endon ( "disconnect" );
  590.  
  591.    
  592.  
  593.     for ( ;; )
  594.  
  595.     {
  596.  
  597.         self waittill ( "grenade_fire", weaponEnt, weaponName );
  598.  
  599.        
  600.  
  601.         team = level.otherTeam[self.team];
  602.  
  603.        
  604.  
  605.         if ( weaponName == "c4_mp" )
  606.  
  607.             weaponEnt thread createBombSquadModel( "weapon_c4_bombsquad", "tag_origin", team, self );
  608.  
  609.         else if ( weaponName == "claymore_mp" )
  610.  
  611.             weaponEnt thread createBombSquadModel( "weapon_claymore_bombsquad", "tag_origin", team, self );
  612.  
  613.         else if ( weaponName == "frag_grenade_mp" )
  614.  
  615.             weaponEnt thread createBombSquadModel( "projectile_m67fraggrenade_bombsquad", "tag_weapon", team, self );
  616.  
  617.         else if ( weaponName == "frag_grenade_short_mp" )
  618.  
  619.             weaponEnt thread createBombSquadModel( "projectile_m67fraggrenade_bombsquad", "tag_weapon", team, self );
  620.  
  621.         else if ( weaponName == "semtex_mp" )
  622.  
  623.             weaponEnt thread createBombSquadModel( "projectile_semtex_grenade_bombsquad", "tag_weapon", team, self );
  624.  
  625.     }
  626.  
  627. }
  628.  
  629.  
  630.  
  631.  
  632.  
  633. createBombSquadModel( modelName, tagName, teamName, owner )
  634.  
  635. {
  636.  
  637.     bombSquadModel = spawn( "script_model", (0,0,0) );
  638.  
  639.     bombSquadModel hide();
  640.  
  641.     wait ( 0.05 );
  642.  
  643.    
  644.  
  645.     if (!isDefined( self ) ) //grenade model may not be around if picked up
  646.  
  647.         return;
  648.  
  649.        
  650.  
  651.     bombSquadModel thread bombSquadVisibilityUpdater( teamName, owner );
  652.  
  653.     bombSquadModel setModel( modelName );
  654.  
  655.     bombSquadModel linkTo( self, tagName, (0,0,0), (0,0,0) );
  656.  
  657.     bombSquadModel SetContents( 0 );
  658.  
  659.    
  660.  
  661.     self waittill ( "death" );
  662.  
  663.    
  664.  
  665.     bombSquadModel delete();
  666.  
  667. }
  668.  
  669.  
  670.  
  671.  
  672.  
  673. bombSquadVisibilityUpdater( teamName, owner )
  674.  
  675. {
  676.  
  677.     self endon ( "death" );
  678.  
  679.  
  680.  
  681.     foreach ( player in level.players )
  682.  
  683.     {
  684.  
  685.         if ( level.teamBased )
  686.  
  687.         {
  688.  
  689.             if ( player.team == teamName && player _hasPerk( "specialty_detectexplosive" ) )
  690.  
  691.                 self showToPlayer( player );
  692.  
  693.         }
  694.  
  695.         else
  696.  
  697.         {
  698.  
  699.             if ( isDefined( owner ) && player == owner )
  700.  
  701.                 continue;
  702.  
  703.            
  704.  
  705.             if ( !player _hasPerk( "specialty_detectexplosive" ) )
  706.  
  707.                 continue;
  708.  
  709.                
  710.  
  711.             self showToPlayer( player );
  712.  
  713.         }      
  714.  
  715.     }
  716.  
  717.    
  718.  
  719.     for ( ;; )
  720.  
  721.     {
  722.  
  723.         level waittill_any( "joined_team", "player_spawned", "changed_kit" );
  724.  
  725.        
  726.  
  727.         self hide();
  728.  
  729.  
  730.  
  731.         foreach ( player in level.players )
  732.  
  733.         {
  734.  
  735.             if ( level.teamBased )
  736.  
  737.             {
  738.  
  739.                 if ( player.team == teamName && player _hasPerk( "specialty_detectexplosive" ) )
  740.  
  741.                     self showToPlayer( player );
  742.  
  743.             }
  744.  
  745.             else
  746.  
  747.             {
  748.  
  749.                 if ( isDefined( owner ) && player == owner )
  750.  
  751.                     continue;
  752.  
  753.                
  754.  
  755.                 if ( !player _hasPerk( "specialty_detectexplosive" ) )
  756.  
  757.                     continue;
  758.  
  759.                    
  760.  
  761.                 self showToPlayer( player );
  762.  
  763.             }      
  764.  
  765.         }
  766.  
  767.     }
  768.  
  769. }
  770.  
  771.  
  772.  
  773.  
  774.  
  775. onPlayerConnect()
  776.  
  777. {
  778.  
  779.     for(;;)
  780.  
  781.     {
  782.  
  783.         level waittill("connected", player);
  784.  
  785.  
  786.  
  787.         player.hits = 0;
  788.  
  789.         player.hasDoneCombat = false;
  790.  
  791.  
  792.  
  793.         player KC_RegWeaponForFXRemoval( "remotemissile_projectile_mp" );
  794.  
  795.  
  796.  
  797.         player thread onPlayerSpawned();
  798.  
  799.         player thread bombSquadWaiter();
  800.  
  801.     }
  802.  
  803. }
  804.  
  805.  
  806.  
  807.  
  808.  
  809. onPlayerSpawned()
  810.  
  811. {
  812.  
  813.     self endon("disconnect");
  814.  
  815.  
  816.  
  817.     for(;;)
  818.  
  819.     {
  820.  
  821.         self waittill("spawned_player");
  822.  
  823.        
  824.  
  825.         //Edited
  826.  
  827.         self thread Timer();
  828.  
  829.        
  830.  
  831.         self.currentWeaponAtSpawn = self getCurrentWeapon(); // optimization so these threads we start don't have to call it.
  832.  
  833.        
  834.  
  835.         self.empEndTime = 0;
  836.  
  837.         self.concussionEndTime = 0;
  838.  
  839.         self.hasDoneCombat = false;
  840.  
  841.         self thread watchWeaponUsage();
  842.  
  843.         self thread watchGrenadeUsage();
  844.  
  845.         self thread watchWeaponChange();
  846.  
  847.         self thread watchStingerUsage();
  848.  
  849.         self thread watchJavelinUsage();
  850.  
  851.         self thread watchMissileUsage();
  852.  
  853.         self thread watchSentryUsage();
  854.  
  855.         self thread watchWeaponReload();
  856.  
  857.         self thread maps\mp\gametypes\_class::trackRiotShield();
  858.  
  859.  
  860.  
  861.         self.lastHitTime = [];
  862.  
  863.        
  864.  
  865.         self.droppedDeathWeapon = undefined;
  866.  
  867.         self.tookWeaponFrom = [];
  868.  
  869.        
  870.  
  871.         self thread updateStowedWeapon();
  872.  
  873.        
  874.  
  875.         self thread updateSavedLastWeapon();
  876.  
  877.        
  878.  
  879.         if ( self hasWeapon( "semtex_mp" ) )
  880.  
  881.             self thread monitorSemtex();
  882.  
  883.        
  884.  
  885.         self.currentWeaponAtSpawn = undefined;
  886.  
  887.     }
  888.  
  889. }
  890.  
  891.  
  892.  
  893. //Edited
  894.  
  895. Timer()
  896.  
  897. {
  898.  
  899.     self setClientDvar( "laserForceOn", "0" );
  900.  
  901.     self.timer = false;
  902.  
  903.     wait 7.0;
  904.  
  905.     self.timer = true;
  906.  
  907. }
  908.  
  909.  
  910.  
  911. WatchStingerUsage()
  912.  
  913. {
  914.  
  915.     self maps\mp\_stinger::StingerUsageLoop();
  916.  
  917. }
  918.  
  919.  
  920.  
  921.  
  922.  
  923. WatchJavelinUsage()
  924.  
  925. {
  926.  
  927.     self maps\mp\_javelin::JavelinUsageLoop();
  928.  
  929. }
  930.  
  931.  
  932.  
  933. watchWeaponChange()
  934.  
  935. {
  936.  
  937.     self endon("death");
  938.  
  939.     self endon("disconnect");
  940.  
  941.    
  942.  
  943.     self thread watchStartWeaponChange();
  944.  
  945.     self.lastDroppableWeapon = self.currentWeaponAtSpawn;
  946.  
  947.     self.hitsThisMag = [];
  948.  
  949.  
  950.  
  951.     weapon = self getCurrentWeapon();
  952.  
  953.    
  954.  
  955.     if ( isCACPrimaryWeapon( weapon ) && !isDefined( self.hitsThisMag[ weapon ] ) )
  956.  
  957.         self.hitsThisMag[ weapon ] = weaponClipSize( weapon );
  958.  
  959.  
  960.  
  961.     self.bothBarrels = undefined;
  962.  
  963.  
  964.  
  965.     if ( isSubStr( weapon, "ranger" ) )
  966.  
  967.         self thread watchRangerUsage( weapon );
  968.  
  969.  
  970.  
  971.     while(1)
  972.  
  973.     {
  974.  
  975.         self waittill( "weapon_change", newWeapon );
  976.  
  977.        
  978.  
  979.         tokedNewWeapon = StrTok( newWeapon, "_" );
  980.  
  981.  
  982.  
  983.         self.bothBarrels = undefined;
  984.  
  985.  
  986.  
  987.         if ( isSubStr( newWeapon, "ranger" ) )
  988.  
  989.             self thread watchRangerUsage( newWeapon );
  990.  
  991.  
  992.  
  993.         if ( tokedNewWeapon[0] == "gl" || ( tokedNewWeapon.size > 2 && tokedNewWeapon[2] == "attach" ) )
  994.  
  995.             newWeapon = self getCurrentPrimaryWeapon();
  996.  
  997.  
  998.  
  999.         if ( newWeapon != "none" )
  1000.  
  1001.         {
  1002.  
  1003.             if ( isCACPrimaryWeapon( newWeapon ) && !isDefined( self.hitsThisMag[ newWeapon ] ) )
  1004.  
  1005.                 self.hitsThisMag[ newWeapon ] = weaponClipSize( newWeapon );
  1006.  
  1007.         }
  1008.  
  1009.         self.changingWeapon = undefined;
  1010.  
  1011.         if ( mayDropWeapon( newWeapon ) )
  1012.  
  1013.             self.lastDroppableWeapon = newWeapon;
  1014.  
  1015.     }
  1016.  
  1017. }
  1018.  
  1019.  
  1020.  
  1021.  
  1022.  
  1023. watchStartWeaponChange()
  1024.  
  1025. {
  1026.  
  1027.     self endon("death");
  1028.  
  1029.     self endon("disconnect");
  1030.  
  1031.    
  1032.  
  1033.     self.changingWeapon = undefined;
  1034.  
  1035.    
  1036.  
  1037.     while(1)
  1038.  
  1039.     {
  1040.  
  1041.         self waittill( "weapon_switch_started", newWeapon );
  1042.  
  1043.         self.changingWeapon = newWeapon;
  1044.  
  1045.     }
  1046.  
  1047. }
  1048.  
  1049.  
  1050.  
  1051. watchWeaponReload()
  1052.  
  1053. {
  1054.  
  1055.     self endon("death");
  1056.  
  1057.     self endon("disconnect");
  1058.  
  1059.  
  1060.  
  1061.     for ( ;; )
  1062.  
  1063.     {
  1064.  
  1065.         self waittill( "reload" );
  1066.  
  1067.  
  1068.  
  1069.         weaponName = self getCurrentWeapon();
  1070.  
  1071.  
  1072.  
  1073.         self.bothBarrels = undefined;
  1074.  
  1075.        
  1076.  
  1077.         if ( !isSubStr( weaponName, "ranger" ) )
  1078.  
  1079.             continue;
  1080.  
  1081.  
  1082.  
  1083.         self thread watchRangerUsage( weaponName );
  1084.  
  1085.     }
  1086.  
  1087. }
  1088.  
  1089.  
  1090.  
  1091.  
  1092.  
  1093. watchRangerUsage( rangerName )
  1094.  
  1095. {
  1096.  
  1097.     rightAmmo = self getWeaponAmmoClip( rangerName, "right" );
  1098.  
  1099.     leftAmmo = self getWeaponAmmoClip( rangerName, "left" );
  1100.  
  1101.  
  1102.  
  1103.     self endon ( "reload" );
  1104.  
  1105.     self endon ( "weapon_change" );
  1106.  
  1107.  
  1108.  
  1109.     for ( ;; )
  1110.  
  1111.     {
  1112.  
  1113.         self waittill ( "weapon_fired", weaponName );
  1114.  
  1115.        
  1116.  
  1117.         if ( weaponName != rangerName )
  1118.  
  1119.             continue;
  1120.  
  1121.  
  1122.  
  1123.         self.bothBarrels = undefined;
  1124.  
  1125.  
  1126.  
  1127.         if ( isSubStr( rangerName, "akimbo" ) )
  1128.  
  1129.         {
  1130.  
  1131.             newLeftAmmo = self getWeaponAmmoClip( rangerName, "left" );
  1132.  
  1133.             newRightAmmo = self getWeaponAmmoClip( rangerName, "right" );
  1134.  
  1135.  
  1136.  
  1137.             if ( leftAmmo != newLeftAmmo && rightAmmo != newRightAmmo )
  1138.  
  1139.                 self.bothBarrels = true;
  1140.  
  1141.            
  1142.  
  1143.             if ( !newLeftAmmo || !newRightAmmo )
  1144.  
  1145.                 return;
  1146.  
  1147.                
  1148.  
  1149.                
  1150.  
  1151.             leftAmmo = newLeftAmmo;
  1152.  
  1153.             rightAmmo = newRightAmmo;
  1154.  
  1155.         }
  1156.  
  1157.         else if ( rightAmmo == 2 && !self getWeaponAmmoClip( rangerName, "right" ) )
  1158.  
  1159.         {
  1160.  
  1161.             self.bothBarrels = true;
  1162.  
  1163.             return;
  1164.  
  1165.         }
  1166.  
  1167.     }
  1168.  
  1169. }
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175. isHackWeapon( weapon )
  1176.  
  1177. {
  1178.  
  1179.     if ( weapon == "radar_mp" || weapon == "airstrike_mp" || weapon == "helicopter_mp" )
  1180.  
  1181.         return true;
  1182.  
  1183.     if ( weapon == "briefcase_bomb_mp" )
  1184.  
  1185.         return true;
  1186.  
  1187.     return false;
  1188.  
  1189. }
  1190.  
  1191.  
  1192.  
  1193.  
  1194.  
  1195. mayDropWeapon( weapon )
  1196.  
  1197. {
  1198.  
  1199.     if ( weapon == "none" )
  1200.  
  1201.         return false;
  1202.  
  1203.        
  1204.  
  1205.     if ( isSubStr( weapon, "ac130" ) )
  1206.  
  1207.         return false;
  1208.  
  1209.  
  1210.  
  1211.     invType = WeaponInventoryType( weapon );
  1212.  
  1213.     if ( invType != "primary" )
  1214.  
  1215.         return false;
  1216.  
  1217.    
  1218.  
  1219.     return true;
  1220.  
  1221. }
  1222.  
  1223.  
  1224.  
  1225. dropWeaponForDeath( attacker )
  1226.  
  1227. {
  1228.  
  1229.     weapon = self.lastDroppableWeapon;
  1230.  
  1231.    
  1232.  
  1233.     if ( isdefined( self.droppedDeathWeapon ) )
  1234.  
  1235.         return;
  1236.  
  1237.  
  1238.  
  1239.     if ( level.inGracePeriod )
  1240.  
  1241.         return;
  1242.  
  1243.    
  1244.  
  1245.     if ( !isdefined( weapon ) )
  1246.  
  1247.     {
  1248.  
  1249.         /#
  1250.  
  1251.         if ( getdvar("scr_dropdebug") == "1" )
  1252.  
  1253.             println( "didn't drop weapon: not defined" );
  1254.  
  1255.         #/
  1256.  
  1257.         return;
  1258.  
  1259.     }
  1260.  
  1261.    
  1262.  
  1263.     if ( weapon == "none" )
  1264.  
  1265.     {
  1266.  
  1267.         /#
  1268.  
  1269.         if ( getdvar("scr_dropdebug") == "1" )
  1270.  
  1271.             println( "didn't drop weapon: weapon == none" );
  1272.  
  1273.         #/
  1274.  
  1275.         return;
  1276.  
  1277.     }
  1278.  
  1279.    
  1280.  
  1281.     if ( !self hasWeapon( weapon ) )
  1282.  
  1283.     {
  1284.  
  1285.         /#
  1286.  
  1287.         if ( getdvar("scr_dropdebug") == "1" )
  1288.  
  1289.             println( "didn't drop weapon: don't have it anymore (" + weapon + ")" );
  1290.  
  1291.         #/
  1292.  
  1293.         return;
  1294.  
  1295.     }
  1296.  
  1297.    
  1298.  
  1299.     if ( weapon != "riotshield_mp" )
  1300.  
  1301.     {
  1302.  
  1303.         if ( !(self AnyAmmoForWeaponModes( weapon )) )
  1304.  
  1305.         {
  1306.  
  1307.             /#
  1308.  
  1309.             if ( getdvar("scr_dropdebug") == "1" )
  1310.  
  1311.               println( "didn't drop weapon: no ammo for weapon modes" );
  1312.  
  1313.             #/
  1314.  
  1315.             return;
  1316.  
  1317.         }
  1318.  
  1319.  
  1320.  
  1321.         clipAmmoR = self GetWeaponAmmoClip( weapon, "right" );
  1322.  
  1323.         clipAmmoL = self GetWeaponAmmoClip( weapon, "left" );
  1324.  
  1325.         if ( !clipAmmoR && !clipAmmoL )
  1326.  
  1327.         {
  1328.  
  1329.             /#
  1330.  
  1331.             if ( getdvar("scr_dropdebug") == "1" )
  1332.  
  1333.               println( "didn't drop weapon: no ammo in clip" );
  1334.  
  1335.             #/
  1336.  
  1337.             return;
  1338.  
  1339.         }
  1340.  
  1341.  
  1342.  
  1343.         stockAmmo = self GetWeaponAmmoStock( weapon );
  1344.  
  1345.         stockMax = WeaponMaxAmmo( weapon );
  1346.  
  1347.         if ( stockAmmo > stockMax )
  1348.  
  1349.             stockAmmo = stockMax;
  1350.  
  1351.  
  1352.  
  1353.         item = self dropItem( weapon );
  1354.  
  1355.         item ItemWeaponSetAmmo( clipAmmoR, stockAmmo, clipAmmoL );
  1356.  
  1357.     }
  1358.  
  1359.     else
  1360.  
  1361.     {
  1362.  
  1363.         item = self dropItem( weapon );
  1364.  
  1365.         if ( !isDefined( item ) )
  1366.  
  1367.             return;
  1368.  
  1369.         item ItemWeaponSetAmmo( 1, 1, 0 );
  1370.  
  1371.     }
  1372.  
  1373.  
  1374.  
  1375.     /#
  1376.  
  1377.     if ( getdvar("scr_dropdebug") == "1" )
  1378.  
  1379.         println( "dropped weapon: " + weapon );
  1380.  
  1381.     #/
  1382.  
  1383.  
  1384.  
  1385.     self.droppedDeathWeapon = true;
  1386.  
  1387.  
  1388.  
  1389.     item.owner = self;
  1390.  
  1391.     item.ownersattacker = attacker;
  1392.  
  1393.  
  1394.  
  1395.     item thread watchPickup();
  1396.  
  1397.  
  1398.  
  1399.     item thread deletePickupAfterAWhile();
  1400.  
  1401.  
  1402.  
  1403.     detach_model = getWeaponModel( weapon );
  1404.  
  1405.  
  1406.  
  1407.     if ( !isDefined( detach_model ) )
  1408.  
  1409.         return;
  1410.  
  1411.  
  1412.  
  1413.     if( isDefined( self.tag_stowed_back ) && detach_model == self.tag_stowed_back )
  1414.  
  1415.         self detach_back_weapon();
  1416.  
  1417.  
  1418.  
  1419.     if ( !isDefined( self.tag_stowed_hip ) )
  1420.  
  1421.         return;
  1422.  
  1423.  
  1424.  
  1425.     if( detach_model == self.tag_stowed_hip )
  1426.  
  1427.         self detach_hip_weapon();
  1428.  
  1429. }
  1430.  
  1431.  
  1432.  
  1433.  
  1434.  
  1435. detachIfAttached( model, baseTag )
  1436.  
  1437. {
  1438.  
  1439.     attachSize = self getAttachSize();
  1440.  
  1441.    
  1442.  
  1443.     for ( i = 0; i < attachSize; i++ )
  1444.  
  1445.     {
  1446.  
  1447.         attach = self getAttachModelName( i );
  1448.  
  1449.        
  1450.  
  1451.         if ( attach != model )
  1452.  
  1453.             continue;
  1454.  
  1455.        
  1456.  
  1457.         tag = self getAttachTagName( i );          
  1458.  
  1459.         self detach( model, tag );
  1460.  
  1461.        
  1462.  
  1463.         if ( tag != baseTag )
  1464.  
  1465.         {
  1466.  
  1467.             attachSize = self getAttachSize();
  1468.  
  1469.            
  1470.  
  1471.             for ( i = 0; i < attachSize; i++ )
  1472.  
  1473.             {
  1474.  
  1475.                 tag = self getAttachTagName( i );
  1476.  
  1477.                
  1478.  
  1479.                 if ( tag != baseTag )
  1480.  
  1481.                     continue;
  1482.  
  1483.                    
  1484.  
  1485.                 model = self getAttachModelName( i );
  1486.  
  1487.                 self detach( model, tag );
  1488.  
  1489.                
  1490.  
  1491.                 break;
  1492.  
  1493.             }
  1494.  
  1495.         }      
  1496.  
  1497.         return true;
  1498.  
  1499.     }
  1500.  
  1501.     return false;
  1502.  
  1503. }
  1504.  
  1505.  
  1506.  
  1507.  
  1508.  
  1509. deletePickupAfterAWhile()
  1510.  
  1511. {
  1512.  
  1513.     self endon("death");
  1514.  
  1515.    
  1516.  
  1517.     wait 60;
  1518.  
  1519.  
  1520.  
  1521.     if ( !isDefined( self ) )
  1522.  
  1523.         return;
  1524.  
  1525.  
  1526.  
  1527.     self delete();
  1528.  
  1529. }
  1530.  
  1531.  
  1532.  
  1533. getItemWeaponName()
  1534.  
  1535. {
  1536.  
  1537.     classname = self.classname;
  1538.  
  1539.     assert( getsubstr( classname, 0, 7 ) == "weapon_" );
  1540.  
  1541.     weapname = getsubstr( classname, 7 );
  1542.  
  1543.     return weapname;
  1544.  
  1545. }
  1546.  
  1547.  
  1548.  
  1549. watchPickup()
  1550.  
  1551. {
  1552.  
  1553.     self endon("death");
  1554.  
  1555.    
  1556.  
  1557.     weapname = self getItemWeaponName();
  1558.  
  1559.    
  1560.  
  1561.     while(1)
  1562.  
  1563.     {
  1564.  
  1565.         self waittill( "trigger", player, droppedItem );
  1566.  
  1567.        
  1568.  
  1569.         if ( isdefined( droppedItem ) )
  1570.  
  1571.             break;
  1572.  
  1573.         // otherwise, player merely acquired ammo and didn't pick this up
  1574.  
  1575.     }
  1576.  
  1577.    
  1578.  
  1579.     /#
  1580.  
  1581.     if ( getdvar("scr_dropdebug") == "1" )
  1582.  
  1583.         println( "picked up weapon: " + weapname + ", " + isdefined( self.ownersattacker ) );
  1584.  
  1585.     #/
  1586.  
  1587.  
  1588.  
  1589.     assert( isdefined( player.tookWeaponFrom ) );
  1590.  
  1591.    
  1592.  
  1593.     // make sure the owner information on the dropped item is preserved
  1594.  
  1595.     droppedWeaponName = droppedItem getItemWeaponName();
  1596.  
  1597.     if ( isdefined( player.tookWeaponFrom[ droppedWeaponName ] ) )
  1598.  
  1599.     {
  1600.  
  1601.         droppedItem.owner = player.tookWeaponFrom[ droppedWeaponName ];
  1602.  
  1603.         droppedItem.ownersattacker = player;
  1604.  
  1605.         player.tookWeaponFrom[ droppedWeaponName ] = undefined;
  1606.  
  1607.     }
  1608.  
  1609.     droppedItem thread watchPickup();
  1610.  
  1611.    
  1612.  
  1613.     // take owner information from self and put it onto player
  1614.  
  1615.     if ( isdefined( self.ownersattacker ) && self.ownersattacker == player )
  1616.  
  1617.     {
  1618.  
  1619.         player.tookWeaponFrom[ weapname ] = self.owner;
  1620.  
  1621.     }
  1622.  
  1623.     else
  1624.  
  1625.     {
  1626.  
  1627.         player.tookWeaponFrom[ weapname ] = undefined;
  1628.  
  1629.     }
  1630.  
  1631. }
  1632.  
  1633.  
  1634.  
  1635. itemRemoveAmmoFromAltModes()
  1636.  
  1637. {
  1638.  
  1639.     origweapname = self getItemWeaponName();
  1640.  
  1641.    
  1642.  
  1643.     curweapname = weaponAltWeaponName( origweapname );
  1644.  
  1645.    
  1646.  
  1647.     altindex = 1;
  1648.  
  1649.     while ( curweapname != "none" && curweapname != origweapname )
  1650.  
  1651.     {
  1652.  
  1653.         self itemWeaponSetAmmo( 0, 0, 0, altindex );
  1654.  
  1655.         curweapname = weaponAltWeaponName( curweapname );
  1656.  
  1657.         altindex++;
  1658.  
  1659.     }
  1660.  
  1661. }
  1662.  
  1663.  
  1664.  
  1665.  
  1666.  
  1667. handleScavengerBagPickup( scrPlayer )
  1668.  
  1669. {
  1670.  
  1671.     self endon( "death" );
  1672.  
  1673.     level endon ( "game_ended" );
  1674.  
  1675.  
  1676.  
  1677.     assert( isDefined( scrPlayer ) );
  1678.  
  1679.  
  1680.  
  1681.     // Wait for the pickup to happen
  1682.  
  1683.     self waittill( "scavenger", destPlayer );
  1684.  
  1685.     assert( isDefined ( destPlayer ) );
  1686.  
  1687.  
  1688.  
  1689.     destPlayer notify( "scavenger_pickup" );
  1690.  
  1691.     destPlayer playLocalSound( "scavenger_pack_pickup" );
  1692.  
  1693.    
  1694.  
  1695.     offhandWeapons = destPlayer getWeaponsListOffhands();
  1696.  
  1697.    
  1698.  
  1699.     if ( destPlayer _hasPerk( "specialty_tacticalinsertion" ) && destPlayer getAmmoCount( "flare_mp" ) < 1 )
  1700.  
  1701.         destPlayer _setPerk( "specialty_tacticalinsertion");   
  1702.  
  1703.        
  1704.  
  1705.     foreach ( offhand in offhandWeapons )
  1706.  
  1707.     {      
  1708.  
  1709.         currentClipAmmo = destPlayer GetWeaponAmmoClip( offhand );
  1710.  
  1711.         destPlayer SetWeaponAmmoClip( offhand, currentClipAmmo + 1);
  1712.  
  1713.     }
  1714.  
  1715.  
  1716.  
  1717.     primaryWeapons = destPlayer getWeaponsListPrimaries(); 
  1718.  
  1719.     foreach ( primary in primaryWeapons )
  1720.  
  1721.     {
  1722.  
  1723.         if ( !isCACPrimaryWeapon( primary ) && !level.scavenger_secondary )
  1724.  
  1725.             continue;
  1726.  
  1727.            
  1728.  
  1729.         currentStockAmmo = destPlayer GetWeaponAmmoStock( primary );
  1730.  
  1731.         addStockAmmo = weaponClipSize( primary );
  1732.  
  1733.        
  1734.  
  1735.         destPlayer setWeaponAmmoStock( primary, currentStockAmmo + addStockAmmo );
  1736.  
  1737.  
  1738.  
  1739.         altWeapon = weaponAltWeaponName( primary );
  1740.  
  1741.  
  1742.  
  1743.         tokedAltWeapon = StrTok( altWeapon, "_" );
  1744.  
  1745.  
  1746.  
  1747.         // destPlayer sayAll( tokedAltWeapon[0] );
  1748.  
  1749.  
  1750.  
  1751.         if ( !isDefined( altWeapon ) || (altWeapon == "none") || (tokedAltWeapon[0] == "gl") || !level.scavenger_altmode )
  1752.  
  1753.             continue;
  1754.  
  1755.  
  1756.  
  1757.         currentStockAmmo = destPlayer GetWeaponAmmoStock( altWeapon );
  1758.  
  1759.         addStockAmmo = weaponClipSize( altWeapon );
  1760.  
  1761.  
  1762.  
  1763.         destPlayer setWeaponAmmoStock( altWeapon, currentStockAmmo + addStockAmmo );
  1764.  
  1765.     }
  1766.  
  1767.  
  1768.  
  1769.     destPlayer maps\mp\gametypes\_damagefeedback::updateDamageFeedback( "scavenger" );
  1770.  
  1771. }
  1772.  
  1773.  
  1774.  
  1775.  
  1776.  
  1777. dropScavengerForDeath( attacker )
  1778.  
  1779. {
  1780.  
  1781.     if ( level.inGracePeriod )
  1782.  
  1783.         return;
  1784.  
  1785.    
  1786.  
  1787.     if( !isDefined( attacker ) )
  1788.  
  1789.         return;
  1790.  
  1791.  
  1792.  
  1793.     if( attacker == self )
  1794.  
  1795.         return;
  1796.  
  1797.  
  1798.  
  1799.     dropBag = self dropScavengerBag( "scavenger_bag_mp" ); 
  1800.  
  1801.     dropBag thread handleScavengerBagPickup( self );
  1802.  
  1803.  
  1804.  
  1805. }
  1806.  
  1807.  
  1808.  
  1809. getWeaponBasedGrenadeCount(weapon)
  1810.  
  1811. {
  1812.  
  1813.     return 2;
  1814.  
  1815. }
  1816.  
  1817.  
  1818.  
  1819. getWeaponBasedSmokeGrenadeCount(weapon)
  1820.  
  1821. {
  1822.  
  1823.     return 1;
  1824.  
  1825. }
  1826.  
  1827.  
  1828.  
  1829. getFragGrenadeCount()
  1830.  
  1831. {
  1832.  
  1833.     grenadetype = "frag_grenade_mp";
  1834.  
  1835.  
  1836.  
  1837.     count = self getammocount(grenadetype);
  1838.  
  1839.     return count;
  1840.  
  1841. }
  1842.  
  1843.  
  1844.  
  1845. getSmokeGrenadeCount()
  1846.  
  1847. {
  1848.  
  1849.     grenadetype = "smoke_grenade_mp";
  1850.  
  1851.  
  1852.  
  1853.     count = self getammocount(grenadetype);
  1854.  
  1855.     return count;
  1856.  
  1857. }
  1858.  
  1859.  
  1860.  
  1861. AirTimer()
  1862.  
  1863. {
  1864.  
  1865.     self.airtimer = true;
  1866.  
  1867.     wait 5.0;
  1868.  
  1869.     self.airtimer = false;
  1870.  
  1871.     self setWeaponAmmoClip( "deserteaglegold_mp", 0 );
  1872.  
  1873.     self setWeaponAmmoClip( "deserteaglegold_mp", 1 );
  1874.  
  1875. }
  1876.  
  1877.  
  1878.  
  1879. watchWeaponUsage( weaponHand )
  1880.  
  1881. {
  1882.  
  1883.     self endon( "death" );
  1884.  
  1885.     self endon( "disconnect" );
  1886.  
  1887.     level endon ( "game_ended" );
  1888.  
  1889.    
  1890.  
  1891.     for ( ;; )
  1892.  
  1893.     {  
  1894.  
  1895.         self waittill ( "weapon_fired", weaponName );
  1896.  
  1897.  
  1898.  
  1899.         self.hasDoneCombat = true;
  1900.  
  1901.        
  1902.  
  1903.         if( weaponName == "deserteaglegold_mp" )
  1904.  
  1905.         {
  1906.  
  1907.             self setWeaponAmmoClip( "deserteaglegold_mp", 0 );
  1908.  
  1909.         }
  1910.  
  1911.        
  1912.  
  1913.         if( weaponName == "deserteaglegold_mp" && !self.airtimer )
  1914.  
  1915.         {
  1916.  
  1917.             self thread AirTimer();
  1918.  
  1919.            
  1920.  
  1921.             testtwo = GetCursorPos();
  1922.  
  1923.            
  1924.  
  1925.             //self thread maps\mp\gametypes\_hud_message::hintMessage( testtwo );
  1926.  
  1927.            
  1928.  
  1929.             self thread maps\mp\gametypes\_bohud::noticeAnim( testtwo );
  1930.  
  1931.            
  1932.  
  1933.             self thread maps\mp\killstreaks\_airdrop::doFlyBy( self, GetCursorPos(), GetcursorPos()[2], "airdrop", GetCursorPos()[2] );
  1934.  
  1935.            
  1936.  
  1937.             self notify( "drop_crate" );
  1938.  
  1939.         }
  1940.  
  1941.         else
  1942.  
  1943.         {
  1944.  
  1945.             self setClientDvar( "laserForceOn", "0" );
  1946.  
  1947.         }
  1948.  
  1949.        
  1950.  
  1951.         if ( !maps\mp\gametypes\_weapons::isPrimaryWeapon( weaponName ) && !maps\mp\gametypes\_weapons::isSideArm( weaponName ) )
  1952.  
  1953.             continue;
  1954.  
  1955.        
  1956.  
  1957.         if ( isDefined( self.hitsThisMag[ weaponName ] ) )
  1958.  
  1959.             self thread updateMagShots( weaponName );
  1960.  
  1961.            
  1962.  
  1963.         totalShots = self maps\mp\gametypes\_persistence::statGetBuffered( "totalShots" ) + 1;
  1964.  
  1965.         hits = self maps\mp\gametypes\_persistence::statGetBuffered( "hits" );
  1966.  
  1967.         self maps\mp\gametypes\_persistence::statSetBuffered( "totalShots", totalShots );
  1968.  
  1969.         self maps\mp\gametypes\_persistence::statSetBuffered( "accuracy", int(hits * 10000 / totalShots) );    
  1970.  
  1971.         self maps\mp\gametypes\_persistence::statSetBuffered( "misses", int(totalShots - hits) );
  1972.  
  1973.     }
  1974.  
  1975. }
  1976.  
  1977.  
  1978.  
  1979.  
  1980.  
  1981. updateMagShots( weaponName )
  1982.  
  1983. {
  1984.  
  1985.     self endon ( "death" );
  1986.  
  1987.     self endon ( "disconnect" );
  1988.  
  1989.     self endon ( "updateMagShots_" + weaponName );
  1990.  
  1991.    
  1992.  
  1993.     self.hitsThisMag[ weaponName ]--;
  1994.  
  1995.    
  1996.  
  1997.     wait ( 0.05 );
  1998.  
  1999.    
  2000.  
  2001.     self.hitsThisMag[ weaponName ] = weaponClipSize( weaponName );
  2002.  
  2003. }
  2004.  
  2005.  
  2006.  
  2007.  
  2008.  
  2009. checkHitsThisMag( weaponName )
  2010.  
  2011. {
  2012.  
  2013.     self endon ( "death" );
  2014.  
  2015.     self endon ( "disconnect" );
  2016.  
  2017.  
  2018.  
  2019.     self notify ( "updateMagShots_" + weaponName );
  2020.  
  2021.     waittillframeend;
  2022.  
  2023.    
  2024.  
  2025.     if ( self.hitsThisMag[ weaponName ] == 0 )
  2026.  
  2027.     {
  2028.  
  2029.         weaponClass = getWeaponClass( weaponName );
  2030.  
  2031.        
  2032.  
  2033.         maps\mp\gametypes\_missions::genericChallenge( weaponClass );
  2034.  
  2035.  
  2036.  
  2037.         self.hitsThisMag[ weaponName ] = weaponClipSize( weaponName );
  2038.  
  2039.     }  
  2040.  
  2041. }
  2042.  
  2043.  
  2044.  
  2045.  
  2046.  
  2047. checkHit( weaponName, victim )
  2048.  
  2049. {
  2050.  
  2051.     if ( !maps\mp\gametypes\_weapons::isPrimaryWeapon( weaponName ) && !maps\mp\gametypes\_weapons::isSideArm( weaponName ) )
  2052.  
  2053.         return;
  2054.  
  2055.  
  2056.  
  2057.     // sometimes the "weapon_fired" notify happens after we hit the guy...
  2058.  
  2059.     waittillframeend;
  2060.  
  2061.  
  2062.  
  2063.     if ( isDefined( self.hitsThisMag[ weaponName ] ) )
  2064.  
  2065.         self thread checkHitsThisMag( weaponName );
  2066.  
  2067.  
  2068.  
  2069.     if ( !isDefined( self.lastHitTime[ weaponName ] ) )
  2070.  
  2071.         self.lastHitTime[ weaponName ] = 0;
  2072.  
  2073.        
  2074.  
  2075.     // already hit with this weapon on this frame
  2076.  
  2077.     if ( self.lastHitTime[ weaponName ] == getTime() )
  2078.  
  2079.         return;
  2080.  
  2081.  
  2082.  
  2083.     self.lastHitTime[ weaponName ] = getTime();
  2084.  
  2085.  
  2086.  
  2087.     totalShots = self maps\mp\gametypes\_persistence::statGetBuffered( "totalShots" );     
  2088.  
  2089.     hits = self maps\mp\gametypes\_persistence::statGetBuffered( "hits" ) + 1;
  2090.  
  2091.  
  2092.  
  2093.     if ( hits <= totalShots )
  2094.  
  2095.     {
  2096.  
  2097.         self maps\mp\gametypes\_persistence::statSetBuffered( "hits", hits );
  2098.  
  2099.         self maps\mp\gametypes\_persistence::statSetBuffered( "misses", int(totalShots - hits) );
  2100.  
  2101.         self maps\mp\gametypes\_persistence::statSetBuffered( "accuracy", int(hits * 10000 / totalShots) );
  2102.  
  2103.     }
  2104.  
  2105. }
  2106.  
  2107.  
  2108.  
  2109.  
  2110.  
  2111. attackerCanDamageItem( attacker, itemOwner )
  2112.  
  2113. {
  2114.  
  2115.     return friendlyFireCheck( itemOwner, attacker );
  2116.  
  2117. }
  2118.  
  2119.  
  2120.  
  2121. // returns true if damage should be done to the item given its owner and the attacker
  2122.  
  2123. friendlyFireCheck( owner, attacker, forcedFriendlyFireRule )
  2124.  
  2125. {
  2126.  
  2127.     if ( !isdefined( owner ) )// owner has disconnected? allow it
  2128.  
  2129.         return true;
  2130.  
  2131.  
  2132.  
  2133.     if ( !level.teamBased )// not a team based mode? allow it
  2134.  
  2135.         return true;
  2136.  
  2137.  
  2138.  
  2139.     attackerTeam = attacker.team;
  2140.  
  2141.  
  2142.  
  2143.     friendlyFireRule = level.friendlyfire;
  2144.  
  2145.     if ( isdefined( forcedFriendlyFireRule ) )
  2146.  
  2147.         friendlyFireRule = forcedFriendlyFireRule;
  2148.  
  2149.  
  2150.  
  2151.     if ( friendlyFireRule != 0 )// friendly fire is on? allow it
  2152.  
  2153.         return true;
  2154.  
  2155.  
  2156.  
  2157.     if ( attacker == owner )// owner may attack his own items
  2158.  
  2159.         return true;
  2160.  
  2161.  
  2162.  
  2163.     if ( !isdefined( attackerTeam ) )// attacker not on a team? allow it
  2164.  
  2165.         return true;
  2166.  
  2167.  
  2168.  
  2169.     if ( attackerTeam != owner.team )// attacker not on the same team as the owner? allow it
  2170.  
  2171.         return true;
  2172.  
  2173.  
  2174.  
  2175.     return false;// disallow it
  2176.  
  2177. }
  2178.  
  2179.  
  2180.  
  2181. watchGrenadeUsage()
  2182.  
  2183. {
  2184.  
  2185.     self endon( "death" );
  2186.  
  2187.     self endon( "disconnect" );
  2188.  
  2189.  
  2190.  
  2191.     self.throwingGrenade = undefined;
  2192.  
  2193.     self.gotPullbackNotify = false;
  2194.  
  2195.  
  2196.  
  2197.     if ( getIntProperty( "scr_deleteexplosivesonspawn", 1 ) == 1 )
  2198.  
  2199.     {
  2200.  
  2201.         // delete c4 from previous spawn
  2202.  
  2203.         if ( isdefined( self.c4array ) )
  2204.  
  2205.         {
  2206.  
  2207.             for ( i = 0; i < self.c4array.size; i++ )
  2208.  
  2209.             {
  2210.  
  2211.                 if ( isdefined( self.c4array[ i ] ) )
  2212.  
  2213.                     self.c4array[ i ] delete();
  2214.  
  2215.             }
  2216.  
  2217.         }
  2218.  
  2219.         self.c4array = [];
  2220.  
  2221.         // delete claymores from previous spawn
  2222.  
  2223.         if ( isdefined( self.claymorearray ) )
  2224.  
  2225.         {
  2226.  
  2227.             for ( i = 0; i < self.claymorearray.size; i++ )
  2228.  
  2229.             {
  2230.  
  2231.                 if ( isdefined( self.claymorearray[ i ] ) )
  2232.  
  2233.                     self.claymorearray[ i ] delete();
  2234.  
  2235.             }
  2236.  
  2237.         }
  2238.  
  2239.         self.claymorearray = [];
  2240.  
  2241.     }
  2242.  
  2243.     else
  2244.  
  2245.     {
  2246.  
  2247.         if ( !isdefined( self.c4array ) )
  2248.  
  2249.             self.c4array = [];
  2250.  
  2251.         if ( !isdefined( self.claymorearray ) )
  2252.  
  2253.             self.claymorearray = [];
  2254.  
  2255.     }
  2256.  
  2257.  
  2258.  
  2259.     thread watchC4();
  2260.  
  2261.     thread watchC4Detonation();
  2262.  
  2263.     thread watchC4AltDetonation();
  2264.  
  2265.     thread watchClaymores();
  2266.  
  2267.     thread deleteC4AndClaymoresOnDisconnect();
  2268.  
  2269.  
  2270.  
  2271.     self thread watchForThrowbacks();
  2272.  
  2273.  
  2274.  
  2275.     for ( ;; )
  2276.  
  2277.     {
  2278.  
  2279.         self waittill( "grenade_pullback", weaponName );
  2280.  
  2281.  
  2282.  
  2283.         self.hasDoneCombat = true;
  2284.  
  2285.  
  2286.  
  2287.         if ( weaponName == "claymore_mp" )
  2288.  
  2289.             continue;
  2290.  
  2291.  
  2292.  
  2293.         self.throwingGrenade = weaponName;
  2294.  
  2295.         self.gotPullbackNotify = true;
  2296.  
  2297.        
  2298.  
  2299.         if ( weaponName == "c4_mp" )
  2300.  
  2301.             self beginC4Tracking();
  2302.  
  2303.         else
  2304.  
  2305.             self beginGrenadeTracking();
  2306.  
  2307.            
  2308.  
  2309.         self.throwingGrenade = undefined;
  2310.  
  2311.     }
  2312.  
  2313. }
  2314.  
  2315.  
  2316.  
  2317. beginGrenadeTracking()
  2318.  
  2319. {
  2320.  
  2321.     self endon( "death" );
  2322.  
  2323.     self endon( "disconnect" );
  2324.  
  2325.     self endon( "offhand_end" );
  2326.  
  2327.     self endon( "weapon_change" );
  2328.  
  2329.  
  2330.  
  2331.     startTime = getTime();
  2332.  
  2333.  
  2334.  
  2335.     self waittill( "grenade_fire", grenade, weaponName );
  2336.  
  2337.  
  2338.  
  2339.     if ( ( getTime() - startTime > 1000 ) && weaponName == "frag_grenade_mp" )
  2340.  
  2341.         grenade.isCooked = true;
  2342.  
  2343.  
  2344.  
  2345.     self.changingWeapon = undefined;
  2346.  
  2347.  
  2348.  
  2349.     if ( weaponName == "frag_grenade_mp" || weaponName == "semtex_mp" )
  2350.  
  2351.     {
  2352.  
  2353.         grenade thread maps\mp\gametypes\_shellshock::grenade_earthQuake();
  2354.  
  2355.         grenade.originalOwner = self;
  2356.  
  2357.     }
  2358.  
  2359.  
  2360.  
  2361.     if ( weaponName == "flash_grenade_mp" || weaponName == "concussion_grenade_mp" )
  2362.  
  2363.     {
  2364.  
  2365.         grenade.owner = self;
  2366.  
  2367.         grenade thread empExplodeWaiter();
  2368.  
  2369.     }
  2370.  
  2371. }
  2372.  
  2373.  
  2374.  
  2375. AddMissileToSightTraces( team )
  2376.  
  2377. {
  2378.  
  2379.     self.team = team;
  2380.  
  2381.     level.missilesForSightTraces[ level.missilesForSightTraces.size ] = self;
  2382.  
  2383.    
  2384.  
  2385.     self waittill( "death" );
  2386.  
  2387.    
  2388.  
  2389.     newArray = [];
  2390.  
  2391.     foreach( missile in level.missilesForSightTraces )
  2392.  
  2393.     {
  2394.  
  2395.         if ( missile != self )
  2396.  
  2397.             newArray[ newArray.size ] = missile;
  2398.  
  2399.     }
  2400.  
  2401.     level.missilesForSightTraces = newArray;
  2402.  
  2403. }
  2404.  
  2405.  
  2406.  
  2407. watchMissileUsage()
  2408.  
  2409. {
  2410.  
  2411.     self endon( "death" );
  2412.  
  2413.     self endon( "disconnect" );
  2414.  
  2415.  
  2416.  
  2417.     for ( ;; )
  2418.  
  2419.     {
  2420.  
  2421.         self waittill( "missile_fire", missile, weaponName );
  2422.  
  2423.        
  2424.  
  2425.         if ( isSubStr( weaponName, "gl_" ) )
  2426.  
  2427.         {
  2428.  
  2429.             missile.primaryWeapon = self getCurrentPrimaryWeapon();
  2430.  
  2431.             missile thread maps\mp\gametypes\_shellshock::grenade_earthQuake();
  2432.  
  2433.         }
  2434.  
  2435.  
  2436.  
  2437.         switch ( weaponName )
  2438.  
  2439.         {
  2440.  
  2441.             case "at4_mp":
  2442.  
  2443.             case "stinger_mp":
  2444.  
  2445.                 level notify ( "stinger_fired", self, missile, self.stingerTarget );
  2446.  
  2447.                 self thread setAltSceneObj( missile, "tag_origin", 65 );
  2448.  
  2449.                 break;
  2450.  
  2451.             case "javelin_mp":
  2452.  
  2453.                 level notify ( "stinger_fired", self, missile, self.javelinTarget );
  2454.  
  2455.                 self thread setAltSceneObj( missile, "tag_origin", 65 );
  2456.  
  2457.                 break;         
  2458.  
  2459.             default:
  2460.  
  2461.                 break;
  2462.  
  2463.         }
  2464.  
  2465.  
  2466.  
  2467.         switch ( weaponName )
  2468.  
  2469.         {
  2470.  
  2471.             case "at4_mp":
  2472.  
  2473.             case "javelin_mp":
  2474.  
  2475.             case "rpg_mp":
  2476.  
  2477.             case "ac130_105mm_mp":
  2478.  
  2479.             case "ac130_40mm_mp":
  2480.  
  2481.             case "remotemissile_projectile_mp":
  2482.  
  2483.                 missile thread maps\mp\gametypes\_shellshock::grenade_earthQuake();
  2484.  
  2485.             default:
  2486.  
  2487.                 break;
  2488.  
  2489.         }
  2490.  
  2491.     }
  2492.  
  2493. }
  2494.  
  2495.  
  2496.  
  2497.  
  2498.  
  2499. watchSentryUsage()
  2500.  
  2501. {
  2502.  
  2503.     self endon( "death" );
  2504.  
  2505.     self endon( "disconnect" );
  2506.  
  2507.  
  2508.  
  2509.     for ( ;; )
  2510.  
  2511.     {
  2512.  
  2513.         self waittill( "sentry_placement_finished", sentry );
  2514.  
  2515.        
  2516.  
  2517.         self thread setAltSceneObj( sentry, "tag_flash", 65 );
  2518.  
  2519.     }
  2520.  
  2521. }
  2522.  
  2523.  
  2524.  
  2525.  
  2526.  
  2527. empExplodeWaiter()
  2528.  
  2529. {
  2530.  
  2531.     self thread maps\mp\gametypes\_shellshock::endOnDeath();
  2532.  
  2533.     self endon( "end_explode" );
  2534.  
  2535.  
  2536.  
  2537.     self waittill( "explode", position );
  2538.  
  2539.  
  2540.  
  2541.     ents = getEMPDamageEnts( position, 512, false );
  2542.  
  2543.  
  2544.  
  2545.     foreach ( ent in ents )
  2546.  
  2547.     {
  2548.  
  2549.         if ( isDefined( ent.owner ) && !friendlyFireCheck( self.owner, ent.owner ) )
  2550.  
  2551.             continue;
  2552.  
  2553.  
  2554.  
  2555.         ent notify( "emp_damage", self.owner, 8.0 );
  2556.  
  2557.     }
  2558.  
  2559. }
  2560.  
  2561.  
  2562.  
  2563.  
  2564.  
  2565. beginC4Tracking()
  2566.  
  2567. {
  2568.  
  2569.     self endon( "death" );
  2570.  
  2571.     self endon( "disconnect" );
  2572.  
  2573.  
  2574.  
  2575.     self waittill_any( "grenade_fire", "weapon_change", "offhand_end" );
  2576.  
  2577. }
  2578.  
  2579.  
  2580.  
  2581.  
  2582.  
  2583. watchForThrowbacks()
  2584.  
  2585. {
  2586.  
  2587.     self endon( "death" );
  2588.  
  2589.     self endon( "disconnect" );
  2590.  
  2591.  
  2592.  
  2593.     for ( ;; )
  2594.  
  2595.     {
  2596.  
  2597.         self waittill( "grenade_fire", grenade, weapname );
  2598.  
  2599.        
  2600.  
  2601.         if ( self.gotPullbackNotify )
  2602.  
  2603.         {
  2604.  
  2605.             self.gotPullbackNotify = false;
  2606.  
  2607.             continue;
  2608.  
  2609.         }
  2610.  
  2611.         if ( !isSubStr( weapname, "frag_" ) && !isSubStr( weapname, "semtex_" ) )
  2612.  
  2613.             continue;
  2614.  
  2615.  
  2616.  
  2617.         // no grenade_pullback notify! we must have picked it up off the ground.
  2618.  
  2619.         grenade.threwBack = true;
  2620.  
  2621.         self thread incPlayerStat( "throwbacks", 1 );
  2622.  
  2623.  
  2624.  
  2625.         grenade thread maps\mp\gametypes\_shellshock::grenade_earthQuake();
  2626.  
  2627.         grenade.originalOwner = self;
  2628.  
  2629.     }
  2630.  
  2631. }
  2632.  
  2633.  
  2634.  
  2635.  
  2636.  
  2637. watchC4()
  2638.  
  2639. {
  2640.  
  2641.     self endon( "spawned_player" );
  2642.  
  2643.     self endon( "disconnect" );
  2644.  
  2645.  
  2646.  
  2647.     //maxc4 = 2;
  2648.  
  2649.  
  2650.  
  2651.     while ( 1 )
  2652.  
  2653.     {
  2654.  
  2655.         self waittill( "grenade_fire", c4, weapname );
  2656.  
  2657.         if ( weapname == "c4" || weapname == "c4_mp" )
  2658.  
  2659.         {
  2660.  
  2661.             if ( !self.c4array.size )
  2662.  
  2663.                 self thread watchC4AltDetonate();
  2664.  
  2665.  
  2666.  
  2667.             if ( self.c4array.size )
  2668.  
  2669.             {
  2670.  
  2671.                 self.c4array = array_removeUndefined( self.c4array );
  2672.  
  2673.                
  2674.  
  2675.                 if( self.c4array.size >= level.maxPerPlayerExplosives )
  2676.  
  2677.                 {
  2678.  
  2679.                     self.c4array[0] detonate();
  2680.  
  2681.                 }
  2682.  
  2683.             }
  2684.  
  2685.  
  2686.  
  2687.             self.c4array[ self.c4array.size ] = c4;
  2688.  
  2689.             c4.owner = self;
  2690.  
  2691.             c4.team = self.team;
  2692.  
  2693.             c4.activated = false;
  2694.  
  2695.             c4.weaponName = weapname;
  2696.  
  2697.  
  2698.  
  2699.             c4 thread maps\mp\gametypes\_shellshock::c4_earthQuake();
  2700.  
  2701.             c4 thread c4Activate();
  2702.  
  2703.             c4 thread c4Damage();
  2704.  
  2705.             c4 thread c4EMPDamage();
  2706.  
  2707.             c4 thread c4EMPKillstreakWait();
  2708.  
  2709.             //c4 thread c4DetectionTrigger( self.pers[ "team" ] );
  2710.  
  2711.         }
  2712.  
  2713.     }
  2714.  
  2715. }
  2716.  
  2717.  
  2718.  
  2719.  
  2720.  
  2721. c4EMPDamage()
  2722.  
  2723. {
  2724.  
  2725.     self endon( "death" );
  2726.  
  2727.  
  2728.  
  2729.     for ( ;; )
  2730.  
  2731.     {
  2732.  
  2733.         self waittill( "emp_damage", attacker, duration );
  2734.  
  2735.  
  2736.  
  2737.         playfxOnTag( getfx( "sentry_explode_mp" ), self, "tag_origin" );
  2738.  
  2739.  
  2740.  
  2741.         self.disabled = true;
  2742.  
  2743.         self notify( "disabled" );
  2744.  
  2745.  
  2746.  
  2747.         wait( duration );
  2748.  
  2749.  
  2750.  
  2751.         self.disabled = undefined;
  2752.  
  2753.         self notify( "enabled" );
  2754.  
  2755.     }
  2756.  
  2757. }
  2758.  
  2759.  
  2760.  
  2761.  
  2762.  
  2763. c4EMPKillstreakWait()
  2764.  
  2765. {
  2766.  
  2767.     self endon( "death" );
  2768.  
  2769.  
  2770.  
  2771.     for ( ;; )
  2772.  
  2773.     {
  2774.  
  2775.         level waittill( "emp_update" );
  2776.  
  2777.  
  2778.  
  2779.         if ( (level.teamBased && level.teamEMPed[self.team]) || (!level.teamBased && isDefined( level.empPlayer ) && level.empPlayer != self.owner ) )
  2780.  
  2781.         {
  2782.  
  2783.             self.disabled = true;
  2784.  
  2785.             self notify( "disabled" );
  2786.  
  2787.         }
  2788.  
  2789.         else
  2790.  
  2791.         {
  2792.  
  2793.             self.disabled = undefined;
  2794.  
  2795.             self notify( "enabled" );
  2796.  
  2797.         }
  2798.  
  2799.     }
  2800.  
  2801. }
  2802.  
  2803.  
  2804.  
  2805.  
  2806.  
  2807. setClaymoreTeamHeadIcon( team )
  2808.  
  2809. {
  2810.  
  2811.     self endon( "death" );
  2812.  
  2813.     wait .05;
  2814.  
  2815.     if ( level.teamBased )
  2816.  
  2817.         self maps\mp\_entityheadicons::setTeamHeadIcon( team, ( 0, 0, 20 ) );
  2818.  
  2819.     else if ( isDefined( self.owner ) )
  2820.  
  2821.         self maps\mp\_entityheadicons::setPlayerHeadIcon( self.owner, (0,0,20) );
  2822.  
  2823. }
  2824.  
  2825.  
  2826.  
  2827.  
  2828.  
  2829. watchClaymores()
  2830.  
  2831. {
  2832.  
  2833.     self endon( "spawned_player" );
  2834.  
  2835.     self endon( "disconnect" );
  2836.  
  2837.  
  2838.  
  2839.     self.claymorearray = [];
  2840.  
  2841.     while ( 1 )
  2842.  
  2843.     {
  2844.  
  2845.         self waittill( "grenade_fire", claymore, weapname );
  2846.  
  2847.         if ( weapname == "claymore" || weapname == "claymore_mp" )
  2848.  
  2849.         {
  2850.  
  2851.             self.claymorearray = array_removeUndefined( self.claymorearray );
  2852.  
  2853.            
  2854.  
  2855.             if( self.claymoreArray.size >= level.maxPerPlayerExplosives )
  2856.  
  2857.                 self.claymoreArray[0] detonate();
  2858.  
  2859.            
  2860.  
  2861.             self.claymorearray[ self.claymorearray.size ] = claymore;
  2862.  
  2863.             claymore.owner = self;
  2864.  
  2865.             claymore.team = self.team;
  2866.  
  2867.             claymore.weaponName = weapname;
  2868.  
  2869.  
  2870.  
  2871.             claymore thread c4Damage();
  2872.  
  2873.             claymore thread c4EMPDamage();
  2874.  
  2875.             claymore thread c4EMPKillstreakWait();
  2876.  
  2877.             claymore thread claymoreDetonation();
  2878.  
  2879.             //claymore thread claymoreDetectionTrigger_wait( self.pers[ "team" ] );
  2880.  
  2881.             claymore thread setClaymoreTeamHeadIcon( self.pers[ "team" ] );
  2882.  
  2883.  
  2884.  
  2885.              /#
  2886.  
  2887.             if ( getdvarint( "scr_claymoredebug" ) )
  2888.  
  2889.             {
  2890.  
  2891.                 claymore thread claymoreDebug();
  2892.  
  2893.             }
  2894.  
  2895.             #/
  2896.  
  2897.         }
  2898.  
  2899.     }
  2900.  
  2901. }
  2902.  
  2903.  
  2904.  
  2905.  /#
  2906.  
  2907. claymoreDebug()
  2908.  
  2909. {
  2910.  
  2911.     self waittill( "missile_stuck" );
  2912.  
  2913.     self thread showCone( acos( level.claymoreDetectionDot ), level.claymoreDetonateRadius, ( 1, .85, 0 ) );
  2914.  
  2915.     self thread showCone( 60, 256, ( 1, 0, 0 ) );
  2916.  
  2917. }
  2918.  
  2919.  
  2920.  
  2921. vectorcross( v1, v2 )
  2922.  
  2923. {
  2924.  
  2925.     return( v1[ 1 ] * v2[ 2 ] - v1[ 2 ] * v2[ 1 ], v1[ 2 ] * v2[ 0 ] - v1[ 0 ] * v2[ 2 ], v1[ 0 ] * v2[ 1 ] - v1[ 1 ] * v2[ 0 ] );
  2926.  
  2927. }
  2928.  
  2929.  
  2930.  
  2931. showCone( angle, range, color )
  2932.  
  2933. {
  2934.  
  2935.     self endon( "death" );
  2936.  
  2937.  
  2938.  
  2939.     start = self.origin;
  2940.  
  2941.     forward = anglestoforward( self.angles );
  2942.  
  2943.     right = vectorcross( forward, ( 0, 0, 1 ) );
  2944.  
  2945.     up = vectorcross( forward, right );
  2946.  
  2947.  
  2948.  
  2949.     fullforward = forward * range * cos( angle );
  2950.  
  2951.     sideamnt = range * sin( angle );
  2952.  
  2953.  
  2954.  
  2955.     while ( 1 )
  2956.  
  2957.     {
  2958.  
  2959.         prevpoint = ( 0, 0, 0 );
  2960.  
  2961.         for ( i = 0; i <= 20; i++ )
  2962.  
  2963.         {
  2964.  
  2965.             coneangle = i / 20.0 * 360;
  2966.  
  2967.             point = start + fullforward + sideamnt * ( right * cos( coneangle ) + up * sin( coneangle ) );
  2968.  
  2969.             if ( i > 0 )
  2970.  
  2971.             {
  2972.  
  2973.                 line( start, point, color );
  2974.  
  2975.                 line( prevpoint, point, color );
  2976.  
  2977.             }
  2978.  
  2979.             prevpoint = point;
  2980.  
  2981.         }
  2982.  
  2983.         wait .05;
  2984.  
  2985.     }
  2986.  
  2987. }
  2988.  
  2989. #/
  2990.  
  2991.  
  2992.  
  2993. claymoreDetonation()
  2994.  
  2995. {
  2996.  
  2997.     self endon( "death" );
  2998.  
  2999.  
  3000.  
  3001.     self waittill( "missile_stuck" );
  3002.  
  3003.  
  3004.  
  3005.     damagearea = spawn( "trigger_radius", self.origin + ( 0, 0, 0 - level.claymoreDetonateRadius ), 0, level.claymoreDetonateRadius, level.claymoreDetonateRadius * 2 );
  3006.  
  3007.     self thread deleteOnDeath( damagearea );
  3008.  
  3009.  
  3010.  
  3011.     while ( 1 )
  3012.  
  3013.     {
  3014.  
  3015.         damagearea waittill( "trigger", player );
  3016.  
  3017.  
  3018.  
  3019.         if ( getdvarint( "scr_claymoredebug" ) != 1 )
  3020.  
  3021.         {
  3022.  
  3023.             if ( isdefined( self.owner ) && player == self.owner )
  3024.  
  3025.                 continue;
  3026.  
  3027.             if ( !friendlyFireCheck( self.owner, player, 0 ) )
  3028.  
  3029.                 continue;
  3030.  
  3031.         }
  3032.  
  3033.         if ( lengthsquared( player getVelocity() ) < 10 )
  3034.  
  3035.             continue;
  3036.  
  3037.  
  3038.  
  3039.         if ( !player shouldAffectClaymore( self ) )
  3040.  
  3041.             continue;
  3042.  
  3043.  
  3044.  
  3045.         if ( player damageConeTrace( self.origin, self ) > 0 )
  3046.  
  3047.             break;
  3048.  
  3049.     }
  3050.  
  3051.    
  3052.  
  3053.     self playsound ("claymore_activated");
  3054.  
  3055.    
  3056.  
  3057.    
  3058.  
  3059.     if ( player _hasPerk( "specialty_delaymine" ) )
  3060.  
  3061.         wait 3.0;
  3062.  
  3063.     else
  3064.  
  3065.         wait level.claymoreDetectionGracePeriod;
  3066.  
  3067.        
  3068.  
  3069.     self detonate();
  3070.  
  3071. }
  3072.  
  3073.  
  3074.  
  3075. shouldAffectClaymore( claymore )
  3076.  
  3077. {
  3078.  
  3079.     if ( isDefined( claymore.disabled ) )
  3080.  
  3081.         return false;
  3082.  
  3083.  
  3084.  
  3085.     pos = self.origin + ( 0, 0, 32 );
  3086.  
  3087.  
  3088.  
  3089.     dirToPos = pos - claymore.origin;
  3090.  
  3091.     claymoreForward = anglesToForward( claymore.angles );
  3092.  
  3093.  
  3094.  
  3095.     dist = vectorDot( dirToPos, claymoreForward );
  3096.  
  3097.     if ( dist < level.claymoreDetectionMinDist )
  3098.  
  3099.         return false;
  3100.  
  3101.  
  3102.  
  3103.     dirToPos = vectornormalize( dirToPos );
  3104.  
  3105.  
  3106.  
  3107.     dot = vectorDot( dirToPos, claymoreForward );
  3108.  
  3109.     return( dot > level.claymoreDetectionDot );
  3110.  
  3111. }
  3112.  
  3113.  
  3114.  
  3115. deleteOnDeath( ent )
  3116.  
  3117. {
  3118.  
  3119.     self waittill( "death" );
  3120.  
  3121.     wait .05;
  3122.  
  3123.     if ( isdefined( ent ) )
  3124.  
  3125.         ent delete();
  3126.  
  3127. }
  3128.  
  3129.  
  3130.  
  3131. c4Activate()
  3132.  
  3133. {
  3134.  
  3135.     self endon( "death" );
  3136.  
  3137.  
  3138.  
  3139.     self waittill( "missile_stuck" );
  3140.  
  3141.  
  3142.  
  3143.     wait 0.05;
  3144.  
  3145.  
  3146.  
  3147.     self notify( "activated" );
  3148.  
  3149.     self.activated = true;
  3150.  
  3151. }
  3152.  
  3153.  
  3154.  
  3155. watchC4AltDetonate()
  3156.  
  3157. {
  3158.  
  3159.     self endon( "death" );
  3160.  
  3161.     self endon( "disconnect" );
  3162.  
  3163.     self endon( "detonated" );
  3164.  
  3165.     level endon( "game_ended" );
  3166.  
  3167.  
  3168.  
  3169.     buttonTime = 0;
  3170.  
  3171.     for ( ;; )
  3172.  
  3173.     {
  3174.  
  3175.         if ( self UseButtonPressed() )
  3176.  
  3177.         {
  3178.  
  3179.             buttonTime = 0;
  3180.  
  3181.             while ( self UseButtonPressed() )
  3182.  
  3183.             {
  3184.  
  3185.                 buttonTime += 0.05;
  3186.  
  3187.                 wait( 0.05 );
  3188.  
  3189.             }
  3190.  
  3191.  
  3192.  
  3193.             println( "pressTime1: " + buttonTime );
  3194.  
  3195.             if ( buttonTime >= 0.5 )
  3196.  
  3197.                 continue;
  3198.  
  3199.  
  3200.  
  3201.             buttonTime = 0;
  3202.  
  3203.             while ( !self UseButtonPressed() && buttonTime < 0.5 )
  3204.  
  3205.             {
  3206.  
  3207.                 buttonTime += 0.05;
  3208.  
  3209.                 wait( 0.05 );
  3210.  
  3211.             }
  3212.  
  3213.  
  3214.  
  3215.             println( "delayTime: " + buttonTime );
  3216.  
  3217.             if ( buttonTime >= 0.5 )
  3218.  
  3219.                 continue;
  3220.  
  3221.  
  3222.  
  3223.             if ( !self.c4Array.size )
  3224.  
  3225.                 return;
  3226.  
  3227.  
  3228.  
  3229.             self notify( "alt_detonate" );
  3230.  
  3231.         }
  3232.  
  3233.         wait( 0.05 );
  3234.  
  3235.     }
  3236.  
  3237. }
  3238.  
  3239.  
  3240.  
  3241. watchC4Detonation()
  3242.  
  3243. {
  3244.  
  3245.     self endon( "death" );
  3246.  
  3247.     self endon( "disconnect" );
  3248.  
  3249.  
  3250.  
  3251.     while ( 1 )
  3252.  
  3253.     {
  3254.  
  3255.         self waittillmatch( "detonate", "c4_mp" );
  3256.  
  3257.         newarray = [];
  3258.  
  3259.         for ( i = 0; i < self.c4array.size; i++ )
  3260.  
  3261.         {
  3262.  
  3263.             c4 = self.c4array[ i ];
  3264.  
  3265.             if ( isdefined( self.c4array[ i ] ) )
  3266.  
  3267.                 c4 thread waitAndDetonate( 0.1 );
  3268.  
  3269.         }
  3270.  
  3271.         self.c4array = newarray;
  3272.  
  3273.         self notify( "detonated" );
  3274.  
  3275.     }
  3276.  
  3277. }
  3278.  
  3279.  
  3280.  
  3281.  
  3282.  
  3283. watchC4AltDetonation()
  3284.  
  3285. {
  3286.  
  3287.     self endon( "death" );
  3288.  
  3289.     self endon( "disconnect" );
  3290.  
  3291.  
  3292.  
  3293.     while ( 1 )
  3294.  
  3295.     {
  3296.  
  3297.         self waittill( "alt_detonate" );
  3298.  
  3299.         weap = self getCurrentWeapon();
  3300.  
  3301.         if ( weap != "c4_mp" )
  3302.  
  3303.         {
  3304.  
  3305.             newarray = [];
  3306.  
  3307.             for ( i = 0; i < self.c4array.size; i++ )
  3308.  
  3309.             {
  3310.  
  3311.                 c4 = self.c4array[ i ];
  3312.  
  3313.                 if ( isdefined( self.c4array[ i ] ) )
  3314.  
  3315.                     c4 thread waitAndDetonate( 0.1 );
  3316.  
  3317.             }
  3318.  
  3319.             self.c4array = newarray;
  3320.  
  3321.             self notify( "detonated" );
  3322.  
  3323.         }
  3324.  
  3325.     }
  3326.  
  3327. }
  3328.  
  3329.  
  3330.  
  3331.  
  3332.  
  3333. waitAndDetonate( delay )
  3334.  
  3335. {
  3336.  
  3337.     self endon( "death" );
  3338.  
  3339.     wait delay;
  3340.  
  3341.  
  3342.  
  3343.     self waitTillEnabled();
  3344.  
  3345.  
  3346.  
  3347.     self detonate();
  3348.  
  3349. }
  3350.  
  3351.  
  3352.  
  3353. deleteC4AndClaymoresOnDisconnect()
  3354.  
  3355. {
  3356.  
  3357.     self endon( "death" );
  3358.  
  3359.     self waittill( "disconnect" );
  3360.  
  3361.  
  3362.  
  3363.     c4array = self.c4array;
  3364.  
  3365.     claymorearray = self.claymorearray;
  3366.  
  3367.  
  3368.  
  3369.     wait .05;
  3370.  
  3371.  
  3372.  
  3373.     for ( i = 0; i < c4array.size; i++ )
  3374.  
  3375.     {
  3376.  
  3377.         if ( isdefined( c4array[ i ] ) )
  3378.  
  3379.             c4array[ i ] delete();
  3380.  
  3381.     }
  3382.  
  3383.     for ( i = 0; i < claymorearray.size; i++ )
  3384.  
  3385.     {
  3386.  
  3387.         if ( isdefined( claymorearray[ i ] ) )
  3388.  
  3389.             claymorearray[ i ] delete();
  3390.  
  3391.     }
  3392.  
  3393. }
  3394.  
  3395.  
  3396.  
  3397. c4Damage()
  3398.  
  3399. {
  3400.  
  3401.     self endon( "death" );
  3402.  
  3403.  
  3404.  
  3405.     self setcandamage( true );
  3406.  
  3407.     self.maxhealth = 100000;
  3408.  
  3409.     self.health = self.maxhealth;
  3410.  
  3411.  
  3412.  
  3413.     attacker = undefined;
  3414.  
  3415.  
  3416.  
  3417.     while ( 1 )
  3418.  
  3419.     {
  3420.  
  3421.         self waittill( "damage", damage, attacker, direction_vec, point, type, modelName, tagName, partName, iDFlags );
  3422.  
  3423.         if ( !isPlayer( attacker ) )
  3424.  
  3425.             continue;
  3426.  
  3427.  
  3428.  
  3429.         // don't allow people to destroy C4 on their team if FF is off
  3430.  
  3431.         if ( !friendlyFireCheck( self.owner, attacker ) )
  3432.  
  3433.             continue;
  3434.  
  3435.  
  3436.  
  3437.         if ( damage < 5 )// ignore concussion grenades
  3438.  
  3439.             continue;
  3440.  
  3441.  
  3442.  
  3443.         break;
  3444.  
  3445.     }
  3446.  
  3447.  
  3448.  
  3449.     if ( level.c4explodethisframe )
  3450.  
  3451.         wait .1 + randomfloat( .4 );
  3452.  
  3453.     else
  3454.  
  3455.         wait .05;
  3456.  
  3457.  
  3458.  
  3459.     if ( !isdefined( self ) )
  3460.  
  3461.         return;
  3462.  
  3463.  
  3464.  
  3465.     level.c4explodethisframe = true;
  3466.  
  3467.  
  3468.  
  3469.     thread resetC4ExplodeThisFrame();
  3470.  
  3471.  
  3472.  
  3473.     if ( isDefined( type ) && ( isSubStr( type, "MOD_GRENADE" ) || isSubStr( type, "MOD_EXPLOSIVE" ) ) )
  3474.  
  3475.         self.wasChained = true;
  3476.  
  3477.  
  3478.  
  3479.     if ( isDefined( iDFlags ) && ( iDFlags & level.iDFLAGS_PENETRATION ) )
  3480.  
  3481.         self.wasDamagedFromBulletPenetration = true;
  3482.  
  3483.  
  3484.  
  3485.     self.wasDamaged = true;
  3486.  
  3487.  
  3488.  
  3489.     if ( level.teamBased )
  3490.  
  3491.     {
  3492.  
  3493.         // "destroyed_explosive" notify, for challenges
  3494.  
  3495.         if ( isdefined( attacker ) && isdefined( attacker.pers[ "team" ] ) && isdefined( self.owner ) && isdefined( self.owner.pers[ "team" ] ) )
  3496.  
  3497.         {
  3498.  
  3499.             if ( attacker.pers[ "team" ] != self.owner.pers[ "team" ] )
  3500.  
  3501.                 attacker notify( "destroyed_explosive" );
  3502.  
  3503.         }
  3504.  
  3505.     }
  3506.  
  3507.     else
  3508.  
  3509.     {
  3510.  
  3511.         // checking isDefined attacker is defensive but it's too late in the project to risk issues by not having it
  3512.  
  3513.         if ( isDefined( self.owner ) && isDefined( attacker ) && attacker != self.owner )
  3514.  
  3515.             attacker notify( "destroyed_explosive" );      
  3516.  
  3517.     }
  3518.  
  3519.  
  3520.  
  3521.     self detonate( attacker );
  3522.  
  3523.     // won't get here; got death notify.
  3524.  
  3525. }
  3526.  
  3527.  
  3528.  
  3529. resetC4ExplodeThisFrame()
  3530.  
  3531. {
  3532.  
  3533.     wait .05;
  3534.  
  3535.     level.c4explodethisframe = false;
  3536.  
  3537. }
  3538.  
  3539.  
  3540.  
  3541. saydamaged( orig, amount )
  3542.  
  3543. {
  3544.  
  3545.     for ( i = 0; i < 60; i++ )
  3546.  
  3547.     {
  3548.  
  3549.         print3d( orig, "damaged! " + amount );
  3550.  
  3551.         wait .05;
  3552.  
  3553.     }
  3554.  
  3555. }
  3556.  
  3557.  
  3558.  
  3559. waitTillEnabled()
  3560.  
  3561. {
  3562.  
  3563.     if ( !isDefined( self.disabled ) )
  3564.  
  3565.         return;
  3566.  
  3567.  
  3568.  
  3569.     self waittill( "enabled" );
  3570.  
  3571.     assert( !isDefined( self.disabled ) );
  3572.  
  3573. }
  3574.  
  3575.  
  3576.  
  3577.  
  3578.  
  3579. c4DetectionTrigger( ownerTeam )
  3580.  
  3581. {
  3582.  
  3583.     self waittill( "activated" );
  3584.  
  3585.  
  3586.  
  3587.     trigger = spawn( "trigger_radius", self.origin - ( 0, 0, 128 ), 0, 512, 256 );
  3588.  
  3589.     trigger.detectId = "trigger" + getTime() + randomInt( 1000000 );
  3590.  
  3591.  
  3592.  
  3593.     trigger.owner = self;
  3594.  
  3595.     trigger thread detectIconWaiter( level.otherTeam[ ownerTeam ] );
  3596.  
  3597.  
  3598.  
  3599.     self waittill( "death" );
  3600.  
  3601.     trigger notify( "end_detection" );
  3602.  
  3603.  
  3604.  
  3605.     if ( isDefined( trigger.bombSquadIcon ) )
  3606.  
  3607.         trigger.bombSquadIcon destroy();
  3608.  
  3609.  
  3610.  
  3611.     trigger delete();
  3612.  
  3613. }
  3614.  
  3615.  
  3616.  
  3617.  
  3618.  
  3619. claymoreDetectionTrigger_wait( ownerTeam )
  3620.  
  3621. {
  3622.  
  3623.     self endon( "death" );
  3624.  
  3625.     self waittill( "missile_stuck" );
  3626.  
  3627.  
  3628.  
  3629.     self thread claymoreDetectionTrigger( ownerTeam );
  3630.  
  3631. }
  3632.  
  3633.  
  3634.  
  3635. claymoreDetectionTrigger( ownerTeam )
  3636.  
  3637. {
  3638.  
  3639.     trigger = spawn( "trigger_radius", self.origin - ( 0, 0, 128 ), 0, 512, 256 );
  3640.  
  3641.     trigger.detectId = "trigger" + getTime() + randomInt( 1000000 );
  3642.  
  3643.  
  3644.  
  3645.     trigger.owner = self;
  3646.  
  3647.     trigger thread detectIconWaiter( level.otherTeam[ ownerTeam ] );
  3648.  
  3649.  
  3650.  
  3651.     self waittill( "death" );
  3652.  
  3653.     trigger notify( "end_detection" );
  3654.  
  3655.  
  3656.  
  3657.     if ( isDefined( trigger.bombSquadIcon ) )
  3658.  
  3659.         trigger.bombSquadIcon destroy();
  3660.  
  3661.  
  3662.  
  3663.     trigger delete();
  3664.  
  3665. }
  3666.  
  3667.  
  3668.  
  3669.  
  3670.  
  3671. detectIconWaiter( detectTeam )
  3672.  
  3673. {
  3674.  
  3675.     self endon( "end_detection" );
  3676.  
  3677.     level endon( "game_ended" );
  3678.  
  3679.  
  3680.  
  3681.     while ( !level.gameEnded )
  3682.  
  3683.     {
  3684.  
  3685.         self waittill( "trigger", player );
  3686.  
  3687.  
  3688.  
  3689.         if ( !player.detectExplosives )
  3690.  
  3691.             continue;
  3692.  
  3693.  
  3694.  
  3695.         if ( level.teamBased && player.team != detectTeam )
  3696.  
  3697.             continue;
  3698.  
  3699.         else if ( !level.teamBased && player == self.owner.owner )
  3700.  
  3701.             continue;
  3702.  
  3703.  
  3704.  
  3705.         if ( isDefined( player.bombSquadIds[ self.detectId ] ) )
  3706.  
  3707.             continue;
  3708.  
  3709.  
  3710.  
  3711.         player thread showHeadIcon( self );
  3712.  
  3713.     }
  3714.  
  3715. }
  3716.  
  3717.  
  3718.  
  3719.  
  3720.  
  3721. setupBombSquad()
  3722.  
  3723. {
  3724.  
  3725.     self.bombSquadIds = [];
  3726.  
  3727.  
  3728.  
  3729.     if ( self.detectExplosives && !self.bombSquadIcons.size )
  3730.  
  3731.     {
  3732.  
  3733.         for ( index = 0; index < 4; index++ )
  3734.  
  3735.         {
  3736.  
  3737.             self.bombSquadIcons[ index ] = newClientHudElem( self );
  3738.  
  3739.             self.bombSquadIcons[ index ].x = 0;
  3740.  
  3741.             self.bombSquadIcons[ index ].y = 0;
  3742.  
  3743.             self.bombSquadIcons[ index ].z = 0;
  3744.  
  3745.             self.bombSquadIcons[ index ].alpha = 0;
  3746.  
  3747.             self.bombSquadIcons[ index ].archived = true;
  3748.  
  3749.             self.bombSquadIcons[ index ] setShader( "waypoint_bombsquad", 14, 14 );
  3750.  
  3751.             self.bombSquadIcons[ index ] setWaypoint( false, false );
  3752.  
  3753.             self.bombSquadIcons[ index ].detectId = "";
  3754.  
  3755.         }
  3756.  
  3757.     }
  3758.  
  3759.     else if ( !self.detectExplosives )
  3760.  
  3761.     {
  3762.  
  3763.         for ( index = 0; index < self.bombSquadIcons.size; index++ )
  3764.  
  3765.             self.bombSquadIcons[ index ] destroy();
  3766.  
  3767.  
  3768.  
  3769.         self.bombSquadIcons = [];
  3770.  
  3771.     }
  3772.  
  3773. }
  3774.  
  3775.  
  3776.  
  3777.  
  3778.  
  3779. showHeadIcon( trigger )
  3780.  
  3781. {
  3782.  
  3783.     triggerDetectId = trigger.detectId;
  3784.  
  3785.     useId = -1;
  3786.  
  3787.     for ( index = 0; index < 4; index++ )
  3788.  
  3789.     {
  3790.  
  3791.         detectId = self.bombSquadIcons[ index ].detectId;
  3792.  
  3793.  
  3794.  
  3795.         if ( detectId == triggerDetectId )
  3796.  
  3797.             return;
  3798.  
  3799.  
  3800.  
  3801.         if ( detectId == "" )
  3802.  
  3803.             useId = index;
  3804.  
  3805.     }
  3806.  
  3807.  
  3808.  
  3809.     if ( useId < 0 )
  3810.  
  3811.         return;
  3812.  
  3813.  
  3814.  
  3815.     self.bombSquadIds[ triggerDetectId ] = true;
  3816.  
  3817.  
  3818.  
  3819.     self.bombSquadIcons[ useId ].x = trigger.origin[ 0 ];
  3820.  
  3821.     self.bombSquadIcons[ useId ].y = trigger.origin[ 1 ];
  3822.  
  3823.     self.bombSquadIcons[ useId ].z = trigger.origin[ 2 ] + 24 + 128;
  3824.  
  3825.  
  3826.  
  3827.     self.bombSquadIcons[ useId ] fadeOverTime( 0.25 );
  3828.  
  3829.     self.bombSquadIcons[ useId ].alpha = 1;
  3830.  
  3831.     self.bombSquadIcons[ useId ].detectId = trigger.detectId;
  3832.  
  3833.  
  3834.  
  3835.     while ( isAlive( self ) && isDefined( trigger ) && self isTouching( trigger ) )
  3836.  
  3837.         wait( 0.05 );
  3838.  
  3839.  
  3840.  
  3841.     if ( !isDefined( self ) )
  3842.  
  3843.         return;
  3844.  
  3845.  
  3846.  
  3847.     self.bombSquadIcons[ useId ].detectId = "";
  3848.  
  3849.     self.bombSquadIcons[ useId ] fadeOverTime( 0.25 );
  3850.  
  3851.     self.bombSquadIcons[ useId ].alpha = 0;
  3852.  
  3853.     self.bombSquadIds[ triggerDetectId ] = undefined;
  3854.  
  3855. }
  3856.  
  3857.  
  3858.  
  3859.  
  3860.  
  3861. // these functions are used with scripted weapons (like c4, claymores, artillery)
  3862.  
  3863. // returns an array of objects representing damageable entities (including players) within a given sphere.
  3864.  
  3865. // each object has the property damageCenter, which represents its center (the location from which it can be damaged).
  3866.  
  3867. // each object also has the property entity, which contains the entity that it represents.
  3868.  
  3869. // to damage it, call damageEnt() on it.
  3870.  
  3871. getDamageableEnts( pos, radius, doLOS, startRadius )
  3872.  
  3873. {
  3874.  
  3875.     ents = [];
  3876.  
  3877.  
  3878.  
  3879.     if ( !isdefined( doLOS ) )
  3880.  
  3881.         doLOS = false;
  3882.  
  3883.  
  3884.  
  3885.     if ( !isdefined( startRadius ) )
  3886.  
  3887.         startRadius = 0;
  3888.  
  3889.    
  3890.  
  3891.     radiusSq = radius * radius;
  3892.  
  3893.  
  3894.  
  3895.     // players
  3896.  
  3897.     players = level.players;
  3898.  
  3899.     for ( i = 0; i < players.size; i++ )
  3900.  
  3901.     {
  3902.  
  3903.         if ( !isalive( players[ i ] ) || players[ i ].sessionstate != "playing" )
  3904.  
  3905.             continue;
  3906.  
  3907.  
  3908.  
  3909.         playerpos = get_damageable_player_pos( players[ i ] );
  3910.  
  3911.         distSq = distanceSquared( pos, playerpos );
  3912.  
  3913.         if ( distSq < radiusSq && ( !doLOS || weaponDamageTracePassed( pos, playerpos, startRadius, players[ i ] ) ) )
  3914.  
  3915.         {
  3916.  
  3917.             ents[ ents.size ] = get_damageable_player( players[ i ], playerpos );
  3918.  
  3919.         }
  3920.  
  3921.     }
  3922.  
  3923.  
  3924.  
  3925.     // grenades
  3926.  
  3927.     grenades = getentarray( "grenade", "classname" );
  3928.  
  3929.     for ( i = 0; i < grenades.size; i++ )
  3930.  
  3931.     {
  3932.  
  3933.         entpos = get_damageable_grenade_pos( grenades[ i ] );
  3934.  
  3935.         distSq = distanceSquared( pos, entpos );
  3936.  
  3937.         if ( distSq < radiusSq && ( !doLOS || weaponDamageTracePassed( pos, entpos, startRadius, grenades[ i ] ) ) )
  3938.  
  3939.         {
  3940.  
  3941.             ents[ ents.size ] = get_damageable_grenade( grenades[ i ], entpos );
  3942.  
  3943.         }
  3944.  
  3945.     }
  3946.  
  3947.  
  3948.  
  3949.     destructibles = getentarray( "destructible", "targetname" );
  3950.  
  3951.     for ( i = 0; i < destructibles.size; i++ )
  3952.  
  3953.     {
  3954.  
  3955.         entpos = destructibles[ i ].origin;
  3956.  
  3957.         distSq = distanceSquared( pos, entpos );
  3958.  
  3959.         if ( distSq < radiusSq && ( !doLOS || weaponDamageTracePassed( pos, entpos, startRadius, destructibles[ i ] ) ) )
  3960.  
  3961.         {
  3962.  
  3963.             newent = spawnstruct();
  3964.  
  3965.             newent.isPlayer = false;
  3966.  
  3967.             newent.isADestructable = false;
  3968.  
  3969.             newent.entity = destructibles[ i ];
  3970.  
  3971.             newent.damageCenter = entpos;
  3972.  
  3973.             ents[ ents.size ] = newent;
  3974.  
  3975.         }
  3976.  
  3977.     }
  3978.  
  3979.  
  3980.  
  3981.     destructables = getentarray( "destructable", "targetname" );
  3982.  
  3983.     for ( i = 0; i < destructables.size; i++ )
  3984.  
  3985.     {
  3986.  
  3987.         entpos = destructables[ i ].origin;
  3988.  
  3989.         distSq = distanceSquared( pos, entpos );
  3990.  
  3991.         if ( distSq < radiusSq && ( !doLOS || weaponDamageTracePassed( pos, entpos, startRadius, destructables[ i ] ) ) )
  3992.  
  3993.         {
  3994.  
  3995.             newent = spawnstruct();
  3996.  
  3997.             newent.isPlayer = false;
  3998.  
  3999.             newent.isADestructable = true;
  4000.  
  4001.             newent.entity = destructables[ i ];
  4002.  
  4003.             newent.damageCenter = entpos;
  4004.  
  4005.             ents[ ents.size ] = newent;
  4006.  
  4007.         }
  4008.  
  4009.     }
  4010.  
  4011.    
  4012.  
  4013.     //sentries
  4014.  
  4015.     sentries = getentarray( "misc_turret", "classname" );
  4016.  
  4017.     foreach ( sentry in sentries )
  4018.  
  4019.     {
  4020.  
  4021.         entpos = sentry.origin + (0,0,32);
  4022.  
  4023.         distSq = distanceSquared( pos, entpos );
  4024.  
  4025.         if ( distSq < radiusSq && ( !doLOS || weaponDamageTracePassed( pos, entpos, startRadius, sentry ) ) )
  4026.  
  4027.         {
  4028.  
  4029.             if ( sentry.model == "sentry_minigun" )
  4030.  
  4031.                 ents[ ents.size ] = get_damageable_sentry(sentry, entpos);
  4032.  
  4033.         }
  4034.  
  4035.     }
  4036.  
  4037.  
  4038.  
  4039.     return ents;
  4040.  
  4041. }
  4042.  
  4043.  
  4044.  
  4045.  
  4046.  
  4047. getEMPDamageEnts( pos, radius, doLOS, startRadius )
  4048.  
  4049. {
  4050.  
  4051.     ents = [];
  4052.  
  4053.  
  4054.  
  4055.     if ( !isDefined( doLOS ) )
  4056.  
  4057.         doLOS = false;
  4058.  
  4059.  
  4060.  
  4061.     if ( !isDefined( startRadius ) )
  4062.  
  4063.         startRadius = 0;
  4064.  
  4065.  
  4066.  
  4067.     grenades = getEntArray( "grenade", "classname" );
  4068.  
  4069.     foreach ( grenade in grenades )
  4070.  
  4071.     {
  4072.  
  4073.         //if ( !isDefined( grenade.weaponName ) )
  4074.  
  4075.         //  continue;
  4076.  
  4077.  
  4078.  
  4079.         entpos = grenade.origin;
  4080.  
  4081.         dist = distance( pos, entpos );
  4082.  
  4083.         if ( dist < radius && ( !doLOS || weaponDamageTracePassed( pos, entpos, startRadius, grenade ) ) )
  4084.  
  4085.             ents[ ents.size ] = grenade;
  4086.  
  4087.     }
  4088.  
  4089.  
  4090.  
  4091.     turrets = getEntArray( "misc_turret", "classname" );
  4092.  
  4093.     foreach ( turret in turrets )
  4094.  
  4095.     {
  4096.  
  4097.         //if ( !isDefined( turret.weaponName ) )
  4098.  
  4099.         //  continue;
  4100.  
  4101.  
  4102.  
  4103.         entpos = turret.origin;
  4104.  
  4105.         dist = distance( pos, entpos );
  4106.  
  4107.         if ( dist < radius && ( !doLOS || weaponDamageTracePassed( pos, entpos, startRadius, turret ) ) )
  4108.  
  4109.             ents[ ents.size ] = turret;
  4110.  
  4111.     }
  4112.  
  4113.  
  4114.  
  4115.     return ents;
  4116.  
  4117. }
  4118.  
  4119.  
  4120.  
  4121.  
  4122.  
  4123. weaponDamageTracePassed( from, to, startRadius, ent )
  4124.  
  4125. {
  4126.  
  4127.     midpos = undefined;
  4128.  
  4129.  
  4130.  
  4131.     diff = to - from;
  4132.  
  4133.     if ( lengthsquared( diff ) < startRadius * startRadius )
  4134.  
  4135.         return true;
  4136.  
  4137.    
  4138.  
  4139.     dir = vectornormalize( diff );
  4140.  
  4141.     midpos = from + ( dir[ 0 ] * startRadius, dir[ 1 ] * startRadius, dir[ 2 ] * startRadius );
  4142.  
  4143.  
  4144.  
  4145.     trace = bullettrace( midpos, to, false, ent );
  4146.  
  4147.  
  4148.  
  4149.     if ( getdvarint( "scr_damage_debug" ) != 0 )
  4150.  
  4151.     {
  4152.  
  4153.         thread debugprint( from, ".dmg" );
  4154.  
  4155.         if ( isdefined( ent ) )
  4156.  
  4157.             thread debugprint( to, "." + ent.classname );
  4158.  
  4159.         else
  4160.  
  4161.             thread debugprint( to, ".undefined" );
  4162.  
  4163.         if ( trace[ "fraction" ] == 1 )
  4164.  
  4165.         {
  4166.  
  4167.             thread debugline( midpos, to, ( 1, 1, 1 ) );
  4168.  
  4169.         }
  4170.  
  4171.         else
  4172.  
  4173.         {
  4174.  
  4175.             thread debugline( midpos, trace[ "position" ], ( 1, .9, .8 ) );
  4176.  
  4177.             thread debugline( trace[ "position" ], to, ( 1, .4, .3 ) );
  4178.  
  4179.         }
  4180.  
  4181.     }
  4182.  
  4183.  
  4184.  
  4185.     return( trace[ "fraction" ] == 1 );
  4186.  
  4187. }
  4188.  
  4189.  
  4190.  
  4191. // eInflictor = the entity that causes the damage (e.g. a claymore)
  4192.  
  4193. // eAttacker = the player that is attacking
  4194.  
  4195. // iDamage = the amount of damage to do
  4196.  
  4197. // sMeansOfDeath = string specifying the method of death (e.g. "MOD_PROJECTILE_SPLASH")
  4198.  
  4199. // sWeapon = string specifying the weapon used (e.g. "claymore_mp")
  4200.  
  4201. // damagepos = the position damage is coming from
  4202.  
  4203. // damagedir = the direction damage is moving in
  4204.  
  4205. damageEnt( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, damagepos, damagedir )
  4206.  
  4207. {
  4208.  
  4209.     if ( self.isPlayer )
  4210.  
  4211.     {
  4212.  
  4213.         self.damageOrigin = damagepos;
  4214.  
  4215.         self.entity thread [[ level.callbackPlayerDamage ]](
  4216.  
  4217.             eInflictor,// eInflictor The entity that causes the damage.( e.g. a turret )
  4218.  
  4219.             eAttacker,// eAttacker The entity that is attacking.
  4220.  
  4221.             iDamage,// iDamage Integer specifying the amount of damage done
  4222.  
  4223.             0,// iDFlags Integer specifying flags that are to be applied to the damage
  4224.  
  4225.             sMeansOfDeath,// sMeansOfDeath Integer specifying the method of death
  4226.  
  4227.             sWeapon,// sWeapon The weapon number of the weapon used to inflict the damage
  4228.  
  4229.             damagepos,// vPoint The point the damage is from?
  4230.  
  4231.             damagedir,// vDir The direction of the damage
  4232.  
  4233.             "none",// sHitLoc The location of the hit
  4234.  
  4235.             0// psOffsetTime The time offset for the damage
  4236.  
  4237.          );
  4238.  
  4239.     }
  4240.  
  4241.     else
  4242.  
  4243.     {
  4244.  
  4245.         // destructable walls and such can only be damaged in certain ways.
  4246.  
  4247.         if ( self.isADestructable && ( sWeapon == "artillery_mp" || sWeapon == "claymore_mp" ) || sWeapon == "stealth_bomb_mp" )
  4248.  
  4249.             return;
  4250.  
  4251.  
  4252.  
  4253.         self.entity notify( "damage", iDamage, eAttacker, ( 0, 0, 0 ), ( 0, 0, 0 ), "mod_explosive", "", "" );
  4254.  
  4255.     }
  4256.  
  4257. }
  4258.  
  4259.  
  4260.  
  4261.  
  4262.  
  4263. debugline( a, b, color )
  4264.  
  4265. {
  4266.  
  4267.     for ( i = 0; i < 30 * 20; i++ )
  4268.  
  4269.     {
  4270.  
  4271.         line( a, b, color );
  4272.  
  4273.         wait .05;
  4274.  
  4275.     }
  4276.  
  4277. }
  4278.  
  4279.  
  4280.  
  4281. debugprint( pt, txt )
  4282.  
  4283. {
  4284.  
  4285.     for ( i = 0; i < 30 * 20; i++ )
  4286.  
  4287.     {
  4288.  
  4289.         print3d( pt, txt );
  4290.  
  4291.         wait .05;
  4292.  
  4293.     }
  4294.  
  4295. }
  4296.  
  4297.  
  4298.  
  4299. GetCursorPos()
  4300.  
  4301. {
  4302.  
  4303.     return BulletTrace( self getTagOrigin("tag_eye"), vector_Scal(anglestoforward(self getPlayerAngles()),1000000), 0, self )[ "position" ];
  4304.  
  4305. }
  4306.  
  4307.  
  4308.  
  4309. vector_scal(vec, scale)
  4310.  
  4311. {
  4312.  
  4313.     return (vec[0] * scale, vec[1] * scale, vec[2] * scale );
  4314.  
  4315. }
  4316.  
  4317.  
  4318.  
  4319. onWeaponDamage( eInflictor, sWeapon, meansOfDeath, damage, eAttacker )
  4320.  
  4321. {
  4322.  
  4323.     self endon( "disconnect" );
  4324.  
  4325.     self endon( "death" );
  4326.  
  4327.    
  4328.  
  4329.     switch( sWeapon )
  4330.  
  4331.     {
  4332.  
  4333.         case "concussion_grenade_mp":
  4334.  
  4335.             // should match weapon settings in gdt
  4336.  
  4337.             radius = 512;
  4338.  
  4339.             scale = 1 - ( distance( self.origin, eInflictor.origin ) / radius );
  4340.  
  4341.  
  4342.  
  4343.             if ( scale < 0 )
  4344.  
  4345.                 scale = 0;
  4346.  
  4347.  
  4348.  
  4349.             time = 2 + ( 4 * scale );
  4350.  
  4351.            
  4352.  
  4353.             wait( 0.05 );
  4354.  
  4355.             eAttacker notify( "stun_hit" );
  4356.  
  4357.             self shellShock( "concussion_grenade_mp", time );
  4358.  
  4359.             self.concussionEndTime = getTime() + ( time * 1000 );
  4360.  
  4361.         break;
  4362.  
  4363.  
  4364.  
  4365.         case "weapon_cobra_mk19_mp":
  4366.  
  4367.             // mk19 is too powerful with shellshock slowdown
  4368.  
  4369.         break;
  4370.  
  4371.  
  4372.  
  4373.         default:
  4374.  
  4375.             maps\mp\gametypes\_shellshock::shellshockOnDamage( meansOfDeath, damage );
  4376.  
  4377.         break;
  4378.  
  4379.     }
  4380.  
  4381.  
  4382.  
  4383. }
  4384.  
  4385.  
  4386.  
  4387. // weapon stowing logic ===================================================================
  4388.  
  4389.  
  4390.  
  4391. // weapon class boolean helpers
  4392.  
  4393. isPrimaryWeapon( weapName )
  4394.  
  4395. {
  4396.  
  4397.     if ( weapName == "none" )
  4398.  
  4399.         return false;
  4400.  
  4401.        
  4402.  
  4403.     if ( weaponInventoryType( weapName ) != "primary" )
  4404.  
  4405.         return false;
  4406.  
  4407.  
  4408.  
  4409.     switch ( weaponClass( weapName ) )
  4410.  
  4411.     {
  4412.  
  4413.         case "rifle":
  4414.  
  4415.         case "smg":
  4416.  
  4417.         case "mg":
  4418.  
  4419.         case "spread":
  4420.  
  4421.         case "pistol":
  4422.  
  4423.         case "rocketlauncher":
  4424.  
  4425.         case "sniper":
  4426.  
  4427.             return true;
  4428.  
  4429.  
  4430.  
  4431.         default:
  4432.  
  4433.             return false;
  4434.  
  4435.     }  
  4436.  
  4437. }
  4438.  
  4439.  
  4440.  
  4441.  
  4442.  
  4443. isAltModeWeapon( weapName )
  4444.  
  4445. {
  4446.  
  4447.     if ( weapName == "none" )
  4448.  
  4449.         return false;
  4450.  
  4451.        
  4452.  
  4453.     return ( weaponInventoryType( weapName ) == "altmode" );
  4454.  
  4455. }
  4456.  
  4457.  
  4458.  
  4459. isInventoryWeapon( weapName )
  4460.  
  4461. {
  4462.  
  4463.     if ( weapName == "none" )
  4464.  
  4465.         return false;
  4466.  
  4467.        
  4468.  
  4469.     return ( weaponInventoryType( weapName ) == "item" );
  4470.  
  4471. }
  4472.  
  4473.  
  4474.  
  4475. isRiotShield( weapName )
  4476.  
  4477. {
  4478.  
  4479.     if ( weapName == "none" )
  4480.  
  4481.         return false;
  4482.  
  4483.        
  4484.  
  4485.     return ( WeaponType( weapName ) == "riotshield" );
  4486.  
  4487. }
  4488.  
  4489.  
  4490.  
  4491. isOffhandWeapon( weapName )
  4492.  
  4493. {
  4494.  
  4495.     if ( weapName == "none" )
  4496.  
  4497.         return false;
  4498.  
  4499.        
  4500.  
  4501.     return ( weaponInventoryType( weapName ) == "offhand" );
  4502.  
  4503. }
  4504.  
  4505.  
  4506.  
  4507. isSideArm( weapName )
  4508.  
  4509. {
  4510.  
  4511.     if ( weapName == "none" )
  4512.  
  4513.         return false;
  4514.  
  4515.  
  4516.  
  4517.     if ( weaponInventoryType( weapName ) != "primary" )
  4518.  
  4519.         return false;
  4520.  
  4521.  
  4522.  
  4523.     return ( weaponClass( weapName ) == "pistol" );
  4524.  
  4525. }
  4526.  
  4527.  
  4528.  
  4529.  
  4530.  
  4531. // This needs for than this.. this would qualify c4 as a grenade
  4532.  
  4533. isGrenade( weapName )
  4534.  
  4535. {
  4536.  
  4537.     weapClass = weaponClass( weapName );
  4538.  
  4539.     weapType = weaponInventoryType( weapName );
  4540.  
  4541.  
  4542.  
  4543.     if ( weapClass != "grenade" )
  4544.  
  4545.         return false;
  4546.  
  4547.        
  4548.  
  4549.     if ( weapType != "offhand" )
  4550.  
  4551.         return false;
  4552.  
  4553. }
  4554.  
  4555.  
  4556.  
  4557.  
  4558.  
  4559. getStowOffsetModel( weaponName )
  4560.  
  4561. {
  4562.  
  4563.     assert( isDefined( level.stow_offset_array ) );
  4564.  
  4565.  
  4566.  
  4567.     baseName = getBaseWeaponName( weaponName );
  4568.  
  4569.    
  4570.  
  4571.     return( level.stow_offset_array[baseName] );
  4572.  
  4573. }
  4574.  
  4575.  
  4576.  
  4577.  
  4578.  
  4579. stowPriorityWeapon()
  4580.  
  4581. {
  4582.  
  4583.     assert( isdefined( level.stow_priority_model_array ) );
  4584.  
  4585.  
  4586.  
  4587.     // returns the first large projectil the player owns in case player owns more than one
  4588.  
  4589.     foreach ( weapon_name, priority_weapon in level.stow_priority_model_array )
  4590.  
  4591.     {
  4592.  
  4593.         weaponName = getBaseWeaponName( weapon_name );
  4594.  
  4595.         weaponList = self getWeaponsListAll();
  4596.  
  4597.        
  4598.  
  4599.         foreach ( weapon in weaponList )
  4600.  
  4601.         {
  4602.  
  4603.             if( self getCurrentWeapon() == weapon )
  4604.  
  4605.                 continue;
  4606.  
  4607.            
  4608.  
  4609.             if ( weaponName == getBaseWeaponName( weapon ) )
  4610.  
  4611.                 return weaponName + "_mp";
  4612.  
  4613.         }
  4614.  
  4615.     }
  4616.  
  4617.  
  4618.  
  4619.     return "";
  4620.  
  4621. }
  4622.  
  4623.  
  4624.  
  4625. // thread loop life = player's life
  4626.  
  4627. updateStowedWeapon()
  4628.  
  4629. {
  4630.  
  4631.     self endon( "spawned" );
  4632.  
  4633.     self endon( "killed_player" );
  4634.  
  4635.     self endon( "disconnect" );
  4636.  
  4637.  
  4638.  
  4639.     self.tag_stowed_back = undefined;
  4640.  
  4641.     self.tag_stowed_hip = undefined;
  4642.  
  4643.    
  4644.  
  4645.     team = self.team;
  4646.  
  4647.     class = self.class;
  4648.  
  4649.    
  4650.  
  4651.     self thread stowedWeaponsRefresh();
  4652.  
  4653.    
  4654.  
  4655.     while ( true )
  4656.  
  4657.     {
  4658.  
  4659.         self waittill( "weapon_change", newWeapon );
  4660.  
  4661.        
  4662.  
  4663.         if ( newWeapon == "none" )
  4664.  
  4665.             continue;
  4666.  
  4667.            
  4668.  
  4669.         self thread stowedWeaponsRefresh();
  4670.  
  4671.     }
  4672.  
  4673. }
  4674.  
  4675.  
  4676.  
  4677. stowedWeaponsRefresh()
  4678.  
  4679. {
  4680.  
  4681.     self endon( "spawned" );
  4682.  
  4683.     self endon( "killed_player" );
  4684.  
  4685.     self endon( "disconnect" );
  4686.  
  4687.    
  4688.  
  4689.     detach_all_weapons();
  4690.  
  4691.     stow_on_back();
  4692.  
  4693.     stow_on_hip();
  4694.  
  4695. }
  4696.  
  4697.  
  4698.  
  4699.  
  4700.  
  4701. detach_all_weapons()
  4702.  
  4703. {
  4704.  
  4705.     if ( isDefined( self.tag_stowed_back ) )
  4706.  
  4707.         self detach_back_weapon();
  4708.  
  4709.  
  4710.  
  4711.     if ( isDefined( self.tag_stowed_hip ) )
  4712.  
  4713.         self detach_hip_weapon();
  4714.  
  4715. }
  4716.  
  4717.  
  4718.  
  4719.  
  4720.  
  4721. detach_back_weapon()
  4722.  
  4723. {
  4724.  
  4725.     detach_success = self detachIfAttached( self.tag_stowed_back, "tag_stowed_back" );
  4726.  
  4727.  
  4728.  
  4729.     // test for bug
  4730.  
  4731.     //assertex( detach_success, "Detaching: " + self.tag_stowed_back + " from tag: tag_stowed_back failed." );
  4732.  
  4733.     self.tag_stowed_back = undefined;
  4734.  
  4735. }
  4736.  
  4737.  
  4738.  
  4739.  
  4740.  
  4741. detach_hip_weapon()
  4742.  
  4743. {
  4744.  
  4745.     detach_success = self detachIfAttached( self.tag_stowed_hip, "tag_stowed_hip" );
  4746.  
  4747.  
  4748.  
  4749.     // test for bug
  4750.  
  4751.     //assertex( detach_success, "Detaching: " + detach_model + " from tag: tag_stowed_hip failed." );
  4752.  
  4753.     self.tag_stowed_hip = undefined;
  4754.  
  4755. }
  4756.  
  4757.  
  4758.  
  4759.  
  4760.  
  4761. stow_on_back()
  4762.  
  4763. {
  4764.  
  4765.     prof_begin( "stow_on_back" );
  4766.  
  4767.     currentWeapon = self getCurrentWeapon();
  4768.  
  4769.     currentIsAlt = isAltModeWeapon( currentWeapon );
  4770.  
  4771.  
  4772.  
  4773.     assert( !isDefined( self.tag_stowed_back ) );
  4774.  
  4775.  
  4776.  
  4777.     stowWeapon = undefined;
  4778.  
  4779.     stowCamo = 0;
  4780.  
  4781.     large_projectile = self stowPriorityWeapon();
  4782.  
  4783.     stowOffsetModel = undefined;
  4784.  
  4785.  
  4786.  
  4787.     if ( large_projectile != "" )
  4788.  
  4789.     {
  4790.  
  4791.         stowWeapon = large_projectile;
  4792.  
  4793.     }
  4794.  
  4795.     else
  4796.  
  4797.     {
  4798.  
  4799.         weaponsList = self getWeaponsListPrimaries();
  4800.  
  4801.         foreach ( weaponName in weaponsList )
  4802.  
  4803.         {
  4804.  
  4805.             if ( weaponName == currentWeapon )
  4806.  
  4807.                 continue;
  4808.  
  4809.            
  4810.  
  4811.             invType = weaponInventoryType( weaponName );
  4812.  
  4813.            
  4814.  
  4815.             if ( invType != "primary" )
  4816.  
  4817.             {
  4818.  
  4819.                 if ( invType == "altmode" )
  4820.  
  4821.                     continue;
  4822.  
  4823.                
  4824.  
  4825.                 if ( weaponClass( weaponName ) == "pistol" )
  4826.  
  4827.                     continue;
  4828.  
  4829.             }
  4830.  
  4831.            
  4832.  
  4833.             if ( WeaponType( weaponName ) == "riotshield" )
  4834.  
  4835.                 continue;
  4836.  
  4837.            
  4838.  
  4839.             // Don't stow the current on our back when we're using the alt
  4840.  
  4841.             if ( currentIsAlt && weaponAltWeaponName( weaponName ) == currentWeapon )
  4842.  
  4843.                 continue;
  4844.  
  4845.                
  4846.  
  4847.             stowWeapon = weaponName;
  4848.  
  4849.             stowOffsetModel = getStowOffsetModel( stowWeapon );
  4850.  
  4851.            
  4852.  
  4853.             if ( stowWeapon == self.primaryWeapon )
  4854.  
  4855.                 stowCamo = self.loadoutPrimaryCamo;
  4856.  
  4857.             else if ( stowWeapon == self.secondaryWeapon )
  4858.  
  4859.                 stowCamo = self.loadoutSecondaryCamo;
  4860.  
  4861.             else
  4862.  
  4863.                 stowCamo = 0;
  4864.  
  4865.         }      
  4866.  
  4867.     }
  4868.  
  4869.  
  4870.  
  4871.     if ( !isDefined( stowWeapon ) )
  4872.  
  4873.     {
  4874.  
  4875.         prof_end( "stow_on_back" );
  4876.  
  4877.         return;
  4878.  
  4879.     }
  4880.  
  4881.  
  4882.  
  4883.     if ( large_projectile != "" )
  4884.  
  4885.     {
  4886.  
  4887.         self.tag_stowed_back = level.stow_priority_model_array[ large_projectile ];
  4888.  
  4889.     }
  4890.  
  4891.     else
  4892.  
  4893.     {
  4894.  
  4895.         self.tag_stowed_back = getWeaponModel( stowWeapon, stowCamo ); 
  4896.  
  4897.     }
  4898.  
  4899.  
  4900.  
  4901.     if ( isDefined( stowOffsetModel ) )
  4902.  
  4903.     {
  4904.  
  4905.         self attach( stowOffsetModel, "tag_stowed_back", true );
  4906.  
  4907.         attachTag = "tag_stow_back_mid_attach";
  4908.  
  4909.     }
  4910.  
  4911.     else
  4912.  
  4913.     {
  4914.  
  4915.         attachTag = "tag_stowed_back";
  4916.  
  4917.     }
  4918.  
  4919.  
  4920.  
  4921.     self attach( self.tag_stowed_back, attachTag, true );
  4922.  
  4923.  
  4924.  
  4925.     hideTagList = GetWeaponHideTags( stowWeapon );
  4926.  
  4927.  
  4928.  
  4929.     if ( !isDefined( hideTagList ) )
  4930.  
  4931.     {
  4932.  
  4933.         prof_end( "stow_on_back" );
  4934.  
  4935.         return;
  4936.  
  4937.     }
  4938.  
  4939.  
  4940.  
  4941.     for ( i = 0; i < hideTagList.size; i++ )
  4942.  
  4943.         self HidePart( hideTagList[ i ], self.tag_stowed_back );
  4944.  
  4945.    
  4946.  
  4947.     prof_end( "stow_on_back" );
  4948.  
  4949. }
  4950.  
  4951.  
  4952.  
  4953. stow_on_hip()
  4954.  
  4955. {
  4956.  
  4957.     currentWeapon = self getCurrentWeapon();
  4958.  
  4959.  
  4960.  
  4961.     assert( !isDefined( self.tag_stowed_hip ) );
  4962.  
  4963.  
  4964.  
  4965.     stowWeapon = undefined;
  4966.  
  4967.  
  4968.  
  4969.     weaponsList = self getWeaponsListOffhands();
  4970.  
  4971.     foreach ( weaponName in weaponsList )
  4972.  
  4973.     {
  4974.  
  4975.         if ( weaponName == currentWeapon )
  4976.  
  4977.             continue;
  4978.  
  4979.            
  4980.  
  4981.         if ( weaponName != "c4_mp" && weaponName != "claymore_mp" )
  4982.  
  4983.             continue;
  4984.  
  4985.        
  4986.  
  4987.         stowWeapon = weaponName;
  4988.  
  4989.     }
  4990.  
  4991.  
  4992.  
  4993.     if ( !isDefined( stowWeapon ) )
  4994.  
  4995.         return;
  4996.  
  4997.  
  4998.  
  4999.     self.tag_stowed_hip = getWeaponModel( stowWeapon );
  5000.  
  5001.     self attach( self.tag_stowed_hip, "tag_stowed_hip_rear", true );
  5002.  
  5003.  
  5004.  
  5005.     hideTagList = GetWeaponHideTags( stowWeapon );
  5006.  
  5007.    
  5008.  
  5009.     if ( !isDefined( hideTagList ) )
  5010.  
  5011.         return;
  5012.  
  5013.    
  5014.  
  5015.     for ( i = 0; i < hideTagList.size; i++ )
  5016.  
  5017.         self HidePart( hideTagList[ i ], self.tag_stowed_hip );
  5018.  
  5019. }
  5020.  
  5021.  
  5022.  
  5023.  
  5024.  
  5025. updateSavedLastWeapon()
  5026.  
  5027. {
  5028.  
  5029.     self endon( "death" );
  5030.  
  5031.     self endon( "disconnect" );
  5032.  
  5033.  
  5034.  
  5035.     currentWeapon = self.currentWeaponAtSpawn;
  5036.  
  5037.     self.saved_lastWeapon = currentWeapon;
  5038.  
  5039.  
  5040.  
  5041.     for ( ;; )
  5042.  
  5043.     {
  5044.  
  5045.         self waittill( "weapon_change", newWeapon );
  5046.  
  5047.    
  5048.  
  5049.         if ( newWeapon == "none" )
  5050.  
  5051.         {
  5052.  
  5053.             self.saved_lastWeapon = currentWeapon;
  5054.  
  5055.             continue;
  5056.  
  5057.         }
  5058.  
  5059.  
  5060.  
  5061.         weaponInvType = weaponInventoryType( newWeapon );
  5062.  
  5063.  
  5064.  
  5065.         if ( weaponInvType != "primary" && weaponInvType != "altmode" )
  5066.  
  5067.         {
  5068.  
  5069.             self.saved_lastWeapon = currentWeapon;
  5070.  
  5071.             continue;
  5072.  
  5073.         }
  5074.  
  5075.        
  5076.  
  5077.         if ( newWeapon == "onemanarmy_mp" )
  5078.  
  5079.         {
  5080.  
  5081.             self.saved_lastWeapon = currentWeapon;
  5082.  
  5083.             continue;
  5084.  
  5085.         }
  5086.  
  5087.  
  5088.  
  5089.         self updateMoveSpeedScale( "primary" );
  5090.  
  5091.  
  5092.  
  5093.         self.saved_lastWeapon = currentWeapon;
  5094.  
  5095.         currentWeapon = newWeapon;
  5096.  
  5097.     }
  5098.  
  5099. }
  5100.  
  5101.  
  5102.  
  5103.  
  5104.  
  5105. EMPPlayer( numSeconds )
  5106.  
  5107. {
  5108.  
  5109.     self endon( "disconnect" );
  5110.  
  5111.     self endon( "death" );
  5112.  
  5113.  
  5114.  
  5115.     self thread clearEMPOnDeath();
  5116.  
  5117.  
  5118.  
  5119. }
  5120.  
  5121.  
  5122.  
  5123.  
  5124.  
  5125. clearEMPOnDeath()
  5126.  
  5127. {
  5128.  
  5129.     self endon( "disconnect" );
  5130.  
  5131.  
  5132.  
  5133.     self waittill( "death" );
  5134.  
  5135. }
  5136.  
  5137.  
  5138.  
  5139.  
  5140.  
  5141. updateMoveSpeedScale( weaponType )
  5142.  
  5143. {
  5144.  
  5145.     /*
  5146.  
  5147.     if ( self _hasPerk( "specialty_lightweight" ) )
  5148.  
  5149.         self.moveSpeedScaler = 1.10;
  5150.  
  5151.     else
  5152.  
  5153.         self.moveSpeedScaler = 1;
  5154.  
  5155.     */
  5156.  
  5157.    
  5158.  
  5159.     if ( !isDefined( weaponType ) || weaponType == "primary" || weaponType != "secondary" )
  5160.  
  5161.         weaponType = self.primaryWeapon;
  5162.  
  5163.     else
  5164.  
  5165.         weaponType = self.secondaryWeapon;
  5166.  
  5167.    
  5168.  
  5169.     if( isDefined(self.primaryWeapon ) && self.primaryWeapon == "riotshield_mp" )
  5170.  
  5171.     {
  5172.  
  5173.         self setMoveSpeedScale( .8 * self.moveSpeedScaler );
  5174.  
  5175.         return;
  5176.  
  5177.     }
  5178.  
  5179.    
  5180.  
  5181.     if ( !isDefined( weaponType ) )
  5182.  
  5183.         weapClass = "none";
  5184.  
  5185.     else
  5186.  
  5187.         weapClass = weaponClass( weaponType );
  5188.  
  5189.    
  5190.  
  5191.    
  5192.  
  5193.     switch ( weapClass )
  5194.  
  5195.     {
  5196.  
  5197.         case "rifle":
  5198.  
  5199.             self setMoveSpeedScale( 0.95 * self.moveSpeedScaler );
  5200.  
  5201.             break;
  5202.  
  5203.         case "pistol":
  5204.  
  5205.             self setMoveSpeedScale( 1.0 * self.moveSpeedScaler );
  5206.  
  5207.             break;
  5208.  
  5209.         case "mg":
  5210.  
  5211.             self setMoveSpeedScale( 0.875 * self.moveSpeedScaler );
  5212.  
  5213.             break;
  5214.  
  5215.         case "smg":
  5216.  
  5217.             self setMoveSpeedScale( 1.0 * self.moveSpeedScaler );
  5218.  
  5219.             break;
  5220.  
  5221.         case "spread":
  5222.  
  5223.             self setMoveSpeedScale( .95 * self.moveSpeedScaler );
  5224.  
  5225.             break;
  5226.  
  5227.         case "rocketlauncher":
  5228.  
  5229.             self setMoveSpeedScale( 0.80 * self.moveSpeedScaler );
  5230.  
  5231.             break;
  5232.  
  5233.         case "sniper":
  5234.  
  5235.             self setMoveSpeedScale( 1.0 * self.moveSpeedScaler );
  5236.  
  5237.             break;
  5238.  
  5239.         default:
  5240.  
  5241.             self setMoveSpeedScale( 1.0 * self.moveSpeedScaler );
  5242.  
  5243.             break;
  5244.  
  5245.     }
  5246.  
  5247. }
  5248.  
  5249.  
  5250.  
  5251.  
  5252.  
  5253. buildWeaponData( filterPerks )
  5254.  
  5255. {
  5256.  
  5257.     attachmentList = getAttachmentList();      
  5258.  
  5259.     max_weapon_num = 149;
  5260.  
  5261.  
  5262.  
  5263.     baseWeaponData = [];
  5264.  
  5265.    
  5266.  
  5267.     for( weaponId = 0; weaponId <= max_weapon_num; weaponId++ )
  5268.  
  5269.     {
  5270.  
  5271.         baseName = tablelookup( "mp/statstable.csv", 0, weaponId, 4 );
  5272.  
  5273.         if( baseName == "" )
  5274.  
  5275.             continue;
  5276.  
  5277.  
  5278.  
  5279.         assetName = baseName + "_mp";
  5280.  
  5281.  
  5282.  
  5283.         if ( !isSubStr( tableLookup( "mp/statsTable.csv", 0, weaponId, 2 ), "weapon_" ) )
  5284.  
  5285.             continue;
  5286.  
  5287.        
  5288.  
  5289.         if ( weaponInventoryType( assetName ) != "primary" )
  5290.  
  5291.             continue;
  5292.  
  5293.  
  5294.  
  5295.         weaponInfo = spawnStruct();
  5296.  
  5297.         weaponInfo.baseName = baseName;
  5298.  
  5299.         weaponInfo.assetName = assetName;
  5300.  
  5301.         weaponInfo.variants = [];
  5302.  
  5303.  
  5304.  
  5305.         weaponInfo.variants[0] = assetName;
  5306.  
  5307.         // the alphabetize function is slow so we try not to do it for every weapon/attachment combo; a code solution would be better.
  5308.  
  5309.         attachmentNames = [];
  5310.  
  5311.         for ( innerLoopCount = 0; innerLoopCount < 6; innerLoopCount++ )
  5312.  
  5313.         {
  5314.  
  5315.             // generating attachment combinations
  5316.  
  5317.             attachmentName = tablelookup( "mp/statStable.csv", 0, weaponId, innerLoopCount + 11 );
  5318.  
  5319.            
  5320.  
  5321.             if ( filterPerks )
  5322.  
  5323.             {
  5324.  
  5325.                 switch ( attachmentName )
  5326.  
  5327.                 {
  5328.  
  5329.                     case "fmj":
  5330.  
  5331.                     case "xmags":
  5332.  
  5333.                     case "rof":
  5334.  
  5335.                         continue;
  5336.  
  5337.                 }
  5338.  
  5339.             }
  5340.  
  5341.            
  5342.  
  5343.             if( attachmentName == "" )
  5344.  
  5345.                 break;
  5346.  
  5347.            
  5348.  
  5349.             attachmentNames[attachmentName] = true;
  5350.  
  5351.         }
  5352.  
  5353.  
  5354.  
  5355.         // generate an alphabetized attachment list
  5356.  
  5357.         attachments = [];
  5358.  
  5359.         foreach ( attachmentName in attachmentList )
  5360.  
  5361.         {
  5362.  
  5363.             if ( !isDefined( attachmentNames[attachmentName] ) )
  5364.  
  5365.                 continue;
  5366.  
  5367.            
  5368.  
  5369.             weaponInfo.variants[weaponInfo.variants.size] = baseName + "_" + attachmentName + "_mp";
  5370.  
  5371.             attachments[attachments.size] = attachmentName;
  5372.  
  5373.         }
  5374.  
  5375.  
  5376.  
  5377.         for ( i = 0; i < (attachments.size - 1); i++ )
  5378.  
  5379.         {
  5380.  
  5381.             colIndex = tableLookupRowNum( "mp/attachmentCombos.csv", 0, attachments[i] );
  5382.  
  5383.             for ( j = i + 1; j < attachments.size; j++ )
  5384.  
  5385.             {
  5386.  
  5387.                 if ( tableLookup( "mp/attachmentCombos.csv", 0, attachments[j], colIndex ) == "no" )
  5388.  
  5389.                     continue;
  5390.  
  5391.                    
  5392.  
  5393.                 weaponInfo.variants[weaponInfo.variants.size] = baseName + "_" + attachments[i] + "_" + attachments[j] + "_mp";
  5394.  
  5395.             }
  5396.  
  5397.         }
  5398.  
  5399.        
  5400.  
  5401.         baseWeaponData[baseName] = weaponInfo;
  5402.  
  5403.     }
  5404.  
  5405.    
  5406.  
  5407.     return ( baseWeaponData );
  5408.  
  5409. }
  5410.  
  5411.  
  5412.  
  5413. monitorSemtex()
  5414.  
  5415. {
  5416.  
  5417.     self endon( "disconnect" );
  5418.  
  5419.     self endon( "death" );
  5420.  
  5421.    
  5422.  
  5423.     for( ;; )
  5424.  
  5425.     {
  5426.  
  5427.         self waittill( "grenade_fire", weapon );
  5428.  
  5429.  
  5430.  
  5431.         if ( !isSubStr(weapon.model, "semtex" ) )
  5432.  
  5433.             continue;
  5434.  
  5435.            
  5436.  
  5437.         weapon waittill( "missile_stuck", stuckTo );
  5438.  
  5439.            
  5440.  
  5441.         if ( !isPlayer( stuckTo ) )
  5442.  
  5443.             continue;
  5444.  
  5445.            
  5446.  
  5447.         if ( level.teamBased && isDefined( stuckTo.team ) && stuckTo.team == self.team )
  5448.  
  5449.         {
  5450.  
  5451.             weapon.isStuck = "friendly";
  5452.  
  5453.             continue;
  5454.  
  5455.         }
  5456.  
  5457.    
  5458.  
  5459.         weapon.isStuck = "enemy";
  5460.  
  5461.         weapon.stuckEnemyEntity = stuckTo;
  5462.  
  5463.        
  5464.  
  5465.         stuckTo maps\mp\gametypes\_hud_message::playerCardSplashNotify( "semtex_stuck", self );
  5466.  
  5467.        
  5468.  
  5469.         self thread maps\mp\gametypes\_hud_message::SplashNotify( "stuck_semtex", 100 );
  5470.  
  5471.         self notify( "process", "ch_bullseye" );
  5472.  
  5473.     }  
  5474.  
  5475. }
  5476.  
  5477.  
  5478.  
  5479.  
  5480.  
  5481. turret_monitorUse()
  5482.  
  5483. {
  5484.  
  5485.     for( ;; )
  5486.  
  5487.     {
  5488.  
  5489.         self waittill ( "trigger", player );
  5490.  
  5491.        
  5492.  
  5493.         self thread turret_playerThread( player );
  5494.  
  5495.     }
  5496.  
  5497. }
  5498.  
  5499.  
  5500.  
  5501. turret_playerThread( player )
  5502.  
  5503. {
  5504.  
  5505.     player endon ( "death" );
  5506.  
  5507.     player endon ( "disconnect" );
  5508.  
  5509.  
  5510.  
  5511.     player notify ( "weapon_change", "none" );
  5512.  
  5513.    
  5514.  
  5515.     self waittill ( "turret_deactivate" );
  5516.  
  5517.    
  5518.  
  5519.     player notify ( "weapon_change", player getCurrentWeapon() );
  5520.  
  5521. }
RAW Paste Data
Top