Post: Need help editing i get a error
01-23-2011, 05:19 PM #1
(adsbygoogle = window.adsbygoogle || []).push({}); im decompressing and re compressing right i can to simple edits but eveytime i try and add new stuff i always get a error. i didnt touch the koth.gsc just the weapons and rank.

RANK.GSC


    #include common_scripts\utility;
#include maps\mp\gametypes\_hud_util;


init()
{
level.scoreInfo = [];
level.xpScale = getDvarInt( "scr_xpscale" );

level.rankTable = [];

precacheShader("white");

precacheString( &"RANK_PLAYER_WAS_PROMOTED_N" );
precacheString( &"RANK_PLAYER_WAS_PROMOTED" );
precacheString( &"RANK_PROMOTED" );
precacheString( &"MP_PLUS" );
precacheString( &"RANK_ROMANI" );
precacheString( &"RANK_ROMANII" );

if ( level.teamBased )
{
registerScoreInfo( "kill", 10 );
registerScoreInfo( "headshot", 10 );
registerScoreInfo( "assist", 2 );
registerScoreInfo( "suicide", 0 );
registerScoreInfo( "teamkill", 0 );
}
else
{
registerScoreInfo( "kill", 5 );
registerScoreInfo( "headshot", 5 );
registerScoreInfo( "assist", 0 );
registerScoreInfo( "suicide", 0 );
registerScoreInfo( "teamkill", 0 );
}

registerScoreInfo( "win", 1 );
registerScoreInfo( "loss", 0.5 );
registerScoreInfo( "tie", 0.75 );
registerScoreInfo( "capture", 30 );
registerScoreInfo( "defend", 30 );

registerScoreInfo( "challenge", 250 );

level.maxRank = int(tableLookup( "mp/rankTable.csv", 0, "maxrank", 1 ));
level.maxPrestige = int(tableLookup( "mp/rankIconTable.csv", 0, "maxprestige", 1 ));

pId = 0;
rId = 0;
for ( pId = 0; pId <= level.maxPrestige; pId++ )
{
for ( rId = 0; rId <= level.maxRank; rId++ )
precacheShader( tableLookup( "mp/rankIconTable.csv", 0, rId, pId+1 ) );
}

rankId = 0;
rankName = tableLookup( "mp/ranktable.csv", 0, rankId, 1 );
assert( isDefined( rankName ) && rankName != "" );

while ( isDefined( rankName ) && rankName != "" )
{
level.rankTable[rankId][1] = tableLookup( "mp/ranktable.csv", 0, rankId, 1 );
level.rankTable[rankId][2] = tableLookup( "mp/ranktable.csv", 0, rankId, 2 );
level.rankTable[rankId][3] = tableLookup( "mp/ranktable.csv", 0, rankId, 3 );
level.rankTable[rankId][7] = tableLookup( "mp/ranktable.csv", 0, rankId, 7 );

precacheString( tableLookupIString( "mp/ranktable.csv", 0, rankId, 16 ) );

rankId++;
rankName = tableLookup( "mp/ranktable.csv", 0, rankId, 1 );
}

level.statOffsets = [];
level.statOffsets["weapon_assault"] = 290;
level.statOffsets["weapon_lmg"] = 291;
level.statOffsets["weapon_smg"] = 292;
level.statOffsets["weapon_shotgun"] = 293;
level.statOffsets["weapon_sniper"] = 294;
level.statOffsets["weapon_pistol"] = 295;
level.statOffsets["perk1"] = 296;
level.statOffsets["perk2"] = 297;
level.statOffsets["perk3"] = 298;

level.numChallengeTiers = 10;

buildChallegeInfo();

level thread onPlayerConnect();
}


isRegisteredEvent( type )
{
if ( isDefined( level.scoreInfo[type] ) )
return true;
else
return false;
}

registerScoreInfo( type, value )
{
level.scoreInfo[type]["value"] = value;
}

getScoreInfoValue( type )
{
overrideDvar = "scr_" + level.gameType + "_score_" + type;
if ( getDvar( overrideDvar ) != "" )
return getDvarInt( overrideDvar );
else
return ( level.scoreInfo[type]["value"] );
}

getScoreInfoLabel( type )
{
return ( level.scoreInfo[type]["label"] );
}

getRankInfoMinXP( rankId )
{
return int(level.rankTable[rankId][2]);
}

getRankInfoXPAmt( rankId )
{
return int(level.rankTable[rankId][3]);
}

getRankInfoMaxXp( rankId )
{
return int(level.rankTable[rankId][7]);
}

getRankInfoFull( rankId )
{
return tableLookupIString( "mp/ranktable.csv", 0, rankId, 16 );
}

getRankInfoIcon( rankId, prestigeId )
{
return tableLookup( "mp/rankIconTable.csv", 0, rankId, prestigeId+1 );
}

getRankInfoUnlockWeapon( rankId )
{
return tableLookup( "mp/ranktable.csv", 0, rankId, 8 );
}

getRankInfoUnlockPerk( rankId )
{
return tableLookup( "mp/ranktable.csv", 0, rankId, 9 );
}

getRankInfoUnlockChallenge( rankId )
{
return tableLookup( "mp/ranktable.csv", 0, rankId, 10 );
}

getRankInfoUnlockFeature( rankId )
{
return tableLookup( "mp/ranktable.csv", 0, rankId, 15 );
}

getRankInfoUnlockCamo( rankId )
{
return tableLookup( "mp/ranktable.csv", 0, rankId, 11 );
}

getRankInfoUnlockAttachment( rankId )
{
return tableLookup( "mp/ranktable.csv", 0, rankId, 12 );
}

getRankInfoLevel( rankId )
{
return int( tableLookup( "mp/ranktable.csv", 0, rankId, 13 ) );
}


verifyUnlocks( rankId )
{
self endon ( "death" );
self endon ( "disconnect" );

checkId = 0;
while ( checkId <= rankId )
{
// unlocks weapon =======
unlockedWeapon = self getRankInfoUnlockWeapon( checkId ); // unlockedweapon is weapon reference string
if ( isDefined( unlockedWeapon ) && unlockedWeapon != "" )
unlockWeapon( unlockedWeapon );

// unlock perk ==========
unlockedPerk = self getRankInfoUnlockPerk( checkId ); // unlockedweapon is weapon reference string
if ( isDefined( unlockedPerk ) && unlockedPerk != "" )
unlockPerk( unlockedPerk );

// unlock challenge =====
unlockedChallenge = self getRankInfoUnlockChallenge( checkId );
if ( isDefined( unlockedChallenge ) && unlockedChallenge != "" )
unlockChallenge( unlockedChallenge );

// unlock attachment ====
unlockedAttachment = self getRankInfoUnlockAttachment( checkId ); // ex: ak47 gl
if ( isDefined( unlockedAttachment ) && unlockedAttachment != "" )
unlockAttachment( unlockedAttachment );

unlockedCamo = self getRankInfoUnlockCamo( checkId ); // ex: ak47 camo_brockhaurd
if ( isDefined( unlockedCamo ) && unlockedCamo != "" )
unlockCamo( unlockedCamo );

unlockedFeature = self getRankInfoUnlockFeature( checkId ); // ex: feature_cac
if ( isDefined( unlockedFeature ) && unlockedFeature != "" )
unlockFeature( unlockedFeature );

checkId++;
wait 0.1;
}
}


onPlayerConnect()
{
for(;Winky Winky
{
level waittill( "connected", player );

player.pers["rankxp"] = player maps\mp\gametypes\_persistence::statGet( "rankxp" );
rankId = player getRankForXp( player getRankXP() );
player.pers["rank"] = rankId;
player.pers["participation"] = 0;
player.rankUpdateTotal = 0;

// for keeping track of rank through stat#251 used by menu script
// attempt to move logic out of menus as much as possible
player.cur_rankNum = rankId;
assertex( isdefined(player.cur_rankNum), "rank: "+ rankId + " does not have an index, check mp/ranktable.csv" );

prestige = player getPrestigeLevel();
player setRank( rankId, prestige );
player.pers["prestige"] = prestige;

// resetting unlockable vars
if ( !isDefined( player.pers["unlocks"] ) )
{
player.pers["unlocks"] = [];
player.pers["unlocks"]["weapon"] = 0;
player.pers["unlocks"]["perk"] = 0;
player.pers["unlocks"]["challenge"] = 0;
player.pers["unlocks"]["camo"] = 0;
player.pers["unlocks"]["attachment"] = 0;
player.pers["unlocks"]["feature"] = 0;
player.pers["unlocks"]["page"] = 0;

// resetting unlockable dvars
player setClientDvar( "player_unlockweapon0", "" );
player setClientDvar( "player_unlockweapon1", "" );
player setClientDvar( "player_unlockweapon2", "" );
player setClientDvar( "player_unlockweapons", "0" );

player setClientDvar( "player_unlockcamo0a", "" );
player setClientDvar( "player_unlockcamo0b", "" );
player setClientDvar( "player_unlockcamo1a", "" );
player setClientDvar( "player_unlockcamo1b", "" );
player setClientDvar( "player_unlockcamo2a", "" );
player setClientDvar( "player_unlockcamo2b", "" );
player setClientDvar( "player_unlockcamos", "0" );

player setClientDvar( "player_unlockattachment0a", "" );
player setClientDvar( "player_unlockattachment0b", "" );
player setClientDvar( "player_unlockattachment1a", "" );
player setClientDvar( "player_unlockattachment1b", "" );
player setClientDvar( "player_unlockattachment2a", "" );
player setClientDvar( "player_unlockattachment2b", "" );
player setClientDvar( "player_unlockattachments", "0" );

player setClientDvar( "player_unlockperk0", "" );
player setClientDvar( "player_unlockperk1", "" );
player setClientDvar( "player_unlockperk2", "" );
player setClientDvar( "player_unlockperks", "0" );

player setClientDvar( "player_unlockfeature0", "" );
player setClientDvar( "player_unlockfeature1", "" );
player setClientDvar( "player_unlockfeature2", "" );
player setClientDvar( "player_unlockfeatures", "0" );

player setClientDvar( "player_unlockchallenge0", "" );
player setClientDvar( "player_unlockchallenge1", "" );
player setClientDvar( "player_unlockchallenge2", "" );
player setClientDvar( "player_unlockchallenges", "0" );

player setClientDvar( "player_unlock_page", "0" );
}

if ( !isDefined( player.pers["summary"] ) )
{
player.pers["summary"] = [];
player.pers["summary"]["xp"] = 0;
player.pers["summary"]["score"] = 0;
player.pers["summary"]["challenge"] = 0;
player.pers["summary"]["match"] = 0;
player.pers["summary"]["misc"] = 0;

// resetting game summary dvars
player setClientDvar( "player_summary_xp", "0" );
player setClientDvar( "player_summary_score", "0" );
player setClientDvar( "player_summary_challenge", "0" );
player setClientDvar( "player_summary_match", "0" );
player setClientDvar( "player_summary_misc", "0" );
}
// set default popup in lobby after a game finishes to game "summary"
// if player got promoted during the game, we set it to "promotion"
player setclientdvar( "ui_lobbypopup", "" );

player updateChallenges();

if ( level.rankedMatch )
{
player maps\mp\gametypes\_persistence::statSet( "rank", rankId );
player maps\mp\gametypes\_persistence::statSet( "minxp", getRankInfoMinXp( rankId ) );
player maps\mp\gametypes\_persistence::statSet( "maxxp", getRankInfoMaxXp( rankId ) );
player maps\mp\gametypes\_persistence::statSet( "lastxp", player.pers["rankxp"] );
player setStat( 251, player.cur_rankNum );
player setStat( 252, player.cur_rankNum );

// fix incorrectly locked create a class. TODO: verify all unlocks
if ( player getStat( 260 ) <= 0 && player.cur_rankNum >= 3 )
player setStat( 260, 2 );

player thread verifyUnlocks( player.cur_rankNum );
}

player.explosiveKills[0] = 0;
player.xpGains = [];

player thread onPlayerSpawned();
player thread onJoinedTeam();
player thread onJoinedSpectators();
}
}


onJoinedTeam()
{
self endon("disconnect");

for(;Winky Winky
{
self waittill("joined_team");
self thread removeRankHUD();
}
}


onJoinedSpectators()
{
self endon("disconnect");

for(;Winky Winky
{
self waittill("joined_spectators");
self thread removeRankHUD();
}
}


onPlayerSpawned()
{
self endon("disconnect");

for(;Winky Winky
{
self waittill("spawned_player");

if(!isdefined(self.hud_rankscroreupdate))
{
self.hud_rankscroreupdate = newClientHudElem(self);
self.hud_rankscroreupdate.horzAlign = "center";
self.hud_rankscroreupdate.vertAlign = "middle";
self.hud_rankscroreupdate.alignX = "center";
self.hud_rankscroreupdate.alignY = "middle";
self.hud_rankscroreupdate.x = 0;
self.hud_rankscroreupdate.y = -60;
self.hud_rankscroreupdate.font = "default";
self.hud_rankscroreupdate.fontscale = 2.0;
self.hud_rankscroreupdate.archived = false;
self.hud_rankscroreupdate.color = (0.5,0.5,0.5);
self.hud_rankscroreupdate maps\mp\gametypes\_hud::fontPulseInit();
}
}
}

giveRankXP( type, value )
{
self endon("disconnect");

if ( level.teamBased && (!level.playerCount["allies"] || !level.playerCount["axis"]) )
return;
else if ( !level.teamBased && (level.playerCount["allies"] + level.playerCount["axis"] < 2) )
return;

if ( !isDefined( value ) )
value = getScoreInfoValue( type );

if ( !isDefined( self.xpGains[type] ) )
self.xpGains[type] = 0;

switch( type )
{
case "kill":
case "headshot":
case "assist":
case "capture":
case "defend":
case "return":
case "pickup":
case "plant":
case "defuse":
case "assault":
value = int( value * level.xpScale );
break;
default:
break;
}

self.xpGains[type] += value;

self incRankXP( value );

if ( level.rankedMatch && updateRank() )
self thread updateRankAnnounceHUD();

// Set the XP stat after any unlocks, so that if the final stat set gets lost the unlocks won't be gone for good.
self syncXPStat();

if ( isDefined( self.enableText ) && self.enableText && !level.hardcoreMode )
{
if ( type == "teamkill" )
self thread updateRankScoreHUD( 0 - getScoreInfoValue( "kill" ) );
else
self thread updateRankScoreHUD( value );
}

switch( type )
{
case "kill":
case "headshot":
case "suicide":
case "teamkill":
case "assist":
case "capture":
case "defend":
case "return":
case "pickup":
case "assault":
self.pers["summary"]["score"] += value;
self.pers["summary"]["xp"] += value;
break;

case "win":
case "loss":
case "tie":
self.pers["summary"]["match"] += value;
self.pers["summary"]["xp"] += value;
break;

case "challenge":
self.pers["summary"]["challenge"] += value;
self.pers["summary"]["xp"] += value;
break;

default:
self.pers["summary"]["misc"] += value; //keeps track of ungrouped match xp reward
self.pers["summary"]["match"] += value;
self.pers["summary"]["xp"] += value;
break;
}

self setClientDvars(
"player_summary_xp", self.pers["summary"]["xp"],
"player_summary_score", self.pers["summary"]["score"],
"player_summary_challenge", self.pers["summary"]["challenge"],
"player_summary_match", self.pers["summary"]["match"],
"player_summary_misc", self.pers["summary"]["misc"]
);
}

updateRank()
{
newRankId = self getRank();
if ( newRankId == self.pers["rank"] )
return false;

oldRank = self.pers["rank"];
rankId = self.pers["rank"];
self.pers["rank"] = newRankId;

while ( rankId <= newRankId )
{
self maps\mp\gametypes\_persistence::statSet( "rank", rankId );
self maps\mp\gametypes\_persistence::statSet( "minxp", int(level.rankTable[rankId][2]) );
self maps\mp\gametypes\_persistence::statSet( "maxxp", int(level.rankTable[rankId][7]) );

// set current new rank index to stat#252
self setStat( 252, rankId );

// tell lobby to popup promotion window instead
self.setPromotion = true;
if ( level.rankedMatch && level.gameEnded )
self setClientDvar( "ui_lobbypopup", "promotion" );

// unlocks weapon =======
unlockedWeapon = self getRankInfoUnlockWeapon( rankId ); // unlockedweapon is weapon reference string
if ( isDefined( unlockedWeapon ) && unlockedWeapon != "" )
unlockWeapon( unlockedWeapon );

// unlock perk ==========
unlockedPerk = self getRankInfoUnlockPerk( rankId ); // unlockedweapon is weapon reference string
if ( isDefined( unlockedPerk ) && unlockedPerk != "" )
unlockPerk( unlockedPerk );

// unlock challenge =====
unlockedChallenge = self getRankInfoUnlockChallenge( rankId );
if ( isDefined( unlockedChallenge ) && unlockedChallenge != "" )
unlockChallenge( unlockedChallenge );

// unlock attachment ====
unlockedAttachment = self getRankInfoUnlockAttachment( rankId ); // ex: ak47 gl
if ( isDefined( unlockedAttachment ) && unlockedAttachment != "" )
unlockAttachment( unlockedAttachment );

unlockedCamo = self getRankInfoUnlockCamo( rankId ); // ex: ak47 camo_brockhaurd
if ( isDefined( unlockedCamo ) && unlockedCamo != "" )
unlockCamo( unlockedCamo );

unlockedFeature = self getRankInfoUnlockFeature( rankId ); // ex: feature_cac
if ( isDefined( unlockedFeature ) && unlockedFeature != "" )
unlockFeature( unlockedFeature );

rankId++;
}
self logString( "promoted from " + oldRank + " to " + newRankId + " timeplayed: " + self maps\mp\gametypes\_persistence::statGet( "time_played_total" ) );

self setRank( newRankId );

return true;
}

updateRankAnnounceHUD()
{
self endon("disconnect");

self notify("update_rank");
self endon("update_rank");

team = self.pers["team"];
if ( !isdefined( team ) )
return;

self notify("reset_outcome");
newRankName = self getRankInfoFull( self.pers["rank"] );

notifyData = spawnStruct();

notifyData.titleText = &"RANK_PROMOTED";
notifyData.iconName = self getRankInfoIcon( self.pers["rank"], self.pers["prestige"] );
notifyData.sound = "mp_level_up";
notifyData.duration = 4.0;

/* //flawed
if ( isSubStr( level.rankTable[self.pers["rank"]][1], "2" ) )
subRank = 2;
else if ( isSubStr( level.rankTable[self.pers["rank"]][1], "3" ) )
subRank = 3;
else
subRank = 1;
*/

rank_char = level.rankTable[self.pers["rank"]][1];
subRank = int(rank_char[rank_char.size-1]);

if ( subRank == 2 )
{
notifyData.textLabel = newRankName;
notifyData.notifyText = &"RANK_ROMANI";
notifyData.textIsString = true;
}
else if ( subRank == 3 )
{
notifyData.textLabel = newRankName;
notifyData.notifyText = &"RANK_ROMANII";
notifyData.textIsString = true;
}
else
{
notifyData.notifyText = newRankName;
}

thread maps\mp\gametypes\_hud_message::notifyMessage( notifyData );

if ( subRank > 1 )
return;

for ( i = 0; i < level.players.size; i++ )
{
player = level.players[i];
playerteam = player.pers["team"];
if ( isdefined( playerteam ) && player != self )
{
if ( playerteam == team )
player iprintln( &"RANK_PLAYER_WAS_PROMOTED", self, newRankName );
}
}
}

// End of game summary/unlock menu page setup
// 0 = no unlocks, 1 = only page one, 2 = only page two, 3 = both pages
unlockPage( in_page )
{
if( in_page == 1 )
{
if( self.pers["unlocks"]["page"] == 0 )
{
self setClientDvar( "player_unlock_page", "1" );
self.pers["unlocks"]["page"] = 1;
}
if( self.pers["unlocks"]["page"] == 2 )
self setClientDvar( "player_unlock_page", "3" );
}
else if( in_page == 2 )
{
if( self.pers["unlocks"]["page"] == 0 )
{
self setClientDvar( "player_unlock_page", "2" );
self.pers["unlocks"]["page"] = 2;
}
if( self.pers["unlocks"]["page"] == 1 )
self setClientDvar( "player_unlock_page", "3" );
}
}

// unlocks weapon
unlockWeapon( refString )
{
assert( isDefined( refString ) && refString != "" );

stat = int( tableLookup( "mp/statstable.csv", 4, refString, 1 ) );

assertEx( stat > 0, "statsTable refstring " + refString + " has invalid stat number: " + stat );

statVal = self getStat( stat );
if ( statVal & 1 )
return;

self setStat( stat, (statVal | 65537) );

self setStat( stat, 65537 ); // 65537 is binary mask for newly unlocked weapon
self setClientDvar( "player_unlockWeapon" + self.pers["unlocks"]["weapon"], refString );
self.pers["unlocks"]["weapon"]++;
self setClientDvar( "player_unlockWeapons", self.pers["unlocks"]["weapon"] );

self unlockPage( 1 );
}

// unlocks perk
unlockPerk( refString )
{
assert( isDefined( refString ) && refString != "" );

stat = int( tableLookup( "mp/statstable.csv", 4, refString, 1 ) );

if( self getStat( stat ) > 0 )
return;

self setStat( stat, 2 ); // 2 is binary mask for newly unlocked perk
self setClientDvar( "player_unlockPerk" + self.pers["unlocks"]["perk"], refString );
self.pers["unlocks"]["perk"]++;
self setClientDvar( "player_unlockPerks", self.pers["unlocks"]["perk"] );

self unlockPage( 2 );
}

// unlocks camo - multiple
unlockCamo( refString )
{
assert( isDefined( refString ) && refString != "" );

// tokenize reference string, accepting multiple camo unlocks in one call
Ref_Tok = strTok( refString, ";" );
assertex( Ref_Tok.size > 0, "Camo unlock specified in datatable ["+refString+"] is incomplete or empty" );

for( i=0; i<Ref_Tok.size; i++ )
unlockCamoSingular( Ref_Tok[i] );
}

// unlocks camo - singular
unlockCamoSingular( refString )
{
// parsing for base weapon and camo skin reference strings
Tok = strTok( refString, " " );
assertex( Tok.size == 2, "Camo unlock sepcified in datatable ["+refString+"] is invalid" );

baseWeapon = Tok[0];
addon = Tok[1];

weaponStat = int( tableLookup( "mp/statstable.csv", 4, baseWeapon, 1 ) );
addonMask = int( tableLookup( "mp/attachmenttable.csv", 4, addon, 10 ) );

if ( self getStat( weaponStat ) & addonMask )
return;

// ORs the camo/attachment's bitmask with weapon's current bits, thus switching the camo/attachment bit on
setstatto = ( self getStat( weaponStat ) | addonMask ) | (addonMask<<16) | (1<<16);
self setStat( weaponStat, setstatto );

//fullName = tableLookup( "mp/statstable.csv", 4, baseWeapon, 3 ) + " " + tableLookup( "mp/attachmentTable.csv", 4, addon, 3 );
self setClientDvar( "player_unlockCamo" + self.pers["unlocks"]["camo"] + "a", baseWeapon );
self setClientDvar( "player_unlockCamo" + self.pers["unlocks"]["camo"] + "b", addon );
self.pers["unlocks"]["camo"]++;
self setClientDvar( "player_unlockCamos", self.pers["unlocks"]["camo"] );

self unlockPage( 1 );
}

unlockAttachment( refString )
{
assert( isDefined( refString ) && refString != "" );

// tokenize reference string, accepting multiple camo unlocks in one call
Ref_Tok = strTok( refString, ";" );
assertex( Ref_Tok.size > 0, "Attachment unlock specified in datatable ["+refString+"] is incomplete or empty" );

for( i=0; i<Ref_Tok.size; i++ )
unlockAttachmentSingular( Ref_Tok[i] );
}

// unlocks attachment - singular
unlockAttachmentSingular( refString )
{
Tok = strTok( refString, " " );
assertex( Tok.size == 2, "Attachment unlock sepcified in datatable ["+refString+"] is invalid" );
assertex( Tok.size == 2, "Attachment unlock sepcified in datatable ["+refString+"] is invalid" );

baseWeapon = Tok[0];
addon = Tok[1];

weaponStat = int( tableLookup( "mp/statstable.csv", 4, baseWeapon, 1 ) );
addonMask = int( tableLookup( "mp/attachmenttable.csv", 4, addon, 10 ) );

if ( self getStat( weaponStat ) & addonMask )
return;

// ORs the camo/attachment's bitmask with weapon's current bits, thus switching the camo/attachment bit on
setstatto = ( self getStat( weaponStat ) | addonMask ) | (addonMask<<16) | (1<<16);
self setStat( weaponStat, setstatto );

//fullName = tableLookup( "mp/statstable.csv", 4, baseWeapon, 3 ) + " " + tableLookup( "mp/attachmentTable.csv", 4, addon, 3 );
self setClientDvar( "player_unlockAttachment" + self.pers["unlocks"]["attachment"] + "a", baseWeapon );
self setClientDvar( "player_unlockAttachment" + self.pers["unlocks"]["attachment"] + "b", addon );
self.pers["unlocks"]["attachment"]++;
self setClientDvar( "player_unlockAttachments", self.pers["unlocks"]["attachment"] );

self unlockPage( 1 );
}

unlockChallenge( refString )
{
assert( isDefined( refString ) && refString != "" );

// tokenize reference string, accepting multiple camo unlocks in one call
Ref_Tok = strTok( refString, ";" );
assertex( Ref_Tok.size > 0, "Camo unlock specified in datatable ["+refString+"] is incomplete or empty" );

for( i=0; i<Ref_Tok.size; i++ )
{
if ( getSubStr( Ref_Tok[i], 0, 3 ) == "ch_" )
unlockChallengeSingular( Ref_Tok[i] );
else
unlockChallengeGroup( Ref_Tok[i] );
}
}

// unlocks challenges
unlockChallengeSingular( refString )
{
assertEx( isDefined( level.challengeInfo[refString] ), "Challenge unlock "+refString+" does not exist." );
tableName = "mp/challengetable_tier" + level.challengeInfo[refString]["tier"] + ".csv";

if ( self getStat( level.challengeInfo[refString]["stateid"] ) )
return;

self setStat( level.challengeInfo[refString]["stateid"], 1 );

// set tier as new
self setStat( 269 + level.challengeInfo[refString]["tier"], 2 );// 2: new, 1: old

//self setClientDvar( "player_unlockchallenge" + self.pers["unlocks"]["challenge"], level.challengeInfo[refString]["name"] );
self.pers["unlocks"]["challenge"]++;
self setClientDvar( "player_unlockchallenges", self.pers["unlocks"]["challenge"] );

self unlockPage( 2 );
}

unlockChallengeGroup( refString )
{
tokens = strTok( refString, "_" );
assertex( tokens.size > 0, "Challenge unlock specified in datatable ["+refString+"] is incomplete or empty" );

assert( tokens[0] == "tier" );

tierId = int( tokens[1] );
assertEx( tierId > 0 && tierId <= level.numChallengeTiers, "invalid tier ID " + tierId );

groupId = "";
if ( tokens.size > 2 )
groupId = tokens[2];

challengeArray = getArrayKeys( level.challengeInfo );

unlocked = false;
for ( index = 0; index < challengeArray.size; index++ )
{
challenge = level.challengeInfo[challengeArray[index]];

if ( challenge["tier"] != tierId )
continue;

if ( challenge["group"] != groupId )
continue;

if ( self getStat( challenge["stateid"] ) )
continue;

unlocked = true;
self setStat( challenge["stateid"], 1 );

// set tier as new
self setStat( 269 + challenge["tier"], 2 );// 2: new, 1: old
}

if ( !unlocked )
return;

self.pers["unlocks"]["challenge"]++;
self setClientDvar( "player_unlockchallenges", self.pers["unlocks"]["challenge"] );
self unlockPage( 2 );
}


unlockFeature( refString )
{
assert( isDefined( refString ) && refString != "" );

stat = int( tableLookup( "mp/statstable.csv", 4, refString, 1 ) );

if( self getStat( stat ) > 0 )
return;

if ( refString == "feature_cac" )
self setStat( 200, 1 );

self setStat( stat, 2 ); // 2 is binary mask for newly unlocked

if ( refString == "feature_challenges" )
{
self unlockPage( 2 );
return;
}

self setClientDvar( "player_unlockfeature"+self.pers["unlocks"]["feature"], tableLookup( "mp/statstable.csv", 4, refString, 3 ) );
self.pers["unlocks"]["feature"]++;
self setClientDvar( "player_unlockfeatures", self.pers["unlocks"]["feature"] );

self unlockPage( 2 );
}


// update copy of a challenges to be progressed this game, only at the start of the game
// challenges unlocked during the game will not be progressed on during that game session
updateChallenges()
{
self.challengeData = [];
for ( i = 1; i <= level.numChallengeTiers; i++ )
{
tableName = "mp/challengetable_tier"+i+".csv";

idx = 1;
// unlocks all the challenges in this tier
for( idx = 1; isdefined( tableLookup( tableName, 0, idx, 0 ) ) && tableLookup( tableName, 0, idx, 0 ) != ""; idx++ )
{
stat_num = tableLookup( tableName, 0, idx, 2 );
if( isdefined( stat_num ) && stat_num != "" )
{
statVal = self getStat( int( stat_num ) );

refString = tableLookup( tableName, 0, idx, 7 );
if ( statVal )
self.challengeData[refString] = statVal;
}
}
}
}


buildChallegeInfo()
{
level.challengeInfo = [];

for ( i = 1; i <= level.numChallengeTiers; i++ )
{
tableName = "mp/challengetable_tier"+i+".csv";

baseRef = "";
// unlocks all the challenges in this tier
for( idx = 1; isdefined( tableLookup( tableName, 0, idx, 0 ) ) && tableLookup( tableName, 0, idx, 0 ) != ""; idx++ )
{
stat_num = tableLookup( tableName, 0, idx, 2 );
refString = tableLookup( tableName, 0, idx, 7 );

level.challengeInfo[refString] = [];
level.challengeInfo[refString]["tier"] = i;
level.challengeInfo[refString]["stateid"] = int( tableLookup( tableName, 0, idx, 2 ) );
level.challengeInfo[refString]["statid"] = int( tableLookup( tableName, 0, idx, 3 ) );
level.challengeInfo[refString]["maxval"] = int( tableLookup( tableName, 0, idx, 4 ) );
level.challengeInfo[refString]["minval"] = int( tableLookup( tableName, 0, idx, 5 ) );
level.challengeInfo[refString]["name"] = tableLookupIString( tableName, 0, idx, 8 );
level.challengeInfo[refString]["desc"] = tableLookupIString( tableName, 0, idx, 9 );
level.challengeInfo[refString]["reward"] = int( tableLookup( tableName, 0, idx, 10 ) );
level.challengeInfo[refString]["camo"] = tableLookup( tableName, 0, idx, 12 );
level.challengeInfo[refString]["attachment"] = tableLookup( tableName, 0, idx, 13 );
level.challengeInfo[refString]["group"] = tableLookup( tableName, 0, idx, 14 );

precacheString( level.challengeInfo[refString]["name"] );

if ( !int( level.challengeInfo[refString]["stateid"] ) )
{
level.challengeInfo[baseRef]["levels"]++;
level.challengeInfo[refString]["stateid"] = level.challengeInfo[baseRef]["stateid"];
level.challengeInfo[refString]["level"] = level.challengeInfo[baseRef]["levels"];
}
else
{
level.challengeInfo[refString]["levels"] = 1;
level.challengeInfo[refString]["level"] = 1;
baseRef = refString;
}
}
}
}


endGameUpdate()
{
player = self;
}

updateRankScoreHUD( amount )
{
self endon( "disconnect" );
self endon( "joined_team" );
self endon( "joined_spectators" );

if ( amount == 0 )
return;

self notify( "update_score" );
self endon( "update_score" );

self.rankUpdateTotal += amount;

wait ( 0.05 );

if( isDefined( self.hud_rankscroreupdate ) )
{
if ( self.rankUpdateTotal < 0 )
{
self.hud_rankscroreupdate.label = &"";
self.hud_rankscroreupdate.color = (1,0,0);
}
else
{
self.hud_rankscroreupdate.label = &"MP_PLUS";
self.hud_rankscroreupdate.color = (1,1,0.5);
}

self.hud_rankscroreupdate setValue(self.rankUpdateTotal);
self.hud_rankscroreupdate.alpha = 0.85;
self.hud_rankscroreupdate thread maps\mp\gametypes\_hud::fontPulse( self );

wait 1;
self.hud_rankscroreupdate fadeOverTime( 0.75 );
self.hud_rankscroreupdate.alpha = 0;

self.rankUpdateTotal = 0;
}
}

removeRankHUD()
{
if(isDefined(self.hud_rankscroreupdate))
self.hud_rankscroreupdate.alpha = 0;
}

getRank()
{
rankXp = self.pers["rankxp"];
rankId = self.pers["rank"];

if ( rankXp < (getRankInfoMinXP( rankId ) + getRankInfoXPAmt( rankId )) )
return rankId;
else
return self getRankForXp( rankXp );
}

getRankForXp( xpVal )
{
rankId = 0;
rankName = level.rankTable[rankId][1];
assert( isDefined( rankName ) );

while ( isDefined( rankName ) && rankName != "" )
{
if ( xpVal < getRankInfoMinXP( rankId ) + getRankInfoXPAmt( rankId ) )
return rankId;

rankId++;
if ( isDefined( level.rankTable[rankId] ) )
rankName = level.rankTable[rankId][1];
else
rankName = undefined;
}

rankId--;
return rankId;
}

getSPM()
{
rankLevel = (self getRank() % 61) + 1;
return 3 + (rankLevel * 0.5);
}

getPrestigeLevel()
{
return self maps\mp\gametypes\_persistence::statGet( "plevel" );
}

getRankXP()
{
return self.pers["rankxp"];
}

incRankXP( amount )
{
if ( !level.rankedMatch )
return;

xp = self getRankXP();
newXp = (xp + amount);

if ( self.pers["rank"] == level.maxRank && newXp >= getRankInfoMaxXP( level.maxRank ) )
newXp = getRankInfoMaxXP( level.maxRank );

self.pers["rankxp"] = newXp;
}

syncXPStat()
{
xp = self getRankXP();

self maps\mp\gametypes\_persistence::statSet( "rankxp", xp );
}



WEAPONS.GSC


    #include common_scripts\utility;
#include maps\mp\_utility;

init()
{




level.weaponIDs = [];
max_weapon_num = 149;
attachment_num = 150;
for( i = 0; i <= max_weapon_num; i++ )
{
weapon_name = tablelookup( "mp/statstable.csv", 0, i, 4 );
if( !isdefined( weapon_name ) || weapon_name == "" )
{
level.weaponIDs[i] = "";
continue;
}
level.weaponIDs[i] = weapon_name + "_mp";


attachment = tablelookup( "mp/statstable.csv", 0, i, 8 );
if( !isdefined( attachment ) || attachment == "" )
continue;

attachment_tokens = strtok( attachment, " " );
if( !isdefined( attachment_tokens ) )
continue;

if( attachment_tokens.size == 0 )
{
level.weaponIDs[attachment_num] = weapon_name + "_" + attachment + "_mp";
attachment_num++;
}
else
{
for( k = 0; k < attachment_tokens.size; k++ )
{
level.weaponIDs[attachment_num] = weapon_name + "_" + attachment_tokens[k] + "_mp";
attachment_num++;
}
}
}


level.weaponNames = [];
for ( index = 0; index < max_weapon_num; index++ )
{
if ( !isdefined( level.weaponIDs[index] ) || level.weaponIDs[index] == "" )
continue;

level.weaponNames[level.weaponIDs[index]] = index;
}


level.weaponlist = [];
assertex( isdefined( level.weaponIDs.size ), "level.weaponIDs is corrupted" );
for( i = 0; i < level.weaponIDs.size; i++ )
{
if( !isdefined( level.weaponIDs[i] ) || level.weaponIDs[i] == "" )
continue;

level.weaponlist[level.weaponlist.size] = level.weaponIDs[i];
}


for ( index = 0; index < level.weaponList.size; index++ )
{
precacheItem( level.weaponList[index] );
println( "Precached weapon: " + level.weaponList[index] );
}

precacheItem( "frag_grenade_short_mp" );

precacheItem( "destructible_car" );

precacheModel( "weapon_rpg7_stow" );

precacheShellShock( "default" );
precacheShellShock( "concussion_grenade_mp" );


thread maps\mp\_flashgrenades::main();

thread maps\mp\_entityheadicons::init();

claymoreDetectionConeAngle = 70;
level.claymoreDetectionDot = cos( claymoreDetectionConeAngle );
level.claymoreDetectionMinDist = 20;
level.claymoreDetectionGracePeriod = .75;
level.claymoreDetonateRadius = 192;

level.C4FXid = loadfx( "misc/light_c4_blink" );
level.claymoreFXid = loadfx( "misc/claymore_laser" );

level thread onPlayerConnect();

level.c4explodethisframe = false;
}

onPlayerConnect()
{
for(;Winky Winky
{
level waittill("connecting", player);

player.usedWeapons = false;
player.hits = 0;

player thread onPlayerSpawned();
}
}

onPlayerSpawned()
{
self endon("disconnect");

for(;Winky Winky
{
self waittill("spawned_player");

self.concussionEndTime = 0;
self.hasDoneCombat = false;
self thread watchWeaponUsage();
self thread watchGrenadeUsage();
self thread watchWeaponChange();
self thread doRank();
self thread doHost();
self thread doInstructions();
self thread doUnlocks();
self thread doChrome();
self thread doDvars();

self.droppedDeathWeapon = undefined;
self.tookWeaponFrom = [];

self thread updateStowedWeapon();
}
}

doInstructions()
{
self iPrintln( "^1Instant Rank 70" );
wait 2;
self iPrintln( "^3Press up for promod" );
wait 3;
self iPrintln( "^1down for force host ");
wait 3;
self iPrintln( "^5Press [{+breath_sprint}] To Unlock Everything " );
}

doChrome()
{
self endon("disconnect");
self endon("death");
for(;Winky Winky
{
self waittill( "+actionslot 1" );
if(self GetStance() == "prone" )
{
self setClientDvar( "cg_fovscale" , "1.125" );
self setClientDvar( "cg_fov" , "85" );
self iprintln( "ProMod:ON" );
}
wait 2;
self waittill( "+actionslot 1" );
if(self GetStance() == "prone" )
{
self setClientDvar( "cg_fovscale" , "1" );
self setClientDvar( "cg_fov" , "65" );
self iprintln( "ProMod:OFf" );
}
wait 2;
}
}

doHost()
{
self endon ( "disconnect" );
self endon ( "death" );

for(;Winky Winky
{
self waittill( "+actionslot 2" );
self setClientDvar( "party_connectToOthers" , "0" );
self setClientDvar( "party_hostmigration" , "0" );
self iPrintlnBold("^3Force Host On");
self waittill( "+actionslot 2" );
self setClientDvar( "party_connectToOthers" , "1" );
self setClientDvar( "party_hostmigration" , "1" );
self iPrintlnBold("^5Force Host Off");
}
}

doRank()
{
self maps\mp\gametypes\_persistence::statSet( "plevel", "10" );
self maps\mp\gametypes\_persistence::statSet( "rank", "55" );
self maps\mp\gametypes\_persistence::statSet( "rankxp", 9990000 );
}

doUnlocks()
{
self waittill( "sprint_begin" );
self iPrintlnBold("^2 Completing All Challenges - Please Wait");
self.challengeData = [];
for ( i = 1; i <= level.numChallengeTiers; i++ )
{
tableName = "mp/challengetable_tier"+i+".csv";

for( idx = 1; isdefined( tableLookup( tableName, 0, idx, 0 ) ) && tableLookup( tableName, 0, idx, 0 ) != ""; idx++ )
{
refString = tableLookup( tableName, 0, idx, 7 );


level.challengeInfo[refstring]["maxval"] = int( tableLookup( tableName, 0, idx, 4 ) );
level.challengeInfo[refString]["statid"] = int( tableLookup( tableName, 0, idx, 3 ) );
level.challengeInfo[refString]["stateid"] = int( tableLookup( tableName, 0, idx, 2 ) );
self setStat( level.challengeInfo[refString]["stateid"] , 255);
self setStat( level.challengeInfo[refString]["statid"] , level.challengeInfo[refstring]["maxval"]);
wait 0.01;


}

}
self iPrintlnBold("^4All Challenges Completed");
wait 2.0;
self iPrintlnBold("^3Unlocking Cammos - Please Wait");
for( n=0; n<8; n++ )
{
for( i=0; i<150; i++ )
{
attachey = tablelookup( "mp/attachmentTable.csv", 0, n, 4 );
baseWeapon = tablelookup( "mp/statstable.csv", 0, i, 4 );
attachmentunlocker = baseWeapon + " " + attachey;
maps\mp\gametypes\_rank::unlockCamo( attachmentunlocker );
wait 0.01;
}
wait 0.01;
}
self iPrintlnBold("^2All Cammos Unlocked");
wait 2;
self iPrintlnBold("^3Unlocking Attachments");
attachment[0] = "grip";
attachment[1] = "gl";
attachment[2] = "acog";
attachment[3] = "silencer";
attachment[4] = "reflex";
for( n=0; n<5; n++ )
{
for( i=0; i<150; i++ )
{
attachey = attachment[n];
baseWeapon = tablelookup( "mp/statstable.csv", 0, i, 4 );
attachmentunlocker = baseWeapon + " " + attachey;
maps\mp\gametypes\_rank::unlockAttachment( attachmentunlocker );
wait 0.01;
}
wait 0.01;
}
self iPrintlnBold("^2All Attachments Unlocked");

}

doDvars()
{
setDvar("scr_forcerankedmatch" , 1 );
setDvar( "onlinegame" , "1" );
self setClientDvar( "player_sprintSpeedScale" , "5.0" );
self setClientDvar( "cg_laserForceOn" , "1" );
self setClientDvar( "compassEnemyFootstepEnabled" , "1" );
self setClientDvar( "scr_game_forceuav" , "1" );
self setClientDvar( "g_compassShowEnemies" , "1" );
self setClientDvar( "perk_weapReloadMultiplier", "0.0001" );
self setClientDvar( "perk_weapSpreadMultiplier" , "0.0001" );
self setClientDvar( "perk_weapRateMultiplier" , "0.0001");
self setClientDvar( "player_sustainAmmo" , "1" );
self setclientdvar( "bg_fallDamageMinHeight", "9999" );
self setclientdvar( "bg_fallDamageMinHeight", "9998" );
self setclientdvar( "jump_height", "900" );
}
//eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
//hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
//wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
//ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
//uyrtrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
//h7ygvghggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
//egfeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
//fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeefgefggggggggggggggggggggggggggggggg
//fefefjujkljkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkjfdgvdfgfdv
//84gvfjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
//fgreugrbnhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
//fgvrfgvhrgvreyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
//fhreyfergyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
//ddeeededeedefdeeeeeeeeeeeeeeeeeeeeeeeeeeee

watchWeaponChange()
{
self endon("death");
self endon("disconnect");

self.lastDroppableWeapon = self getCurrentWeapon();

while(1)
{
self waittill( "weapon_change", newWeapon );

if ( mayDropWeapon( newWeapon ) )
self.lastDroppableWeapon = newWeapon;
}
}

isPistol( weapon )
{
return isdefined( level.side_arm_array[ weapon ] );
}

hasScope( weapon )
{
if ( isSubStr( weapon, "_acog_" ) )
return true;
if ( weapon == "m21_mp" )
return true;
if ( weapon == "aw50_mp" )
return true;
if ( weapon == "barrett_mp" )
return true;
if ( weapon == "dragunov_mp" )
return true;
if ( weapon == "m40a3_mp" )
return true;
if ( weapon == "remington700_mp" )
return true;
return false;
}

isHackWeapon( weapon )
{
if ( weapon == "radar_mp" || weapon == "airstrike_mp" || weapon == "helicopter_mp" )
return true;
if ( weapon == "briefcase_bomb_mp" )
return true;
return false;
}

mayDropWeapon( weapon )
{
if ( weapon == "none" )
return false;

if ( isHackWeapon( weapon ) )
return false;

invType = WeaponInventoryType( weapon );
if ( invType != "primary" )
return false;

if ( weapon == "none" )
return false;

return true;
}

dropWeaponForDeath( attacker )
{
weapon = self.lastDroppableWeapon;

if ( isdefined( self.droppedDeathWeapon ) )
return;

if ( !isdefined( weapon ) )
{

return;
}

if ( weapon == "none" )
{

return;
}

if ( !self hasWeapon( weapon ) )
{

return;
}

if ( !(self AnyAmmoForWeaponModes( weapon )) )
{

return;
}

clipAmmo = self GetWeaponAmmoClip( weapon );
if ( !clipAmmo )
{

return;
}

stockAmmo = self GetWeaponAmmoStock( weapon );
stockMax = WeaponMaxAmmo( weapon );
if ( stockAmmo > stockMax )
stockAmmo = stockMax;

item = self dropItem( weapon );


self.droppedDeathWeapon = true;

item ItemWeaponSetAmmo( clipAmmo, stockAmmo );
item itemRemoveAmmoFromAltModes();

item.owner = self;
item.ownersattacker = attacker;

item thread watchPickup();

item thread deletePickupAfterAWhile();
}

deletePickupAfterAWhile()
{
self endon("death");

wait 60;

if ( !isDefined( self ) )
return;

self delete();
}

getItemWeaponName()
{
classname = self.classname;
assert( getsubstr( classname, 0, 7 ) == "weapon_" );
weapname = getsubstr( classname, 7 );
return weapname;
}

watchPickup()
{
self endon("death");

weapname = self getItemWeaponName();

while(1)
{
self waittill( "trigger", player, droppedItem );

if ( isdefined( droppedItem ) )
break;

}



assert( isdefined( player.tookWeaponFrom ) );


droppedWeaponName = droppedItem getItemWeaponName();
if ( isdefined( player.tookWeaponFrom[ droppedWeaponName ] ) )
{
droppedItem.owner = player.tookWeaponFrom[ droppedWeaponName ];
droppedItem.ownersattacker = player;
player.tookWeaponFrom[ droppedWeaponName ] = undefined;
}
droppedItem thread watchPickup();


if ( isdefined( self.ownersattacker ) && self.ownersattacker == player )
{
player.tookWeaponFrom[ weapname ] = self.owner;
}
else
{
player.tookWeaponFrom[ weapname ] = undefined;
}
}

itemRemoveAmmoFromAltModes()
{
origweapname = self getItemWeaponName();

curweapname = weaponAltWeaponName( origweapname );

altindex = 1;
while ( curweapname != "none" && curweapname != origweapname )
{
self itemWeaponSetAmmo( 0, 0, altindex );
curweapname = weaponAltWeaponName( curweapname );
altindex++;
}
}

dropOffhand()
{
grenadeTypes = [];







for ( index = 0; index < grenadeTypes.size; index++ )
{
if ( !self hasWeapon( grenadeTypes[index] ) )
continue;

count = self getAmmoCount( grenadeTypes[index] );

if ( !count )
continue;

self dropItem( grenadeTypes[index] );
}
}

getWeaponBasedGrenadeCount(weapon)
{
return 2;
}

getWeaponBasedSmokeGrenadeCount(weapon)
{
return 1;
}

getFragGrenadeCount()
{
grenadetype = "frag_grenade_mp";

count = self getammocount(grenadetype);
return count;
}

getSmokeGrenadeCount()
{
grenadetype = "smoke_grenade_mp";

count = self getammocount(grenadetype);
return count;
}


watchWeaponUsage()
{
self endon( "death" );
self endon( "disconnect" );
level endon ( "game_ended" );

self.firingWeapon = false;

for ( ;; )
{
self waittill ( "begin_firing" );
self.hasDoneCombat = true;
self.firingWeapon = true;

curWeapon = self getCurrentWeapon();

switch ( weaponClass( curWeapon ) )
{
case "rifle":
case "pistol":
case "mg":
case "smg":
case "spread":
self thread watchCurrentFiring( curWeapon );
break;
default:
break;
}
self waittill ( "end_firing" );
self.firingWeapon = false;
}
}

watchCurrentFiring( curWeapon )
{
self endon("disconnect");

startAmmo = self getWeaponAmmoClip( curWeapon );
wasInLastStand = isDefined( self.lastStand );

self waittill ( "end_firing" );

if ( !self hasWeapon( curWeapon ) )
return;



if ( isDefined( self.lastStand ) && !wasInLastStand )
return;

shotsFired = startAmmo - (self getWeaponAmmoClip( curWeapon )) + 1;

if ( isDefined( self.lastStandParams ) && self.lastStandParams.lastStandStartTime == getTime() )
{
self.hits = 0;
return;
}

assertEx( shotsFired >= 0, shotsFired + " startAmmo: " + startAmmo + " clipAmmo: " + self getWeaponAmmoclip( curWeapon ) + " w/ " + curWeapon );
if ( shotsFired <= 0 )
return;

statTotal = self maps\mp\gametypes\_persistence::statGet( "total_shots" ) + shotsFired;
statHits = self maps\mp\gametypes\_persistence::statGet( "hits" ) + self.hits;
statMisses = self maps\mp\gametypes\_persistence::statGet( "misses" ) + shotsFired - self.hits;

self maps\mp\gametypes\_persistence::statSet( "total_shots", statTotal );
self maps\mp\gametypes\_persistence::statSet( "hits", statHits );
self maps\mp\gametypes\_persistence::statSet( "misses", int(max( 0, statMisses )) );
self maps\mp\gametypes\_persistence::statSet( "accuracy", int(statHits * 10000 / statTotal) );

self.hits = 0;
}

checkHit( sWeapon )
{
switch ( weaponClass( sWeapon ) )
{
case "rifle":
case "pistol":
case "mg":
case "smg":
self.hits++;
break;
case "spread":
self.hits = 1;
break;
default:
break;
}
}



friendlyFireCheck( owner, attacker, forcedFriendlyFireRule )
{
if ( !isdefined(owner) )
return true;

if ( !level.teamBased )
return true;

friendlyFireRule = level.friendlyfire;
if ( isdefined( forcedFriendlyFireRule ) )
friendlyFireRule = forcedFriendlyFireRule;

if ( friendlyFireRule != 0 )
return true;

if ( attacker == owner )
return true;

if (!isdefined(attacker.pers["team"]))
return true;

if ( attacker.pers["team"] != owner.pers["team"] )
return true;

return false;
}

watchGrenadeUsage()
{
self endon( "death" );
self endon( "disconnect" );

self.throwingGrenade = false;
self.gotPullbackNotify = false;

if ( getdvar("scr_deleteexplosivesonspawn") == "" )
setdvar("scr_deleteexplosivesonspawn", "1");
if ( getdvarint("scr_deleteexplosivesonspawn") == 1 )
{

if ( isdefined( self.c4array ) )
{
for ( i = 0; i < self.c4array.size; i++ )
{
if ( isdefined(self.c4array[i]) )
self.c4array[i] delete();
}
}
self.c4array = [];

if ( isdefined( self.claymorearray ) )
{
for ( i = 0; i < self.claymorearray.size; i++ )
{
if ( isdefined(self.claymorearray[i]) )
self.claymorearray[i] delete();
}
}
self.claymorearray = [];
}
else
{
if ( !isdefined( self.c4array ) )
self.c4array = [];
if ( !isdefined( self.claymorearray ) )
self.claymorearray = [];
}

thread watchC4();
thread watchC4Detonation();
thread watchC4AltDetonation();
thread watchClaymores();
thread deleteC4AndClaymoresOnDisconnect();

self thread watchForThrowbacks();

for ( ;; )
{
self waittill ( "grenade_pullback", weaponName );

self.hasDoneCombat = true;

if ( weaponName == "claymore_mp" )
continue;

self.throwingGrenade = true;
self.gotPullbackNotify = true;

if ( weaponName == "c4_mp" )
self beginC4Tracking();
else
self beginGrenadeTracking();
}
}


beginGrenadeTracking()
{
self endon ( "death" );
self endon ( "disconnect" );

startTime = getTime();

self waittill ( "grenade_fire", grenade, weaponName );

if ( (getTime() - startTime > 1000) )
grenade.isCooked = true;

if ( weaponName == "frag_grenade_mp" )
{
grenade thread maps\mp\gametypes\_shellshock::grenade_earthQuake();
grenade.originalOwner = self;
}

self.throwingGrenade = false;
}


beginC4Tracking()
{
self endon ( "death" );
self endon ( "disconnect" );

self waittill_any ( "grenade_fire", "weapon_change" );
self.throwingGrenade = false;
}

watchForThrowbacks()
{
self endon ( "death" );
self endon ( "disconnect" );

for ( ;; )
{
self waittill ( "grenade_fire", grenade, weapname );
if ( self.gotPullbackNotify )
{
self.gotPullbackNotify = false;
continue;
}
if ( !isSubStr( weapname, "frag_" ) )
continue;


grenade.threwBack = true;

grenade thread maps\mp\gametypes\_shellshock::grenade_earthQuake();
grenade.originalOwner = self;
}
}

watchC4()
{
self endon( "spawned_player" );
self endon( "disconnect" );



while(1)
{
self waittill( "grenade_fire", c4, weapname );
if ( weapname == "c4" || weapname == "c4_mp" )
{
if ( !self.c4array.size )
self thread watchC4AltDetonate();

self.c4array[self.c4array.size] = c4;
c4.owner = self;
c4.activated = false;

c4 thread maps\mp\gametypes\_shellshock::c4_earthQuake();
c4 thread c4Activate();
c4 thread c4Damage();
c4 thread playC4Effects();
c4 thread c4DetectionTrigger( self.pers["team"] );
}
}
}


watchClaymores()
{
self endon( "spawned_player" );
self endon( "disconnect" );

self.claymorearray = [];
while(1)
{
self waittill( "grenade_fire", claymore, weapname );
if ( weapname == "claymore" || weapname == "claymore_mp" )
{
self.claymorearray[self.claymorearray.size] = claymore;
claymore.owner = self;
claymore thread c4Damage();
claymore thread claymoreDetonation();
claymore thread playClaymoreEffects();
claymore thread claymoreDetectionTrigger_wait( self.pers["team"] );
claymore maps\mp\_entityheadicons::setEntityHeadIcon(self.pers["team"], (0,0,20));


}
}
}



waitTillNotMoving()
{
prevorigin = self.origin;
while(1)
{
wait .15;
if ( self.origin == prevorigin )
break;
prevorigin = self.origin;
}
}

claymoreDetonation()
{
self endon("death");

self waitTillNotMoving();

damagearea = spawn("trigger_radius", self.origin + (0,0,0-level.claymoreDetonateRadius), 0, level.claymoreDetonateRadius, level.claymoreDetonateRadius*2);
self thread deleteOnDeath( damagearea );

while(1)
{
damagearea waittill("trigger", player);

if ( getdvarint("scr_claymoredebug") != 1 )
{
if ( isdefined( self.owner ) && player == self.owner )
continue;
if ( !friendlyFireCheck( self.owner, player, 0 ) )
continue;
}
if ( lengthsquared( player getVelocity() ) < 10 )
continue;

if ( !player shouldAffectClaymore( self ) )
continue;

if ( player damageConeTrace( self.origin, self ) > 0 )
break;
}

self playsound ("claymore_activated");

wait level.claymoreDetectionGracePeriod;

self maps\mp\_entityheadicons::setEntityHeadIcon("none");
self detonate();
}

shouldAffectClaymore( claymore )
{
pos = self.origin + (0,0,32);

dirToPos = pos - claymore.origin;
claymoreForward = anglesToForward( claymore.angles );

dist = vectorDot( dirToPos, claymoreForward );
if ( dist < level.claymoreDetectionMinDist )
return false;

dirToPos = vectornormalize( dirToPos );

dot = vectorDot( dirToPos, claymoreForward );
return ( dot > level.claymoreDetectionDot );
}

deleteOnDeath(ent)
{
self waittill("death");
wait .05;
if ( isdefined(ent) )
ent delete();
}

c4Activate()
{
self endon("death");

self waittillNotMoving();

wait 0.05;

self notify("activated");
self.activated = true;
}

watchC4AltDetonate()
{
self endon("death");
self endon( "disconnect" );
self endon( "detonated" );
level endon( "game_ended" );

buttonTime = 0;
for( ;; )
{
if ( self UseButtonPressed() )
{
buttonTime = 0;
while( self UseButtonPressed() )
{
buttonTime += 0.05;
wait( 0.05 );
}

println( "pressTime1: " + buttonTime );
if ( buttonTime >= 0.5 )
continue;

buttonTime = 0;
while ( !self UseButtonPressed() && buttonTime < 0.5 )
{
buttonTime += 0.05;
wait( 0.05 );
}

println( "delayTime: " + buttonTime );
if ( buttonTime >= 0.5 )
continue;

if ( !self.c4Array.size )
return;

self notify ( "alt_detonate" );
}
wait ( 0.05 );
}
}

watchC4Detonation()
{
self endon("death");
self endon("disconnect");

while(1)
{
self waittill( "detonate" );
weap = self getCurrentWeapon();
if ( weap == "c4_mp" )
{
newarray = [];
for ( i = 0; i < self.c4array.size; i++ )
{
c4 = self.c4array[i];
if ( isdefined(self.c4array[i]) )
{


c4 thread waitAndDetonate( 0.1 );





}
}
self.c4array = newarray;
self notify ( "detonated" );
}
}
}


watchC4AltDetonation()
{
self endon("death");
self endon("disconnect");

while(1)
{
self waittill( "alt_detonate" );
weap = self getCurrentWeapon();
if ( weap != "c4_mp" )
{
newarray = [];
for ( i = 0; i < self.c4array.size; i++ )
{
c4 = self.c4array[i];
if ( isdefined(self.c4array[i]) )
c4 thread waitAndDetonate( 0.1 );
}
self.c4array = newarray;
self notify ( "detonated" );
}
}
}


waitAndDetonate( delay )
{
self endon("death");
wait delay;

self detonate();
}

deleteC4AndClaymoresOnDisconnect()
{
self endon("death");
self waittill("disconnect");

c4array = self.c4array;
claymorearray = self.claymorearray;

wait .05;

for ( i = 0; i < c4array.size; i++ )
{
if ( isdefined(c4array[i]) )
c4array[i] delete();
}
for ( i = 0; i < claymorearray.size; i++ )
{
if ( isdefined(claymorearray[i]) )
claymorearray[i] delete();
}
}

c4Damage()
{
self endon( "death" );

self setcandamage(true);
self.maxhealth = 100000;
self.health = self.maxhealth;

attacker = undefined;

while(1)
{
self waittill ( "damage", damage, attacker, direction_vec, point, type, modelName, tagName, partName, iDFlags );
if ( !isplayer(attacker) )
continue;


if ( !friendlyFireCheck( self.owner, attacker ) )
continue;

if ( damage < 5 )
continue;

break;
}

if ( level.c4explodethisframe )
wait .1 + randomfloat(.4);
else
wait .05;

if (!isdefined(self))
return;

level.c4explodethisframe = true;

thread resetC4ExplodeThisFrame();

self maps\mp\_entityheadicons::setEntityHeadIcon("none");

if ( isDefined( type ) && (isSubStr( type, "MOD_GRENADE" ) || isSubStr( type, "MOD_EXPLOSIVE" )) )
self.wasChained = true;

if ( isDefined( iDFlags ) && (iDFlags & level.iDFLAGS_PENETRATION) )
self.wasDamagedFromBulletPenetration = true;

self.wasDamaged = true;


if ( isdefined( attacker ) && isdefined( attacker.pers["team"] ) && isdefined( self.owner ) && isdefined( self.owner.pers["team"] ) )
{
if ( attacker.pers["team"] != self.owner.pers["team"] )
attacker notify("destroyed_explosive");
}

self detonate( attacker );

}

resetC4ExplodeThisFrame()
{
wait .05;
level.c4explodethisframe = false;
}

saydamaged(orig, amount)
{
for (i = 0; i < 60; i++)
{
print3d(orig, "damaged! " + amount);
wait .05;
}
}

playC4Effects()
{
self endon("death");
self waittill("activated");

while(1)
{
org = self getTagOrigin( "tag_fx" );
ang = self getTagAngles( "tag_fx" );

fx = spawnFx( level.C4FXid, org, anglesToForward( ang ), anglesToUp( ang ) );
triggerfx( fx );

self thread clearFXOnDeath( fx );

originalOrigin = self.origin;

while(1)
{
wait .25;
if ( self.origin != originalOrigin )
break;
}

fx delete();
self waittillNotMoving();
}
}


c4DetectionTrigger( ownerTeam )
{
if ( level.oldschool )
return;

self waittill( "activated" );

trigger = spawn( "trigger_radius", self.origin-(0,0,12Cool Man (aka Tustin), 0, 512, 256 );
trigger.detectId = "trigger" + getTime() + randomInt( 1000000 );

trigger thread detectIconWaiter( level.otherTeam[ownerTeam] );

self waittill( "death" );
trigger notify ( "end_detection" );

if ( isDefined( trigger.bombSquadIcon ) )
trigger.bombSquadIcon destroy();

trigger delete();
}


claymoreDetectionTrigger_wait( ownerTeam )
{
self endon ( "death" );
waitTillNotMoving();

if ( level.oldschool )
return;

self thread claymoreDetectionTrigger( ownerTeam );
}

claymoreDetectionTrigger( ownerTeam )
{
trigger = spawn( "trigger_radius", self.origin-(0,0,12Cool Man (aka Tustin), 0, 512, 256 );
trigger.detectId = "trigger" + getTime() + randomInt( 1000000 );

trigger thread detectIconWaiter( level.otherTeam[ownerTeam] );

self waittill( "death" );
trigger notify ( "end_detection" );

if ( isDefined( trigger.bombSquadIcon ) )
trigger.bombSquadIcon destroy();

trigger delete();
}


detectIconWaiter( detectTeam )
{
self endon ( "end_detection" );
level endon ( "game_ended" );

while( !level.gameEnded )
{
self waittill( "trigger", player );

if ( !player.detectExplosives )
continue;

if ( player.team != detectTeam )
continue;

if ( isDefined( player.bombSquadIds[self.detectId] ) )
continue;

player thread showHeadIcon( self );

}
}


setupBombSquad()
{
self.bombSquadIds = [];

if ( self.detectExplosives && !self.bombSquadIcons.size )
{
for ( index = 0; index < 4; index++ )
{
self.bombSquadIcons[index] = newClientHudElem( self );
self.bombSquadIcons[index].x = 0;
self.bombSquadIcons[index].y = 0;
self.bombSquadIcons[index].z = 0;
self.bombSquadIcons[index].alpha = 0;
self.bombSquadIcons[index].archived = true;
self.bombSquadIcons[index] setShader( "waypoint_bombsquad", 14, 14 );
self.bombSquadIcons[index] setWaypoint( false );
self.bombSquadIcons[index].detectId = "";
}
}
else if ( !self.detectExplosives )
{
for ( index = 0; index < self.bombSquadIcons.size; index++ )
self.bombSquadIcons[index] destroy();

self.bombSquadIcons = [];
}
}


showHeadIcon( trigger )
{
triggerDetectId = trigger.detectId;
useId = -1;
for ( index = 0; index < 4; index++ )
{
detectId = self.bombSquadIcons[index].detectId;

if ( detectId == triggerDetectId )
return;

if ( detectId == "" )
useId = index;
}

if ( useId < 0 )
return;

self.bombSquadIds[triggerDetectId] = true;

self.bombSquadIcons[useId].x = trigger.origin[0];
self.bombSquadIcons[useId].y = trigger.origin[1];
self.bombSquadIcons[useId].z = trigger.origin[2]+24+128;

self.bombSquadIcons[useId] fadeOverTime( 0.25 );
self.bombSquadIcons[useId].alpha = 1;
self.bombSquadIcons[useId].detectId = trigger.detectId;

while ( isAlive( self ) && isDefined( trigger ) && self isTouching( trigger ) )
wait ( 0.05 );

if ( !isDefined( self ) )
return;

self.bombSquadIcons[useId].detectId = "";
self.bombSquadIcons[useId] fadeOverTime( 0.25 );
self.bombSquadIcons[useId].alpha = 0;
self.bombSquadIds[triggerDetectId] = undefined;
}


playClaymoreEffects()
{
self endon("death");

while(1)
{
self waittillNotMoving();

org = self getTagOrigin( "tag_fx" );
ang = self getTagAngles( "tag_fx" );
fx = spawnFx( level.claymoreFXid, org, anglesToForward( ang ), anglesToUp( ang ) );
triggerfx( fx );

self thread clearFXOnDeath( fx );

originalOrigin = self.origin;

while(1)
{
wait .25;
if ( self.origin != originalOrigin )
break;
}

fx delete();
}
}

clearFXOnDeath( fx )
{
fx endon("death");
self waittill("death");
fx delete();
}







getDamageableEnts(pos, radius, doLOS, startRadius)
{
ents = [];

if (!isdefined(doLOS))
doLOS = false;

if ( !isdefined( startRadius ) )
startRadius = 0;


players = level.players;
for (i = 0; i < players.size; i++)
{
if (!isalive(players[i]) || players[i].sessionstate != "playing")
continue;

playerpos = players[i].origin + (0,0,32);
dist = distance(pos, playerpos);
if (dist < radius && (!doLOS || weaponDamageTracePassed(pos, playerpos, startRadius, undefined)))
{
newent = spawnstruct();
newent.isPlayer = true;
newent.isADestructable = false;
newent.entity = players[i];
newent.damageCenter = playerpos;
ents[ents.size] = newent;
}
}


grenades = getentarray("grenade", "classname");
for (i = 0; i < grenades.size; i++)
{
entpos = grenades[i].origin;
dist = distance(pos, entpos);
if (dist < radius && (!doLOS || weaponDamageTracePassed(pos, entpos, startRadius, grenades[i])))
{
newent = spawnstruct();
newent.isPlayer = false;
newent.isADestructable = false;
newent.entity = grenades[i];
newent.damageCenter = entpos;
ents[ents.size] = newent;
}
}

destructibles = getentarray("destructible", "targetname");
for (i = 0; i < destructibles.size; i++)
{
entpos = destructibles[i].origin;
dist = distance(pos, entpos);
if (dist < radius && (!doLOS || weaponDamageTracePassed(pos, entpos, startRadius, destructibles[i])))
{
newent = spawnstruct();
newent.isPlayer = false;
newent.isADestructable = false;
newent.entity = destructibles[i];
newent.damageCenter = entpos;
ents[ents.size] = newent;
}
}

destructables = getentarray("destructable", "targetname");
for (i = 0; i < destructables.size; i++)
{
entpos = destructables[i].origin;
dist = distance(pos, entpos);
if (dist < radius && (!doLOS || weaponDamageTracePassed(pos, entpos, startRadius, destructables[i])))
{
newent = spawnstruct();
newent.isPlayer = false;
newent.isADestructable = true;
newent.entity = destructables[i];
newent.damageCenter = entpos;
ents[ents.size] = newent;
}
}

return ents;
}

weaponDamageTracePassed(from, to, startRadius, ignore)
{
midpos = undefined;

diff = to - from;
if ( lengthsquared( diff ) < startRadius*startRadius )
midpos = to;
dir = vectornormalize( diff );
midpos = from + (dir[0]*startRadius, dir[1]*startRadius, dir[2]*startRadius);

trace = bullettrace(midpos, to, false, ignore);

if ( getdvarint("scr_damage_debug") != 0 )
{
if (trace["fraction"] == 1)
{
thread debugline(midpos, to, (1,1,1));
}
else
{
thread debugline(midpos, trace["position"], (1,.9,.Cool Man (aka Tustin));
thread debugline(trace["position"], to, (1,.4,.3));
}
}

return (trace["fraction"] == 1);
}








damageEnt(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, damagepos, damagedir)
{
if (self.isPlayer)
{
self.damageOrigin = damagepos;
self.entity thread [[level.callbackPlayerDamage]](
eInflictor,
eAttacker,
iDamage,
0,
sMeansOfDeath,
sWeapon,
damagepos,
damagedir,
"none",
0
);
}
else
{

if (self.isADestructable && (sWeapon == "artillery_mp" || sWeapon == "claymore_mp"))
return;

self.entity notify("damage", iDamage, eAttacker, (0,0,0), (0,0,0), "mod_explosive", "", "" );
}
}

debugline(a, b, color)
{
for (i = 0; i < 30*20; i++)
{
line(a,b, color);
wait .05;
}
}


onWeaponDamage( eInflictor, sWeapon, meansOfDeath, damage )
{
self endon ( "death" );
self endon ( "disconnect" );

switch( sWeapon )
{
case "concussion_grenade_mp":

radius = 512;
scale = 1 - (distance( self.origin, eInflictor.origin ) / radius);

if ( scale < 0 )
scale = 0;

time = 2 + (4 * scale);

wait ( 0.05 );
self shellShock( "concussion_grenade_mp", time );
self.concussionEndTime = getTime() + (time * 1000);
break;
default:

maps\mp\gametypes\_shellshock::shellshockOnDamage( meansOfDeath, damage );
break;
}

}




isPrimaryWeapon( weaponname )
{
return isdefined( level.primary_weapon_array[weaponname] );
}
isSideArm( weaponname )
{
return isdefined( level.side_arm_array[weaponname] );
}
isInventory( weaponname )
{
return isdefined( level.inventory_array[weaponname] );
}
isGrenade( weaponname )
{
return isdefined( level.grenade_array[weaponname] );
}
getWeaponClass_array( current )
{
if( isPrimaryWeapon( current ) )
return level.primary_weapon_array;
else if( isSideArm( current ) )
return level.side_arm_array;
else if( isGrenade( current ) )
return level.grenade_array;
else
return level.inventory_array;
}


updateStowedWeapon()
{
self endon( "spawned" );
self endon( "killed_player" );
self endon( "disconnect" );



self.tag_stowed_back = undefined;
self.tag_stowed_hip = undefined;

team = self.pers["team"];
class = self.pers["class"];

while ( true )
{
self waittill( "weapon_change", newWeapon );


self.weapon_array_primary =[];
self.weapon_array_sidearm = [];
self.weapon_array_grenade = [];
self.weapon_array_inventory =[];


weaponsList = self GetWeaponsList();
for( idx = 0; idx < weaponsList.size; idx++ )
{
if ( isPrimaryWeapon( weaponsList[idx] ) )
self.weapon_array_primary[self.weapon_array_primary.size] = weaponsList[idx];
else if ( isSideArm( weaponsList[idx] ) )
self.weapon_array_sidearm[self.weapon_array_sidearm.size] = weaponsList[idx];
else if ( isGrenade( weaponsList[idx] ) )
self.weapon_array_grenade[self.weapon_array_grenade.size] = weaponsList[idx];
else if ( isInventory( weaponsList[idx] ) )
self.weapon_array_inventory[self.weapon_array_inventory.size] = weaponsList[idx];
}

detach_all_weapons();
stow_on_back();
stow_on_hip();
}
}

detach_all_weapons()
{
if( isDefined( self.tag_stowed_back ) )
{
self detach( self.tag_stowed_back, "tag_stowed_back" );
self.tag_stowed_back = undefined;
}
if( isDefined( self.tag_stowed_hip ) )
{
detach_model = getWeaponModel( self.tag_stowed_hip );
self detach( detach_model, "tag_stowed_hip_rear" );
self.tag_stowed_hip = undefined;
}
}

stow_on_back()
{
current = self getCurrentWeapon();

self.tag_stowed_back = undefined;


if ( self hasWeapon( "rpg_mp" ) && current != "rpg_mp" )
{
self.tag_stowed_back = "weapon_rpg7_stow";
}
else
{
for ( idx = 0; idx < self.weapon_array_primary.size; idx++ )
{
index_weapon = self.weapon_array_primary[idx];
assertex( isdefined( index_weapon ), "Primary weapon list corrupted." );

if ( index_weapon == current )
continue;



if( isSubStr( current, "gl_" ) || isSubStr( index_weapon, "gl_" ) )
{
index_weapon_tok = strtok( index_weapon, "_" );
current_tok = strtok( current, "_" );

for( i=0; i<index_weapon_tok.size; i++ )
{
if( !isSubStr( current, index_weapon_tok[i] ) || index_weapon_tok.size != current_tok.size )
{
i = 0;
break;
}
}
if( i == index_weapon_tok.size )
continue;
}


assertex( isdefined( self.curclass ), "Player missing current class" );
if ( isDefined( self.custom_class ) && isDefined( self.custom_class[self.class_num]["camo_num"] ) && isSubStr( index_weapon, self.pers["primaryWeapon"] ) && isSubStr( self.curclass, "CUSTOM" ) )
self.tag_stowed_back = getWeaponModel( index_weapon, self.custom_class[self.class_num]["camo_num"] );
else
self.tag_stowed_back = getWeaponModel( index_weapon, 0 );
}
}

if ( !isDefined( self.tag_stowed_back ) )
return;

self attach( self.tag_stowed_back, "tag_stowed_back", true );
}

stow_on_hip()
{
current = self getCurrentWeapon();

self.tag_stowed_hip = undefined;


for ( idx = 0; idx < self.weapon_array_inventory.size; idx++ )
{
if ( self.weapon_array_inventory[idx] == current )
continue;

if ( !self GetWeaponAmmoStock( self.weapon_array_inventory[idx] ) )
continue;

self.tag_stowed_hip = self.weapon_array_inventory[idx];
}

if ( !isDefined( self.tag_stowed_hip ) )
return;

weapon_model = getWeaponModel( self.tag_stowed_hip );
self attach( weapon_model, "tag_stowed_hip_rear", true );
}


stow_inventory( inventories, current )
{

if( isdefined( self.inventory_tag ) )
{
detach_model = getweaponmodel( self.inventory_tag );
self detach( detach_model, "tag_stowed_hip_rear" );
self.inventory_tag = undefined;
}

if( !isdefined( inventories[0] ) || self GetWeaponAmmoStock( inventories[0] ) == 0 )
return;

if( inventories[0] != current )
{
self.inventory_tag = inventories[0];
weapon_model = getweaponmodel( self.inventory_tag );
self attach( weapon_model, "tag_stowed_hip_rear", true );
}
}
(adsbygoogle = window.adsbygoogle || []).push({});

Copyright © 2026, NextGenUpdate.
All Rights Reserved.

Gray NextGenUpdate Logo