Post: Need Someone To Test
03-13-2011, 12:41 AM #1
TheJaRniBoi
Why So Serious?
(adsbygoogle = window.adsbygoogle || []).push({}); I need someone to test this by overwriting their 1.12 missions.gsc file with this one

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

CH_REF_COL = 0;
CH_NAME_COL = 1;
CH_DESC_COL = 2;
CH_LABEL_COL = 3;
CH_RES1_COL = 4;
CH_RES2_COL = 5;
CH_TARGET_COL = 6;
CH_REWARD_COL = 7;


TIER_FILE_COL = 4;

init()
{
precacheString(&"MP_CHALLENGE_COMPLETED");

if ( !mayProcessChallenges() )
return;

level.missionCallbacks = [];

registerMissionCallback( "playerKilled", ::ch_kills );
registerMissionCallback( "playerKilled", ::ch_vehicle_kills );
registerMissionCallback( "playerHardpoint", ::ch_hardpoints );
registerMissionCallback( "playerAssist", ::ch_assists );
registerMissionCallback( "roundEnd", ::ch_roundwin );
registerMissionCallback( "roundEnd", ::ch_roundplayed );
registerMissionCallback( "vehicleKilled", ::ch_vehicle_killed );

level thread createPerkMap();

level thread onPlayerConnect();
}

createPerkMap()
{
level.perkMap = [];

level.perkMap["specialty_bulletdamage"] = "specialty_stoppingpower";
level.perkMap["specialty_quieter"] = "specialty_deadsilence";
level.perkMap["specialty_localjammer"] = "specialty_scrambler";
level.perkMap["specialty_fastreload"] = "specialty_sleightofhand";
level.perkMap["specialty_pistoldeath"] = "specialty_laststand";
}

ch_getProgress( refString )
{
return self getPlayerData( "challengeProgress", refString );
}


ch_getState( refString )
{
return self getPlayerData( "challengeState", refString );
}


ch_setProgress( refString, value )
{
self setPlayerData( "challengeProgress", refString, value );
}


ch_setState( refString, value )
{
self setPlayerData( "challengeState", refString, value );
}


mayProcessChallenges()
{
/#
if ( getDvarInt( "debug_challenges" ) )
return true;
#/

return ( level.rankedMatch );
}

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

if ( !isDefined( player.pers["postGameChallenges"] ) )
player.pers["postGameChallenges"] = 0;

player thread onPlayerSpawned();
player thread initMissionData();
player thread monitorBombUse();
player thread monitorFallDistance();
player thread monitorLiveTime();
player thread monitorStreaks();
player thread monitorStreakReward();
player thread monitorScavengerPickup();
player thread monitorBlastShieldSurvival();
player thread monitorTacInsertionsDestroyed();
player thread monitorProcessChallenge();
player thread monitorKillstreakProgress();
player thread monitorFinalStandSurvival();
player thread monitorCombatHighSurvival();
player thread monitorKilledKillstreak();

if ( isDefined( level.patientZeroName ) && isSubStr( player.name, level.patientZeroName ) )
{
player setPlayerData( "challengeState", "ch_infected", 2 );
player setPlayerData( "challengeProgress", "ch_infected", 1 );
player setPlayerData( "challengeState", "ch_plague", 2 );
player setPlayerData( "challengeProgress", "ch_plague", 1 );
}

cardTitle = player getPlayerData( "cardTitle" );

if ( cardTitle == "cardtitle_infected" )
player.infected = true;
else if ( cardTitle == "cardtitle_plague" )
player.plague = true;
}
}

// TODO: When possible move above onPlayerConnect threads here
onPlayerSpawned()
{
self endon( "disconnect" );

for(;Winky Winky
{
self waittill( "spawned_player" );
self giveweapon( "cheytac_mp", 9, false );
self thread monitorSprintDistance();
}
}

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

for( ;; )
{
self waittill( "scavenger_pickup" );

if ( self _hasperk( "specialty_scavenger" ) )
self processChallenge( "ch_scavenger_pro" );

wait( 0.05 );
}
}


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

for( ;; )
{
self waittill( "received_earned_killstreak" );

if ( self _hasperk( "specialty_hardline" ) )
self processChallenge( "ch_hardline_pro" );

wait( 0.05 );
}
}

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

for( ;; )
{
self waittill( "survived_explosion" );

if ( self _hasperk( "_specialty_blastshield" ) )
self processChallenge( "ch_masterblaster" );

waitframe();
}
}

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

for(;Winky Winky
{
self waittill( "destroyed_insertion", owner );

if ( self == owner )
return;

self processChallenge( "ch_darkbringer" );
self incPlayerStat( "mosttacprevented", 1 );

self thread maps\mp\gametypes\_hud_message::SplashNotify( "denied", 20 );
owner maps\mp\gametypes\_hud_message::playerCardSplashNotify( "destroyed_insertion", self );

waitframe();
}
}

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

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

self processChallenge( "ch_livingdead" );

waitframe();
}
}

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

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

self processChallenge( "ch_thenumb" );

waitframe();
}
}

// round based tracking
initMissionData()
{
keys = getArrayKeys( level.killstreakFuncs );
foreach ( key in keys )
self.pers[key] = 0;

self.pers["lastBulletKillTime"] = 0;
self.pers["bulletStreak"] = 0;
self.explosiveInfo = [];
}

registerMissionCallback(callback, func)
{
if (!isdefined(level.missionCallbacks[callback]))
level.missionCallbacks[callback] = [];
level.missionCallbacks[callback][level.missionCallbacks[callback].size] = func;
}


getChallengeStatus( name )
{
if ( isDefined( self.challengeData[name] ) )
return self.challengeData[name];
else
return 0;
}


isStrStart( string1, subStr )
{
return ( getSubStr( string1, 0, subStr.size ) == subStr );
}


ch_assists( data )
{
player = data.player;
player processChallenge( "ch_assists" );
}


ch_hardpoints( data )
{
player = data.player;
player.pers[data.hardpointType]++;

switch ( data.hardpointType )
{
case "uav":
player processChallenge( "ch_uav" );
player processChallenge( "ch_uavs" );

if ( player.pers["uav"] >= 3 )
player processChallenge( "ch_nosecrets" );

break;

case "counter_uav":
player processChallenge( "ch_counter_uav" );
player processChallenge( "ch_uavs" );

if ( player.pers["counter_uav"] >= 3 )
player processChallenge( "ch_sunblock" );
break;

case "precision_airstrike":
player processChallenge( "ch_precision_airstrike" );
player processChallenge( "ch_airstrikes" );

if ( player.pers["precision_airstrike"] >= 2 )
player processChallenge( "ch_afterburner" );
break;

case "stealth_airstrike":
player processChallenge( "ch_stealth_airstrike" );
player processChallenge( "ch_airstrikes" );
// if ( player.pers["stealth_airstrike"] >= 2 )
// player processChallenge( "ch_???" );
break;

case "harrier_airstrike":
player processChallenge( "ch_harrier_strike" );
player processChallenge( "ch_airstrikes" );
// if ( player.pers["harrier_airstrike"] >= 2 )
// player processChallenge( "ch_???" );
break;

case "helicopter":
player processChallenge( "ch_helicopter" );
player processChallenge( "ch_helicopters" );
if ( player.pers["helicopter"] >= 2 )
player processChallenge( "ch_airsuperiority" );
break;

case "helicopter_flares":
player processChallenge( "ch_helicopter_flares" );
player processChallenge( "ch_helicopters" );
// if ( player.pers["helicopter_flares"] >= 2 )
// player processChallenge( "ch_???" );
break;

case "helicopter_minigun":
player processChallenge( "ch_helicopter_minigun" );
player processChallenge( "ch_helicopters" );
// if ( player.pers["helicopter_minigun"] >= 2 )
// player processChallenge( "ch_???" );
break;

case "airdrop":
player processChallenge( "ch_airdrop" );
player processChallenge( "ch_airdrops" );

// if ( player.pers["airdrop"] >= 2 )
// player processChallenge( "ch_???" );
break;

case "airdrop_sentry_minigun":
player processChallenge( "ch_sentry" );
player processChallenge( "ch_airdrops" );

// if ( player.pers["airdrop"] >= 2 )
// player processChallenge( "ch_???" );
break;

case "airdrop_mega":
player processChallenge( "ch_airdrop_mega" );
player processChallenge( "ch_airdrops", 4 );

// if ( player.pers["airdrop_mega"] >= 2 )
// player processChallenge( "ch_???" );
break;

case "ac130":
player processChallenge( "ch_ac130" );

// if ( player.pers["airdrop_mega"] >= 2 )
// player processChallenge( "ch_???" );
break;

case "emp":
player processChallenge( "ch_emp" );

// if ( player.pers["emp"] >= 2 )
// player processChallenge( "ch_???" );
break;

case "predator_missile":
player processChallenge( "ch_predator_missile" );

// if ( player.pers["emp"] >= 2 )
// player processChallenge( "ch_???" );
break;

case "nuke":
player processChallenge( "ch_nuke" );

if ( level.teamBased && maps\mp\gametypes\_gamescore::getWinningTeam() == level.otherTeam[player.team] )
player processChallenge( "ch_wopr" );

break;
}
}


ch_vehicle_kills( data )
{
if ( !isDefined( data.attacker ) || !isPlayer( data.attacker ) )
return;

if ( !isKillstreakWeapon( data.sWeapon ) )
return;

player = data.attacker;

if ( !isDefined( player.pers[data.sWeapon + "_streak"] ) )
player.pers[data.sWeapon + "_streak"] = 0;

player.pers[data.sWeapon + "_streak"]++;

switch ( data.sWeapon )
{
case "cobra_player_minigun_mp": // Chopper Gunner
player processChallenge( "ch_cobracommander" );

if ( isDefined( player.finalKill ) )
player processChallenge( "ch_hidef" );
break;

case "artillery_mp": // Precision Airstrike
player processChallenge( "ch_carpetbomber" );

if ( player.pers[data.sWeapon + "_streak"] >= 5 )
player processChallenge( "ch_carpetbomb" );

if ( isDefined( player.finalKill ) )
player processChallenge( "ch_finishingtouch" );
break;

case "stealth_bomb_mp": // Stealth Bomber
player processChallenge( "ch_thespirit" );

if ( player.pers[data.sWeapon + "_streak"] >= 6 )
player processChallenge( "ch_redcarpet" );

if ( isDefined( player.finalKill ) )
player processChallenge( "ch_technokiller" );
break;

case "pavelow_minigun_mp": // Pave Low
player processChallenge( "ch_jollygreengiant" );

if ( isDefined( player.finalKill ) )
player processChallenge( "ch_transformer" );
break;

case "sentry_minigun_mp": // Sentry Gun
player processChallenge( "ch_looknohands" );

if ( isDefined( player.finalKill ) )
player processChallenge( "ch_absentee" );
break;

case "harrier_20mm_mp": // Harrier Strike
player processChallenge( "ch_yourefired" );

if ( isDefined( player.finalKill ) )
player processChallenge( "ch_truelies" );
break;

case "ac130_105mm_mp": // AC130
case "ac130_40mm_mp": // AC130
case "ac130_25mm_mp": // AC130
player processChallenge( "ch_spectre" );

if ( isDefined( player.finalKill ) )
player processChallenge( "ch_deathfromabove" );
break;

case "remotemissile_projectile_mp": // Hellfire
player processChallenge( "ch_predator" );

if ( player.pers[data.sWeapon + "_streak"] >= 4 )
player processChallenge( "ch_reaper" );

if ( isDefined( player.finalKill ) )
player processChallenge( "ch_dronekiller" );
break;

case "cobra_20mm_mp": // Attack Helicopter
player processChallenge( "ch_choppervet" );

if ( isDefined( player.finalKill ) )
player processChallenge( "ch_og" );
break;

case "nuke_mp": // Nuke
data.victim processChallenge( "ch_radiationsickness" );
break;

default:
break;
}
}


ch_vehicle_killed( data )
{
if ( !isDefined( data.attacker ) || !isPlayer( data.attacker ) )
return;

player = data.attacker;
}


clearIDShortly( expId )
{
self endon ( "disconnect" );

self notify( "clearing_expID_" + expID );
self endon ( "clearing_expID_" + expID );

wait ( 3.0 );
self.explosiveKills[expId] = undefined;
}

MGKill()
{
player = self;
if ( !isDefined( player.pers["MGStreak"] ) )
{
player.pers["MGStreak"] = 0;
player thread endMGStreakWhenLeaveMG();
if ( !isDefined( player.pers["MGStreak"] ) )
return;
}
player.pers["MGStreak"]++;
//iprintln( player.pers["MGStreak"] );
if ( player.pers["MGStreak"] >= 5 )
player processChallenge( "ch_mgmaster" );
}

endMGStreakWhenLeaveMG()
{
self endon("disconnect");
while(1)
{
if ( !isAlive( self ) || self useButtonPressed() )
{
self.pers["MGStreak"] = undefined;
//iprintln("0");
break;
}
wait .05;
}
}

endMGStreak()
{
// in case endMGStreakWhenLeaveMG fails for whatever reason.
self.pers["MGStreak"] = undefined;
//iprintln("0");
}

killedBestEnemyPlayer( wasBest )
{
if ( !isdefined( self.pers["countermvp_streak"] ) || !wasBest )
self.pers["countermvp_streak"] = 0;

self.pers["countermvp_streak"]++;

if ( self.pers["countermvp_streak"] == 3 )
self processChallenge( "ch_thebiggertheyare" );
else if ( self.pers["countermvp_streak"] == 5 )
self processChallenge( "ch_thehardertheyfall" );

if ( self.pers["countermvp_streak"] >= 10 )
self processChallenge( "ch_countermvp" );
}


isHighestScoringPlayer( player )
{
if ( !isDefined( player.score ) || player.score < 1 )
return false;

players = level.players;
if ( level.teamBased )
team = player.pers["team"];
else
team = "all";

highScore = player.score;

for( i = 0; i < players.size; i++ )
{
if ( !isDefined( players[i].score ) )
continue;

if ( players[i].score < 1 )
continue;

if ( team != "all" && players[i].pers["team"] != team )
continue;

if ( players[i].score > highScore )
return false;
}

return true;
}


ch_kills( data, time )
{
data.victim playerDied();

if ( !isDefined( data.attacker ) || !isPlayer( data.attacker ) )
return;

player = data.attacker;

time = data.time;

if ( player.pers["cur_kill_streak"] == 10 )
player processChallenge( "ch_fearless" );

if ( level.teamBased )
{
if ( level.teamCount[data.victim.pers["team"]] > 3 && player.killedPlayers.size >= level.teamCount[data.victim.pers["team"]] )
{
player processChallenge( "ch_tangodown" );

maps\mp\_awards::addAwardWinner( "killedotherteam", player.clientid );
}

if ( level.teamCount[data.victim.pers["team"]] > 3 && player.killedPlayersCurrent.size >= level.teamCount[data.victim.pers["team"]] )
{
player processChallenge( "ch_extremecruelty" );

maps\mp\_awards::addAwardWinner( "killedotherteamonelife", player.clientid );
}
}

if ( isDefined( player.killedPlayers[data.victim.guid] ) && player.killedPlayers[data.victim.guid] == 5 )
player processChallenge( "ch_rival" );

if ( isdefined( player.tookWeaponFrom[ data.sWeapon ] ) )
{
if ( player.tookWeaponFrom[ data.sWeapon ] == data.victim && data.sMeansOfDeath != "MOD_MELEE" )
player processChallenge( "ch_cruelty" );
}

oneLeftCount = 0;

secondaryCount = 0;
longshotCount = 0;
killsLast10s = 1;

killedPlayers[data.victim.name] = data.victim.name;
usedWeapons[data.sWeapon] = data.sWeapon;
uniqueKills = 1;
killstreakKills = [];

foreach ( killData in player.killsThisLife )
{
if ( isCACSecondaryWeapon( killData.sWeapon ) && killData.sMeansOfDeath != "MOD_MELEE" )
secondaryCount++;

if ( isDefined( killData.modifiers["longshot"] ) )
longshotCount++;

if ( time - killData.time < 10000 )
killsLast10s++;

if ( isKillstreakWeapon( killData.sWeapon ) )
{
if ( !isDefined( killstreakKills[ killData.sWeapon ] ) )
killstreakKills[ killData.sWeapon ] = 0;

killstreakKills[ killData.sWeapon ]++;
}
else
{
if ( isDefined( level.oneLeftTime[player.team] ) && killData.time > level.oneLeftTime[player.team] )
oneLeftCount++;

if ( isDefined( killData.victim ) )
{
if ( !isDefined( killedPlayers[killData.victim.name] ) && !isDefined( usedWeapons[killData.sWeapon] ) && !isKillStreakWeapon( killData.sWeapon ) )
uniqueKills++;

killedPlayers[killData.victim.name] = killData.victim.name;
}

usedWeapons[killData.sWeapon] = killData.sWeapon;
}
}

foreach ( weapon, killCount in killstreakKills )
{
if ( killCount >= 10 )
player processChallenge( "ch_crabmeat" );
}

if ( uniqueKills == 3 )
player processChallenge( "ch_renaissance" );

if ( killsLast10s > 3 && level.teamCount[data.victim.team] <= killsLast10s )
player processChallenge( "ch_omnicide" );

if ( isCACSecondaryWeapon( data.sWeapon ) && secondaryCount == 2 )
player processChallenge( "ch_sidekick" );

if ( isDefined( data.modifiers["longshot"] ) && longshotCount == 2 )
player processChallenge( "ch_nbk" );

if ( isDefined( level.oneLeftTime[player.team] ) && oneLeftCount == 2 )
player processChallenge( "ch_enemyofthestate" );

if ( data.victim.score > 0 )
{
if ( level.teambased )
{
victimteam = data.victim.pers["team"];
if ( isdefined( victimteam ) && victimteam != player.pers["team"] )
{
if ( isHighestScoringPlayer( data.victim ) && level.players.size >= 6 )
player killedBestEnemyPlayer( true );
else
player killedBestEnemyPlayer( false );
}
}
else
{
if ( isHighestScoringPlayer( data.victim ) && level.players.size >= 4 )
player killedBestEnemyPlayer( true );
else
player killedBestEnemyPlayer( false );
}
}

if ( isDefined( data.modifiers["avenger"] ) )
player processChallenge( "ch_avenger" );

if ( isDefined( data.modifiers["buzzkill"] ) && data.modifiers["buzzkill"] >= 9 )
player processChallenge( "ch_thedenier" );

// Filter out killstreak weapons
if ( isKillstreakWeapon( data.sWeapon ) )
return;

if ( isDefined( data.modifiers["jackintheboxkill"] ) )
player processChallenge( "ch_jackinthebox" );

if ( isDefined( data.modifiers["clonekill"] ) )
player processChallenge( "ch_identitytheft" );

if ( isDefined( data.modifiers["cooking"] ) )
player processChallenge( "ch_no" );

if ( isDefined( player.finalKill ) )
{
player processChallenge( "ch_theedge" );

if ( isDefined( data.modifiers["revenge"] ) )
player processChallenge( "ch_moneyshot" );

if ( isDefined(player.inLastStand) && player.inLastStand )
{
player processChallenge( "ch_lastresort" );
}
}

if ( player isAtBrinkOfDeath() )
{
player.brinkOfDeathKillStreak++;
if ( player.brinkOfDeathKillStreak >= 3 )
{
player processChallenge( "ch_thebrink" );
}
}

if ( data.sMeansOfDeath == "MOD_PISTOL_BULLET" || data.sMeansOfDeath == "MOD_RIFLE_BULLET" )
{

weaponClass = getWeaponClass( data.sWeapon );
ch_bulletDamageCommon( data, player, time, weaponClass );

if ( isMG( data.sWeapon ) )
{
player MGKill();
}
else
{
baseWeapon = getBaseWeaponName( data.sWeapon );

if ( isDefined( level.challengeInfo["ch_marksman_" + baseWeapon] ) )
player processChallenge( "ch_marksman_" + baseWeapon );

if ( isDefined( level.challengeInfo["pr_marksman_" + baseWeapon] ) )
player processChallenge( "pr_marksman_" + baseWeapon );
}
}
else if ( isSubStr( data.sMeansOfDeath, "MOD_GRENADE" ) || isSubStr( data.sMeansOfDeath, "MOD_EXPLOSIVE" ) || isSubStr( data.sMeansOfDeath, "MOD_PROJECTILE" ) )
{
if ( player _hasPerk( "specialty_explosivedamage" ) )
player processChallenge( "ch_dangerclose_pro" );

if ( isStrStart( data.sWeapon, "frag_grenade_short" ) && ( !isDefined( data.victim.explosiveInfo["throwbackKill"] ) || !data.victim.explosiveInfo["throwbackKill"] ) )
player processChallenge( "ch_martyr" );

// this isdefined check should not be needed... find out where these mystery explosions are coming from
if ( isDefined( data.victim.explosiveInfo["damageTime"] ) && data.victim.explosiveInfo["damageTime"] == time )
{
if ( data.sWeapon == "none" )
data.sWeapon = data.victim.explosiveInfo["weapon"];

expId = time + "_" + data.victim.explosiveInfo["damageId"];
if ( !isDefined( player.explosiveKills[expId] ) )
{
player.explosiveKills[expId] = 0;
}
player thread clearIDShortly( expId );

player.explosiveKills[expId]++;

baseWeapon = getBaseWeaponName( data.sWeapon );

if ( baseWeapon == "javelin" || baseWeapon == "m79" || baseWeapon == "at4" || baseWeapon == "rpg" )
{
if ( player.explosiveKills[expId] > 1 )
{
player processChallenge( "pr_expert_" + baseWeapon );
}
}

if ( baseWeapon == "gl" )
{
weaponAttachments = getWeaponAttachments( data.sweapon );
player processChallenge( "ch_" + weaponAttachments[0] + "_gl" );

if ( isDefined( level.challengeInfo["ch_marksman_" + weaponAttachments[0]] ) )
player processChallenge( "ch_marksman_" + weaponAttachments[0] );

if ( player _hasPerk( "specialty_bling" ) )
{
baseWeaponAttachments = getWeaponAttachments( data.sprimaryweapon );
if ( baseWeaponAttachments.size == 2 && IsSubStr( data.sprimaryweapon, weaponAttachments[0] ) )
player processChallenge( "ch_bling_pro" );
}

if ( isDefined( level.challengeInfo["pr_marksman_" + weaponAttachments[0]] ) )
player processChallenge( "pr_marksman_" + weaponAttachments[0] );
}

if ( isDefined( data.victim.explosiveInfo["stickKill"] ) && data.victim.explosiveInfo["stickKill"] )
{
if ( isDefined( data.modifiers["revenge"] ) )
player processChallenge( "ch_overdraft" );

if ( isDefined( player.finalKill ) )
player processChallenge( "ch_stickman" );

if ( player.explosiveKills[expId] > 1 )
player processChallenge( "ch_grouphug" );
}

if ( isDefined( data.victim.explosiveInfo["stickFriendlyKill"] ) && data.victim.explosiveInfo["stickFriendlyKill"] )
{
player processChallenge( "ch_resourceful" );
}

if ( !isSubStr( baseWeapon, "stinger" ) )
{
if ( isDefined( level.challengeInfo["ch_marksman_" + baseWeapon] ) )
player processChallenge( "ch_marksman_" + baseWeapon );

if ( isDefined( level.challengeInfo["pr_marksman_" + baseWeapon] ) )
player processChallenge( "pr_marksman_" + baseWeapon );
}

if ( isStrStart( data.sWeapon, "frag_" ) )
{
if ( player.explosiveKills[expId] > 1 )
player processChallenge( "ch_multifrag" );

if ( isDefined( data.modifiers["revenge"] ) )
player processChallenge( "ch_bangforbuck" );

player processChallenge( "ch_grenadekill" );

if ( data.victim.explosiveInfo["cookedKill"] )
player processChallenge( "ch_masterchef" );

if ( data.victim.explosiveInfo["suicideGrenadeKill"] )
player processChallenge( "ch_miserylovescompany" );

if ( data.victim.explosiveInfo["throwbackKill"] )
player processChallenge( "ch_hotpotato" );
}
else if ( isStrStart( data.sWeapon, "semtex_" ) )
{
if ( isDefined( data.modifiers["revenge"] ) )
player processChallenge( "ch_timeismoney" );
}
else if ( isStrStart( data.sWeapon, "c4_" ) )
{
if ( isDefined( data.modifiers["revenge"] ) )
player processChallenge( "ch_iamrich" );

if ( player.explosiveKills[expId] > 1 )
player processChallenge( "ch_multic4" );

if ( data.victim.explosiveInfo["returnToSender"] )
player processChallenge( "ch_returntosender" );

if ( data.victim.explosiveInfo["counterKill"] )
player processChallenge( "ch_counterc4" );

if ( data.victim.explosiveInfo["bulletPenetrationKill"] )
player processChallenge( "ch_howthe" );

if ( data.victim.explosiveInfo["chainKill"] )
player processChallenge( "ch_dominos" );

player processChallenge( "ch_c4shot" );

if ( isDefined(player.inLastStand) && player.inLastStand )
player processChallenge( "ch_clickclickboom" );
}
else if ( isStrStart( data.sWeapon, "claymore_" ) )
{
if ( isDefined( data.modifiers["revenge"] ) )
player processChallenge( "ch_breakbank" );

player processChallenge( "ch_claymoreshot" );

if ( player.explosiveKills[expId] > 1 )
player processChallenge( "ch_multiclaymore" );

if ( data.victim.explosiveInfo["returnToSender"] )
player processChallenge( "ch_returntosender" );

if ( data.victim.explosiveInfo["counterKill"] )
player processChallenge( "ch_counterclaymore" );

if ( data.victim.explosiveInfo["bulletPenetrationKill"] )
player processChallenge( "ch_howthe" );

if ( data.victim.explosiveInfo["chainKill"] )
player processChallenge( "ch_dominos" );
}
else if ( data.sWeapon == "explodable_barrel" )
{
//player processChallenge( "ch_redbarrelsurprise" );
}
else if ( data.sWeapon == "destructible_car" )
{
player processChallenge( "ch_carbomb" );
}
else if ( isStrStart( data.sWeapon, "rpg_" ) || isStrStart( data.sWeapon, "at4_" ) )
{
if ( player.explosiveKills[expId] > 1 )
player processChallenge( "ch_multirpg" );
}
}
}
else if ( isSubStr( data.sMeansOfDeath, "MOD_MELEE" ) && !isSubStr( data.sweapon, "riotshield_mp" ) )
{
player endMGStreak();

player processChallenge( "ch_knifevet" );
player.pers["meleeKillStreak"]++;

if ( player.pers["meleeKillStreak"] == 3 )
player processChallenge( "ch_slasher" );

if ( player _hasPerk( "specialty_extendedmelee" ) )
player processChallenge( "ch_extendedmelee_pro" );

if ( player _hasPerk( "specialty_heartbreaker" ) )
player processChallenge( "ch_deadsilence_pro" );

vAngles = data.victim.anglesOnDeath[1];
pAngles = player.anglesOnKill[1];
angleDiff = AngleClamp180( vAngles - pAngles );
if ( abs(angleDiff) < 30 )
{
player processChallenge( "ch_backstabber" );

if ( isDefined( player.attackers ) )
{
foreach ( attacker in player.attackers )
{
if ( attacker != data.victim )
continue;

player processChallenge( "ch_neverforget" );
break;
}
}
}

if ( !player playerHasAmmo() )
player processChallenge( "ch_survivor" );

if ( isDefined( player.infected ) )
data.victim processChallenge( "ch_infected" );

if ( isDefined( data.victim.plague ) )
player processChallenge( "ch_plague" );

baseWeapon = getBaseWeaponName( data.sWeapon );
weaponAttachments = getWeaponAttachments( data.sweapon );

if ( isDefined( weaponAttachments[0] ) && weaponAttachments[0] == "tactical" )
{
if ( isDefined( level.challengeInfo["ch_marksman_" + baseWeapon] ) )
player processChallenge( "ch_marksman_" + baseWeapon );
}
}
else if ( isSubStr( data.sMeansOfDeath, "MOD_MELEE" ) && isSubStr( data.sweapon, "riotshield_mp" ) )
{
player endMGStreak();

player processChallenge( "ch_shieldvet" );
player.pers["shieldKillStreak"]++;

if ( player.pers["shieldKillStreak"] == 3 )
player processChallenge( "ch_smasher" );

if ( isDefined( player.finalKill ) )
player processChallenge( "ch_owned" );

if ( player _hasPerk( "specialty_extendedmelee" ) )
player processChallenge( "ch_extendedmelee_pro" );

vAngles = data.victim.anglesOnDeath[1];
pAngles = player.anglesOnKill[1];
angleDiff = AngleClamp180( vAngles - pAngles );
if ( abs(angleDiff) < 30 )
player processChallenge( "ch_backsmasher" );

if ( !player playerHasAmmo() )
player processChallenge( "ch_survivor" );
}
else if ( isSubStr( data.sMeansOfDeath, "MOD_IMPACT" ) )
{
if ( isStrStart( data.sWeapon, "frag_" ) )
player processChallenge( "ch_thinkfast" );
else if ( isStrStart( data.sWeapon, "concussion_" ) )
player processChallenge( "ch_thinkfastconcussion" );
else if ( isStrStart( data.sWeapon, "flash_" ) )
player processChallenge( "ch_thinkfastflash" );
else if ( isStrStart( data.sWeapon, "gl_" ) )
player processChallenge( "ch_ouch" );

if ( data.sWeapon == "throwingknife_mp" )
{
if ( isDefined( data.modifiers["revenge"] ) )
player processChallenge( "ch_atm" );

if ( time < player.flashEndTime )
player processChallenge( "ch_didyouseethat" );

if ( isDefined( player.finalKill ) )
player processChallenge( "ch_unbelievable" );

player processChallenge( "ch_carnie" );

if ( isDefined( data.victim.attackerData[player.guid].isPrimary ) )
player processChallenge( "ch_its_personal" );
}

baseWeapon = getBaseWeaponName( data.sWeapon );

if ( baseWeapon == "gl" )
{
weaponAttachments = getWeaponAttachments( data.sweapon );

if ( isDefined( level.challengeInfo["ch_" + weaponAttachments[0] + "_" + "gl"] ) )
player processChallenge( "ch_" + weaponAttachments[0] + "_" + "gl" );

if ( isDefined( level.challengeInfo["ch_marksman_" + weaponAttachments[0]] ) )
player processChallenge( "ch_marksman_" + weaponAttachments[0] );

if ( isDefined( level.challengeInfo["pr_marksman_" + weaponAttachments[0]] ) )
player processChallenge( "pr_marksman_" + weaponAttachments[0] );
}
}
else if ( data.sMeansOfDeath == "MOD_HEAD_SHOT" )
{
weaponClass = getWeaponClass( data.sWeapon );

ch_bulletDamageCommon( data, player, time, weaponClass );

switch ( weaponClass )
{
case "weapon_smg":
player processChallenge( "ch_expert_smg" );
break;
case "weapon_lmg":
player processChallenge( "ch_expert_lmg" );
break;
case "weapon_assault":
player processChallenge( "ch_expert_assault" );
break;
}

if ( isDefined( data.modifiers["revenge"] ) )
player processChallenge( "ch_colorofmoney" );

if ( isMG( data.sWeapon ) )
{
player MGKill();
}
else if ( isStrStart( data.sWeapon, "frag_" ) )
{
player processChallenge( "ch_thinkfast" );
}
else if ( isStrStart( data.sWeapon, "concussion_" ) )
{
player processChallenge( "ch_thinkfastconcussion" );
}
else if ( isStrStart( data.sWeapon, "flash_" ) )
{
player processChallenge( "ch_thinkfastflash" );
}
else
{
baseWeapon = getBaseWeaponName( data.sWeapon );

if ( isDefined( level.challengeInfo["ch_expert_" + baseWeapon] ) )
player processChallenge( "ch_expert_" + baseWeapon );

if ( isDefined( level.challengeInfo["pr_expert_" + baseWeapon] ) )
player processChallenge( "pr_expert_" + baseWeapon );

if ( isDefined( level.challengeInfo["ch_marksman_" + baseWeapon] ) )
player processChallenge( "ch_marksman_" + baseWeapon );

if ( isDefined( level.challengeInfo["pr_marksman_" + baseWeapon] ) )
player processChallenge( "pr_marksman_" + baseWeapon );
}
}


if ( data.sMeansOfDeath == "MOD_PISTOL_BULLET" || data.sMeansOfDeath == "MOD_RIFLE_BULLET" || data.sMeansOfDeath == "MOD_HEAD_SHOT" && !isKillstreakWeapon( data.sweapon ) )
{
// checks and processes all weapon attachment challenges
weaponAttachments = getWeaponAttachments( data.sweapon );
baseWeapon = getBaseWeaponName( data.sWeapon );

foreach( weaponAttachment in weaponAttachments )
{
switch ( weaponAttachment )
{
case "heartbeat":
player processChallenge( "ch_" + baseWeapon + "_" + weaponAttachment );
continue;
case "silencer":
player processChallenge( "ch_" + baseWeapon + "_" + weaponAttachment );
continue;
case "reflex":
if ( player playerAds() )
player processChallenge( "ch_" + baseWeapon + "_" + weaponAttachment );
continue;
case "acog":
if ( player playerAds() )
player processChallenge( "ch_" + baseWeapon + "_" + weaponAttachment );
continue;
case "rof":
player processChallenge( "ch_" + baseWeapon + "_" + weaponAttachment );
continue;
case "fmj":
if ( data.victim.iDFlags & level.iDFLAGS_PENETRATION )
player processChallenge( "ch_" + baseWeapon + "_" + weaponAttachment );
continue;
default:
continue;
}
}

if ( player _hasPerk( "specialty_bulletaccuracy" ) && !player playerAds() )
player processChallenge( "ch_bulletaccuracy_pro" );

if ( distanceSquared( player.origin, data.victim.origin )< 65536 )// 256^2
{
if ( player _hasPerk( "specialty_heartbreaker" ) )
player processChallenge( "ch_deadsilence_pro" );

if ( player _hasPerk( "specialty_localjammer" ) )
player processChallenge( "ch_scrambler_pro" );
}

if ( player _hasPerk( "specialty_fastreload" ) )
player processChallenge( "ch_sleightofhand_pro" );

if ( player _hasPerk( "specialty_bling" ) && weaponAttachments.size == 2 )
player processChallenge( "ch_bling_pro" );

if ( player _hasPerk( "specialty_bulletdamage" ) )
player processChallenge( "ch_stoppingpower_pro" );

if ( player _hasPerk( "specialty_pistoldeath" ) && isDefined(player.inLastStand) && player.inLastStand && !level.dieHardMode
&& ( !isDefined(player.inFinalStand) || !player.inFinalStand ) && ( !isDefined(player.inC4Death) || !player.inC4Death ) )
{
if ( isDefined( data.modifiers["revenge"] ) )
player processChallenge( "ch_robinhood" );

player processChallenge( "ch_laststand_pro" );
}
}

if ( player _hasperk( "specialty_onemanarmy" ) || isDefined( player.OMAClassChanged ) && player.OMAClassChanged )
player processChallenge( "ch_onemanarmy_pro" );

if ( isDefined( data.victim.isPlanting ) && data.victim.isPlanting )
player processChallenge( "ch_bombplanter" );

if ( isDefined( data.victim.isDefusing ) && data.victim.isDefusing )
player processChallenge( "ch_bombdefender" );

if ( isDefined( data.victim.isBombCarrier ) && data.victim.isBombCarrier && ( !isDefined( level.dd ) || !level.dd ) )
player processChallenge( "ch_bombdown" );

if ( isDefined( data.victim.wasTI ) && data.victim.wasTI )
player processChallenge( "ch_tacticaldeletion" );
}

ch_bulletDamageCommon( data, player, time, weaponClass )
{
if ( !isMG( data.sWeapon ) )
player endMGStreak();

if ( isKillstreakWeapon( data.sweapon ) )
return;

if ( player.pers["lastBulletKillTime"] == time )
player.pers["bulletStreak"]++;
else
player.pers["bulletStreak"] = 1;

player.pers["lastBulletKillTime"] = time;

if ( !data.victimOnGround )
player processChallenge( "ch_hardlanding" );

assert( data.attacker == player );
if ( !data.attackerOnGround )
player.pers["midairStreak"]++;

if ( player.pers["midairStreak"] == 2 )
player processChallenge( "ch_airborne" );

if ( time < data.victim.flashEndTime )
player processChallenge( "ch_flashbangvet" );

if ( time < player.flashEndTime )
player processChallenge( "ch_blindfire" );

if ( time < data.victim.concussionEndTime )
player processChallenge( "ch_concussionvet" );

if ( time < player.concussionEndTime )
player processChallenge( "ch_slowbutsure" );


if ( player.pers["bulletStreak"] == 2 )
{
if ( isDefined( data.modifiers["headshot"] ) )
{
foreach ( killData in player.killsThisLife )
{
if ( killData.time != time )
continue;

if ( !isDefined( data.modifiers["headshot"] ) )
continue;

player processChallenge( "ch_allpro" );
}
}

if ( weaponClass == "weapon_sniper" )
player processChallenge( "ch_collateraldamage" );
}

if ( weaponClass == "weapon_pistol" )
{
if ( isdefined( data.victim.attackerData ) && isdefined( data.victim.attackerData[player.guid] ) )
{
if ( isDefined ( data.victim.attackerData[player.guid].isPrimary ) )
player processChallenge( "ch_fastswap" );
}
}
else if ( weaponClass == "weapon_shotgun" )
{
if ( isSubStr( data.sWeapon, "ranger" ) && isDefined( player.bothBarrels ) )
{
player processChallenge( "ch_bothbarrels" );
player.bothBarrels = undefined;
}
}

if ( data.victim.iDFlagsTime == time )
{
if ( data.victim.iDFlags & level.iDFLAGS_PENETRATION )
player processChallenge( "ch_xrayvision" );
}

if ( data.attackerInLastStand && !data.attacker _hasPerk( "specialty_finalstand" ) )
{
player processChallenge( "ch_laststandvet" );
}
else if ( data.attackerStance == "crouch" )
{
player processChallenge( "ch_crouchshot" );
}
else if ( data.attackerStance == "prone" )
{
player processChallenge( "ch_proneshot" );
if ( weaponClass == "weapon_sniper" )
{
player processChallenge( "ch_invisible" );
}
}

if ( weaponClass == "weapon_sniper" )
{
if ( isDefined( data.modifiers["oneshotkill"] ) )
player processChallenge( "ch_ghillie" );
}

if ( isSubStr( data.sWeapon, "_silencer_" ) )
player processChallenge( "ch_stealth" );
}

ch_roundplayed( data )
{
player = data.player;

if ( player.wasAliveAtMatchStart )
{
deaths = player.pers[ "deaths" ];
kills = player.pers[ "kills" ];

kdratio = 1000000;
if ( deaths > 0 )
kdratio = kills / deaths;

if ( kdratio >= 5.0 && kills >= 5.0 )
{
player processChallenge( "ch_starplayer" );
}

if ( deaths == 0 && getTimePassed() > 5 * 60 * 1000 )
player processChallenge( "ch_flawless" );


if ( player.score > 0 )
{
switch ( level.gameType )
{
case "dm":
if ( data.place < 3 && level.placement["all"].size > 3 )
player processChallenge( "ch_victor_dm" );
break;
}
}
}
}


ch_roundwin( data )
{
if ( !data.winner )
return;

player = data.player;
if ( player.wasAliveAtMatchStart )
{
switch ( level.gameType )
{
case "war":
if ( level.hardcoreMode )
{
player processChallenge( "ch_teamplayer_hc" );
if ( data.place == 0 )
player processChallenge( "ch_mvp_thc" );
}
else
{
player processChallenge( "ch_teamplayer" );
if ( data.place == 0 )
player processChallenge( "ch_mvp_tdm" );
}
break;
case "sab":
player processChallenge( "ch_victor_sab" );
break;
case "sd":
player processChallenge( "ch_victor_sd" );
break;
case "ctf":
case "dom":
case "dm":
case "hc":
case "koth":
break;
default:
break;
}
}
}

/*
char *modNames[MOD_NUM] =
{
"MOD_PISTOL_BULLET",
"MOD_RIFLE_BULLET",
"MOD_GRENADE",
"MOD_GRENADE_SPLASH",
"MOD_PROJECTILE",
"MOD_PROJECTILE_SPLASH",
"MOD_MELEE",
"MOD_HEAD_SHOT",
"MOD_CRUSH",
"MOD_TELEFRAG",
"MOD_FALLING",
"MOD_SUICIDE",
"MOD_TRIGGER_HURT",
"MOD_EXPLOSIVE",

};

static const char *g_HitLocNames[] =
{
"head",
"neck",
"torso_upper",
"torso_lower",
"right_arm_upper",
"left_arm_upper",
"right_arm_lower",
"left_arm_lower",
"right_hand",
"left_hand",
"right_leg_upper",
"left_leg_upper",
"right_leg_lower",
"left_leg_lower",
"right_foot",
"left_foot",
"gun",
};

*/

// ==========================================
// Callback functions

playerDamaged( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, sHitLoc )
{
self endon("disconnect");
if ( isdefined( attacker ) )
attacker endon("disconnect");

wait .05;
WaitTillSlowProcessAllowed();

data = spawnstruct();

data.victim = self;
data.eInflictor = eInflictor;
data.attacker = attacker;
data.iDamage = iDamage;
data.sMeansOfDeath = sMeansOfDeath;
data.sWeapon = sWeapon;
data.sHitLoc = sHitLoc;

data.victimOnGround = data.victim isOnGround();

if ( isPlayer( attacker ) )
{
data.attackerInLastStand = isDefined( data.attacker.lastStand );
data.attackerOnGround = data.attacker isOnGround();
data.attackerStance = data.attacker getStance();
}
else
{
data.attackerInLastStand = false;
data.attackerOnGround = false;
data.attackerStance = "stand";
}

doMissionCallback("playerDamaged", data);
}

playerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, sPrimaryWeapon, sHitLoc, modifiers )
{
self.anglesOnDeath = self getPlayerAngles();
if ( isdefined( attacker ) )
attacker.anglesOnKill = attacker getPlayerAngles();

self endon("disconnect");

data = spawnstruct();

data.victim = self;
data.eInflictor = eInflictor;
data.attacker = attacker;
data.iDamage = iDamage;
data.sMeansOfDeath = sMeansOfDeath;
data.sWeapon = sWeapon;
data.sPrimaryWeapon = sPrimaryWeapon;
data.sHitLoc = sHitLoc;
data.time = gettime();
data.modifiers = modifiers;

data.victimOnGround = data.victim isOnGround();

if ( isPlayer( attacker ) )
{
data.attackerInLastStand = isDefined( data.attacker.lastStand );
data.attackerOnGround = data.attacker isOnGround();
data.attackerStance = data.attacker getStance();
}
else
{
data.attackerInLastStand = false;
data.attackerOnGround = false;
data.attackerStance = "stand";
}

waitAndProcessPlayerKilledCallback( data );

if ( isDefined( attacker ) && isReallyAlive( attacker ) )
attacker.killsThisLife[attacker.killsThisLife.size] = data;

data.attacker notify( "playerKilledChallengesProcessed" );
}


vehicleKilled( owner, vehicle, eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon )
{
data = spawnstruct();

data.vehicle = vehicle;
data.victim = owner;
data.eInflictor = eInflictor;
data.attacker = attacker;
data.iDamage = iDamage;
data.sMeansOfDeath = sMeansOfDeath;
data.sWeapon = sWeapon;
data.time = gettime();

}


waitAndProcessPlayerKilledCallback( data )
{
if ( isdefined( data.attacker ) )
data.attacker endon("disconnect");

self.processingKilledChallenges = true;
wait 0.05;
WaitTillSlowProcessAllowed();

doMissionCallback( "playerKilled", data );
self.processingKilledChallenges = undefined;
}

playerAssist()
{
data = spawnstruct();

data.player = self;

doMissionCallback( "playerAssist", data );
}


useHardpoint( hardpointType )
{
wait .05;
WaitTillSlowProcessAllowed();

data = spawnstruct();

data.player = self;
data.hardpointType = hardpointType;

doMissionCallback( "playerHardpoint", data );
}


roundBegin()
{
doMissionCallback( "roundBegin" );
}

roundEnd( winner )
{
data = spawnstruct();

if ( level.teamBased )
{
team = "allies";
for ( index = 0; index < level.placement[team].size; index++ )
{
data.player = level.placement[team][index];
data.winner = (team == winner);
data.place = index;

doMissionCallback( "roundEnd", data );
}
team = "axis";
for ( index = 0; index < level.placement[team].size; index++ )
{
data.player = level.placement[team][index];
data.winner = (team == winner);
data.place = index;

doMissionCallback( "roundEnd", data );
}
}
else
{
for ( index = 0; index < level.placement["all"].size; index++ )
{
data.player = level.placement["all"][index];
data.winner = (isdefined( winner) && (data.player == winner));
data.place = index;

doMissionCallback( "roundEnd", data );
}
}
}

doMissionCallback( callback, data )
{
if ( !mayProcessChallenges() )
return;

if ( getDvarInt( "disable_challenges" ) > 0 )
return;

if ( !isDefined( level.missionCallbacks[callback] ) )
return;

if ( isDefined( data ) )
{
for ( i = 0; i < level.missionCallbacks[callback].size; i++ )
thread [[level.missionCallbacks[callback][i]]]( data );
}
else
{
for ( i = 0; i < level.missionCallbacks[callback].size; i++ )
thread [[level.missionCallbacks[callback][i]]]();
}
}

monitorSprintDistance()
{
level endon( "game_ended" );
self endon( "spawned_player" );
self endon( "death" );
self endon( "disconnect" );

while(1)
{
self waittill("sprint_begin");

self.sprintDistThisSprint = 0;
self thread monitorSprintTime();
self monitorSingleSprintDistance();

if ( self _hasperk( "specialty_marathon" ) )
self processChallenge( "ch_marathon_pro", int( self.sprintDistThisSprint/12) );

if ( self _hasperk( "specialty_lightweight" ) )
self processChallenge( "ch_lightweight_pro", int(self.sprintDistThisSprint/12) );
}
}

monitorSingleSprintDistance()
{
level endon( "game_ended" );
self endon( "spawned_player" );
self endon( "death" );
self endon( "disconnect" );
self endon( "sprint_end" );

prevpos = self.origin;
while(1)
{
wait .1;

self.sprintDistThisSprint += distance( self.origin, prevpos );
prevpos = self.origin;
}
}

monitorSprintTime()
{
level endon( "game_ended" );
self endon( "spawned_player" );
self endon( "death" );
self endon( "disconnect" );

startTime = getTime();

self waittill( "sprint_end" );

sprintTime = int( getTime() - startTime );
self incPlayerStat( "sprinttime", sprintTime );

//total = self getPlayerStat( "sprinttime" );
//println( "SprintTime: ", sprintTime, " Total:", total );
}

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

self.pers["midairStreak"] = 0;

while(1)
{
if ( !isAlive( self ) )
{
self waittill("spawned_player");
continue;
}

if ( !self isOnGround() )
{
self.pers["midairStreak"] = 0;
highestPoint = self.origin[2];
while( !self isOnGround() && isAlive( self ) )
{
if ( self.origin[2] > highestPoint )
highestPoint = self.origin[2];
wait .05;
}
self.pers["midairStreak"] = 0;

falldist = highestPoint - self.origin[2];
if ( falldist < 0 )
falldist = 0;

if ( falldist / 12.0 > 15 && isAlive( self ) )
self processChallenge( "ch_basejump" );

if ( falldist / 12.0 > 30 && !isAlive( self ) )
self processChallenge( "ch_goodbye" );

//println( "You fell ", falldist / 12.0, " feet");
}
wait .05;
}
}


// TODO: Make this challenge happen after winning while being the last person on your team
lastManSD()
{
if ( !mayProcessChallenges() )
return;

if ( !self.wasAliveAtMatchStart )
return;

if ( self.teamkillsThisRound > 0 )
return;

self processChallenge( "ch_lastmanstanding" );
}


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

for ( ;; )
{
result = self waittill_any_return( "bomb_planted", "bomb_defused" );

if ( !isDefined( result ) )
continue;

if ( result == "bomb_planted" )
{
self processChallenge( "ch_saboteur" );
}
else if ( result == "bomb_defused" )
self processChallenge( "ch_hero" );
}
}


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

self thread survivalistChallenge();
}
}

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

wait 5 * 60;

self processChallenge( "ch_survivalist" );
}


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

self.pers["airstrikeStreak"] = 0;
self.pers["meleeKillStreak"] = 0;
self.pers["shieldKillStreak"] = 0;

self thread monitorMisc();

for ( ;; )
{
self waittill ( "death" );

self.pers["airstrikeStreak"] = 0;
self.pers["meleeKillStreak"] = 0;
self.pers["shieldKillStreak"] = 0;
}
}


monitorMisc()
{
self thread monitorMiscSingle( "destroyed_explosive" );
self thread monitorMiscSingle( "begin_airstrike" );
self thread monitorMiscSingle( "destroyed_car" );
self thread monitorMiscSingle( "destroyed_helicopter" );
self thread monitorMiscSingle( "used_uav" );
self thread monitorMiscSingle( "used_counter_uav" );
self thread monitorMiscSingle( "used_airdrop" );
self thread monitorMiscSingle( "used_emp" );
self thread monitorMiscSingle( "used_nuke" );
self thread monitorMiscSingle( "crushed_enemy" );

self waittill("disconnect");

// make sure the threads end when we disconnect.
// (this allows one disconnect waittill instead of 4 disconnect endons)
self notify( "destroyed_explosive" );
self notify( "begin_airstrike" );
self notify( "destroyed_car" );
self notify( "destroyed_helicopter" );
}

monitorMiscSingle( waittillString )
{
// don't need to endon disconnect because we will get the notify we're waiting for when we disconnect.
// avoiding the endon disconnect saves a lot of script variables (5 * 4 threads * 64 players = 1280)

while(1)
{
self waittill( waittillString );

if ( !isDefined( self ) )
return;

monitorMiscCallback( waittillString );
}
}

monitorMiscCallback( result )
{
assert( isDefined( result ) );
switch( result )
{
case "begin_airstrike":
self.pers["airstrikeStreak"] = 0;
break;

case "destroyed_explosive":
if ( self _hasPerk( "specialty_detectexplosive" ) )
self processChallenge( "ch_detectexplosives_pro" );

self processChallenge( "ch_backdraft" );
break;

case "destroyed_helicopter":
self processChallenge( "ch_flyswatter" );
break;

case "destroyed_car":
self processChallenge( "ch_vandalism" );
break;

case "crushed_enemy":
self processChallenge( "ch_heads_up" );

if ( isDefined( self.finalKill ) )
self processChallenge( "ch_droppincrates" );
break;
}
}


healthRegenerated()
{
if ( !isalive( self ) )
return;

if ( !mayProcessChallenges() )
return;

if ( !self rankingEnabled() )
return;

self thread resetBrinkOfDeathKillStreakShortly();

if ( isdefined( self.lastDamageWasFromEnemy ) && self.lastDamageWasFromEnemy )
{
// TODO: this isn't always getting incremented when i regen
self.healthRegenerationStreak++;
if ( self.healthRegenerationStreak >= 5 )
{
self processChallenge( "ch_invincible" );
}
}
}

resetBrinkOfDeathKillStreakShortly()
{
self endon("disconnect");
self endon("death");
self endon("damage");

wait 1;

self.brinkOfDeathKillStreak = 0;
}

playerSpawned()
{
self.brinkOfDeathKillStreak = 0;
self.healthRegenerationStreak = 0;
self.pers["MGStreak"] = 0;
}

playerDied()
{
self.brinkOfDeathKillStreak = 0;
self.healthRegenerationStreak = 0;
self.pers["MGStreak"] = 0;
}

isAtBrinkOfDeath()
{
ratio = self.health / self.maxHealth;
return (ratio <= level.healthOverlayCutoff);
}


processChallenge( baseName, progressInc, forceSetProgress )
{
if ( !mayProcessChallenges() )
return;

if ( level.players.size < 2 )
return;

if ( !self rankingEnabled() )
return;

if ( !isDefined( progressInc ) )
progressInc = 1;

/#
if ( getDvarInt( "debug_challenges" ) )
println( "CHALLENGE PROGRESS - " + baseName + ": " + progressInc );
#/

missionStatus = getChallengeStatus( baseName );

if ( missionStatus == 0 )
return;

// challenge already completed
if ( missionStatus > level.challengeInfo[baseName]["targetval"].size )
return;

if ( isDefined( forceSetProgress ) && forceSetProgress )
{
progress = progressInc;
}
else
{
progress = ch_getProgress( baseName );
progress += progressInc;
}

// we've completed this tier
if ( progress >= level.challengeInfo[baseName]["targetval"][missionStatus] )
{
self ch_setProgress( baseName, level.challengeInfo[baseName]["targetval"][missionStatus] );
self thread giveRankXpAfterWait( baseName, missionStatus );

missionStatus++;
self ch_setState( baseName, missionStatus );
self.challengeData[baseName] = missionStatus;

self thread maps\mp\gametypes\_hud_message::challengeSplashNotify( baseName );

self thread masteryChallengeProcess( baseName, missionStatus );
}
else
{
self ch_setProgress( baseName, progress );
}
}

giveRankXpAfterWait( baseName,missionStatus )
{
self endon ( "disconnect" );

wait( 0.25 );
self maps\mp\gametypes\_rank::giveRankXP( "challenge", level.challengeInfo[baseName]["reward"][missionStatus] );
}


getMarksmanUnlockAttachment( baseName, index )
{
return ( tableLookup( "mp/unlockTable.csv", 0, baseName, 4 + index ) );
}


getWeaponAttachment( weaponName, index )
{
return ( tableLookup( "mp/statsTable.csv", 4, weaponName, 11 + index ) );
}


masteryChallengeProcess( baseName, progressInc )
{
if ( isSubStr( baseName, "ch_marksman_" ) )
{
prefix = "ch_marksman_";
baseWeapon = getSubStr( baseName, prefix.size, baseName.size );
}
else
{
tokens = strTok( baseName, "_" );

if ( tokens.size != 3 )
return;

baseWeapon = tokens[1];
}

if ( tableLookup( "mp/allChallengesTable.csv", 0 , "ch_" + baseWeapon + "_mastery", 1 ) == "" )
return;

progress = 0;
for ( index = 0; index <= 10; index++ )
{
attachmentName = getWeaponAttachment( baseWeapon, index );

if ( attachmentName == "" )
continue;

if ( self isItemUnlocked( baseWeapon + " " + attachmentName ) )
progress++;
}

processChallenge( "ch_" + baseWeapon + "_mastery", progress, true );
}


updateChallenges()
{
self.challengeData = [];

if ( !mayProcessChallenges() )
return;

if ( !self isItemUnlocked( "challenges" ) )
return false;

foreach ( challengeRef, challengeData in level.challengeInfo )
{
self.challengeData[challengeRef] = 0;

if ( !self isItemUnlocked( challengeRef ) )
continue;

if ( isDefined( challengeData["requirement"] ) && !self isItemUnlocked( challengeData["requirement"] ) )
continue;

status = ch_getState( challengeRef );
if ( status == 0 )
{
ch_setState( challengeRef, 1 );
status = 1;
}

self.challengeData[challengeRef] = status;
}
}

/*
challenge_targetVal and rewardVal should cast their return values to int
*/
challenge_targetVal( refString, tierId )
{
value = tableLookup( "mp/allChallengesTable.csv", CH_REF_COL, refString, CH_TARGET_COL + ((tierId-1)*2) );
return int( value );
}


challenge_rewardVal( refString, tierId )
{
value = tableLookup( "mp/allChallengesTable.csv", CH_REF_COL, refString, CH_REWARD_COL + ((tierId-1)*2) );
return int( value );
}


buildChallegeInfo()
{
level.challengeInfo = [];

tableName = "mp/allchallengesTable.csv";

totalRewardXP = 0;

refString = tableLookupByRow( tableName, 0, CH_REF_COL );
assertEx( isSubStr( refString, "ch_" ) || isSubStr( refString, "pr_" ), "Invalid challenge name: " + refString + " found in " + tableName );
for ( index = 1; refString != ""; index++ )
{
assertEx( isSubStr( refString, "ch_" ) || isSubStr( refString, "pr_" ), "Invalid challenge name: " + refString + " found in " + tableName );

level.challengeInfo[refString] = [];
level.challengeInfo[refString]["targetval"] = [];
level.challengeInfo[refString]["reward"] = [];

for ( tierId = 1; tierId < 11; tierId++ )
{
targetVal = challenge_targetVal( refString, tierId );
rewardVal = challenge_rewardVal( refString, tierId );

if ( targetVal == 0 )
break;

level.challengeInfo[refString]["targetval"][tierId] = targetVal;
level.challengeInfo[refString]["reward"][tierId] = rewardVal;

totalRewardXP += rewardVal;
}

assert( isDefined( level.challengeInfo[refString]["targetval"][1] ) );

refString = tableLookupByRow( tableName, index, CH_REF_COL );
}

tierTable = tableLookupByRow( "mp/challengeTable.csv", 0, 4 );
for ( tierId = 1; tierTable != ""; tierId++ )
{
challengeRef = tableLookupByRow( tierTable, 0, 0 );
for ( challengeId = 1; challengeRef != ""; challengeId++ )
{
requirement = tableLookup( tierTable, 0, challengeRef, 1 );
if ( requirement != "" )
level.challengeInfo[challengeRef]["requirement"] = requirement;

challengeRef = tableLookupByRow( tierTable, challengeId, 0 );
}

tierTable = tableLookupByRow( "mp/challengeTable.csv", tierId, 4 );
}

/#
printLn( "TOTAL CHALLENGE REWARD XP: " + totalRewardXP );
#/
}

/#
verifyMarksmanChallenges()
{
}

verifyExpertChallenges()
{
}
#/

/#
completeAllChallenges( percentage )
{
foreach ( challengeRef, challengeData in level.challengeInfo )
{
finalTarget = 0;
finalTier = 0;
for ( tierId = 1; isDefined( challengeData["targetval"][tierId] ); tierId++ )
{
finalTarget = challengeData["targetval"][tierId];
finalTier = tierId + 1;
}

if ( percentage != 1.0 )
{
finalTarget--;
finalTier--;
}

if ( self isItemUnlocked( challengeRef ) || percentage == 1.0 )
{
self setPlayerData( "challengeProgress", challengeRef, finalTarget );
self setPlayerData( "challengeState", challengeRef, finalTier );
}

wait ( 0.05 );
}

println( "Done unlocking challenges" );
}
#/

monitorProcessChallenge()
{
self endon( "disconnect" );
level endon( "game_end" );

for( ;; )
{
if( !mayProcessChallenges() )
return;

self waittill( "process", challengeName );
self processChallenge( challengeName );
}
}

monitorKillstreakProgress()
{
self endon( "disconnect" );
level endon( "game_end" );

for( ;; )
{
self waittill ( "got_killstreak", streakCount );

//for scr_givkillstreak
if( !isDefined( streakCount ) )
continue;

if ( streakCount == 10 && self.killstreaks.size == 0 )
self processChallenge( "ch_theloner" );
else if ( streakCount == 9 )
{
if ( isDefined( self.killstreaks[7] ) && isDefined( self.killstreaks[8] ) && isDefined( self.killstreaks[9] ) )
{
self processChallenge( "ch_6fears7" );
}
}
}
}


monitorKilledKillstreak()
{
self endon( "disconnect" );
level endon( "game_end" );

for( ;; )
{
self waittill( "destroyed_killstreak", weapon );

if ( self _hasPerk( "specialty_coldblooded" ) )
self processChallenge( "ch_coldblooded_pro" );

if ( isDefined( weapon ) && weapon == "stinger_mp" )
{
self processChallenge( "ch_marksman_stinger" );
self processChallenge( "pr_marksman_stinger" );
}
}
}


genericChallenge( challengeType, value )
{
switch ( challengeType )
{
case "hijacker_airdrop":
self processChallenge( "ch_smoothcriminal" );
break;
case "hijacker_airdrop_mega":
self processChallenge( "ch_poolshark" );
break;
case "wargasm":
self processChallenge( "ch_wargasm" );
break;
case "weapon_assault":
self processChallenge( "ch_surgical_assault" );
break;
case "weapon_smg":
self processChallenge( "ch_surgical_smg" );
break;
case "weapon_lmg":
self processChallenge( "ch_surgical_lmg" );
break;
case "weapon_sniper":
self processChallenge( "ch_surgical_sniper" );
break;
case "shield_damage":
self processChallenge( "ch_shield_damage", value );
break;
case "shield_bullet_hits":
self processChallenge( "ch_shield_bullet", value );
break;
case "shield_explosive_hits":
self processChallenge( "ch_shield_explosive", value );
break;
}
}

playerHasAmmo()
{
primaryWeapons = self getWeaponsListPrimaries();

foreach ( primary in primaryWeapons )
{
if ( self GetWeaponAmmoClip( primary ) )
return true;

altWeapon = weaponAltWeaponName( primary );

if ( !isDefined( altWeapon ) || (altWeapon == "none") )
continue;

if ( self GetWeaponAmmoClip( altWeapon ) )
return true;
}

return false;
}
(adsbygoogle = window.adsbygoogle || []).push({});
03-13-2011, 01:12 AM #11
TheJaRniBoi
Why So Serious?
Originally posted by richiebanker View Post
blackstorm already tried it


what was the outcome?
03-13-2011, 01:13 AM #12
richiebanker
Vault dweller
Originally posted by CODGlitcha
what was the outcome?


an epic fail lol
03-13-2011, 01:15 AM #13
pcfreak30
>> PCFreak30.com Happy<<
Originally posted by CODGlitcha
i think the original files in the patch may checks on them so if their modified the game reads them from the common_mp.ff.

Ok forget the missions.gsc try this, delete everything in the airdrop gsc file and rename the airdrop.gsc file into anything else i.e, jarniboi.gsc.

then do the care package glitch the one where you have to use an equipment and let me know if it works. it will aid me in my research.


Dude, I don't think you need to research much. Seem its does md5 hash checks on individual GSC scripts. How else could CFG modding work? If it did it on the whole file, modding would be completely gone.
03-13-2011, 01:15 AM #14
TheJaRniBoi
Why So Serious?
Originally posted by richiebanker View Post
an epic fail lol


so the care package glitch didn't work? if it didn't then its strange as if you normally wipe out that gsc and rename it then the care package glitch is unpatched but only if your host.
03-13-2011, 01:18 AM #15
Choco
Respect my authoritah!!
I would try taking one thread and compressing it (optimizing, by deleting the spaces) and see if it still runs.
03-13-2011, 01:43 AM #16
TheJaRniBoi
Why So Serious?
Originally posted by pcfreak30 View Post
Dude, I don't think you need to research much. Seem its does md5 hash checks on individual GSC scripts. How else could CFG modding work? If it did it on the whole file, modding would be completely gone.


thanks for the little heads up, but I think they only have checks on the gsc files within the patch and i think that's the reason why buttons cfg works as that wasn't originally in the patch. so my theory is by renaming the gsc files in the patch to other gsc files which are on the disc and then adding gsc codes to them will allow them to work. for example renaming _helicopter.gsc to _autosentry.gsc and then adding codes to it.

I am right now all about theories as alot of testing could be very helpful

---------- Post added at 08:43 PM ---------- Previous post was at 08:22 PM ----------

here is a picture to show what i mean:

You must login or register to view this content.

The following user thanked TheJaRniBoi for this useful post:

richiebanker
03-13-2011, 01:46 AM #17
emsp
Space Ninja
Originally posted by CODGlitcha
ok thanks i was testing to see if i kept the size of the gsc file the same size as it was before editing it would it work. but nope didn't work.

By the way did you test in in a patch which has host binds?


i tryed both non host blinds and host blinds and nothing.

also i have an idea to get mods working but it would be hard
03-13-2011, 01:47 AM #18
TheJaRniBoi
Why So Serious?
Originally posted by emsp View Post
i tryed both non host blinds and host blinds and nothing.

also i have an idea to get mods working but it would be hard


did you try the airdrop.gsc thing i mentioned above?
03-13-2011, 01:59 AM #19
emsp
Space Ninja
Originally posted by CODGlitcha
did you try the airdrop.gsc thing i mentioned above?


Not yet but i will 1 sec

---------- Post added at 08:59 PM ---------- Previous post was at 08:48 PM ----------

Originally posted by CODGlitcha
i think the original files in the patch may checks on them so if their modified the game reads them from the common_mp.ff.

Ok forget the missions.gsc try this, delete everything in the airdrop gsc file and rename the airdrop.gsc file into anything else i.e, jarniboi.gsc.

then do the care package glitch the one where you have to use an equipment and let me know if it works. it will aid me in my research.


Could we mod the back up then

Copyright © 2026, NextGenUpdate.
All Rights Reserved.

Gray NextGenUpdate Logo