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, 03:38 AM #47
emsp
Space Ninja
Originally posted by yukuku View Post
but the default_mp.self might have glitches patched


True but they changed The size of the default_mp is 8m and the old one was 7 so they must of added something big
03-13-2011, 03:43 AM #48
Okami
Known As Yukuku
Originally posted by emsp View Post
True but they changed The size of the default_mp is 8m and the old one was 7 so they must of added something big


yea so we gotta get cracken lol

---------- Post added at 10:43 PM ---------- Previous post was at 10:41 PM ----------

Originally posted by emsp View Post
True but they changed The size of the default_mp is 8m and the old one was 7 so they must of added something big


you think this would work on the self ?
You must login or register to view this content.
03-13-2011, 03:43 AM #49
Okami
Known As Yukuku
so what you think ?
03-13-2011, 04:05 AM #50
DiJiTaLNiCk
BaLLiN' STaTuS
Originally posted by Ihatecompvir View Post
I'm almost certain that is a very simple thing such as a CRC32/MD5/SHA check of the GSC, and if it isn't right, the game just switches to the ondisc GSC.


why not run backups?
run the 1.12 self's but replace the disc .ff with the modded ne.
ohh and send me ur debug prestige hack eboot bro.. "@
03-13-2011, 04:07 AM #51
Alfa
Banned
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.


the .self file injects the gsc's through the .self its weird it must do something like that cuz i have deleted every .gsc and renamed it and everything was still patched

also i tried renaming the file extensions so i used .csc instead of .gsc and that didnt work either so i have NO idea how they did this but there must be a way around it
03-13-2011, 04:10 AM #52
Okami
Known As Yukuku
Originally posted by niccrx View Post
why not run backups?
run the 1.12 self's but replace the disc .ff with the modded ne.
ohh and send me ur debug prestige hack eboot bro.. "@


thats what im saying but i need a modded pkg of mw2 1.12 so i can run the backup

---------- Post added at 11:10 PM ---------- Previous post was at 11:07 PM ----------

Originally posted by niccrx View Post
why not run backups?
run the 1.12 self's but replace the disc .ff with the modded ne.
ohh and send me ur debug prestige hack eboot bro.. "@


like this 1.11
You must login or register to view this content.
03-13-2011, 04:25 AM #53
The backups idea would work.

The problem being no one can get MW2 to run as a backup.
Maybe someone with an External HDD can help?
03-13-2011, 04:43 AM #54
Okami
Known As Yukuku
Originally posted by Ihatecompvir View Post
The backups idea would work.

The problem being no one can get MW2 to run as a backup.
Maybe someone with an External HDD can help?


pkg works Happy

---------- Post added at 11:29 PM ---------- Previous post was at 11:28 PM ----------

Originally posted by Ihatecompvir View Post
The backups idea would work.

The problem being no one can get MW2 to run as a backup.
Maybe someone with an External HDD can help?


heres mw2 1.12 pkg for geohot backup
You must login or register to view this content.

---------- Post added at 11:31 PM ---------- Previous post was at 11:29 PM ----------

now i need 1.12 modded patch to test it

---------- Post added at 11:38 PM ---------- Previous post was at 11:31 PM ----------

k got one testing now

---------- Post added at 11:43 PM ---------- Previous post was at 11:38 PM ----------

Originally posted by Ihatecompvir View Post
The backups idea would work.

The problem being no one can get MW2 to run as a backup.
Maybe someone with an External HDD can help?


didint work for me :(
03-13-2011, 04:45 AM #55
emsp
Space Ninja
Originally posted by Ihatecompvir View Post
The backups idea would work.

The problem being no one can get MW2 to run as a backup.
Maybe someone with an External HDD can help?


The new mutiman works for mw2

The following user thanked emsp for this useful post:

Okami

Copyright © 2026, NextGenUpdate.
All Rights Reserved.

Gray NextGenUpdate Logo