s1-scripts-dev/raw/maps/mp/_events.gsc
2025-05-21 16:23:17 +02:00

1850 lines
57 KiB
Plaintext

#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
init()
{
gameType = GetDvar( "g_gametype" );
gameTypeRow = 0;
gameTypeColumn = [];
gameTypeColumn["dm"] = 4;
gameTypeColumn["war"] = 5;
gameTypeColumn["sd"] = 6;
gameTypeColumn["dom"] = 7;
gameTypeColumn["conf"] = 8;
gameTypeColumn["sr"] = 9;
gameTypeColumn["infect"] = 10;
gameTypeColumn["gun"] = 11;
gameTypeColumn["ctf"] = 12;
gameTypeColumn["horde"] = 13;
gameTypeColumn["twar"] = 14;
gameTypeColumn["hp"] = 15;
gameTypeColumn["ball"] = 16;
// register all XP events
while( true )
{
if( !IsDefined(gameTypeColumn[gameType]) )
gameType = "war";
name = TableLookupByRow( "mp/xp_event_table.csv", gameTypeRow, 0 );
playSplash = TableLookupByRow( "mp/xp_event_table.csv", gameTypeRow, 1 );
allowPlayerScore = TableLookupByRow( "mp/xp_event_table.csv", gameTypeRow, 2 );
value = TableLookupByRow( "mp/xp_event_table.csv", gameTypeRow, gameTypeColumn[ gameType ] );
if( !IsDefined( name ) || name == "" )
break;
if( name == "win" || name == "loss" || name == "tie" )
{
value = float( value );
}
else
{
value = int( value );
}
if( value != -1 )
{
allowPlayerScore = int( allowPlayerScore );
playSplash = int( playSplash );
maps\mp\gametypes\_rank::registerXPEventInfo( name, value, allowPlayerScore, playSplash );
}
gameTypeRow++;
}
level.numKills = 0;
level thread onPlayerConnect();
}
onPlayerConnect()
{
while( true )
{
level waittill( "connected", player );
player.killedPlayers = [];
player.killedPlayersCurrent = [];
player.damagedPlayers = [];
player.killedBy = [];
player.lastKilledBy = undefined;
player.recentKillCount = 0;
player.lastKillTime = 0;
player.bulletStreak = 0;
player.lastCoopStreakTime = 0;
}
}
killedPlayer( killId, victim, weapon, meansOfDeath, eInflictor )
{
level.numKills++;
victimGuid = victim.guid;
victimKillStreak = victim.pers[ "cur_kill_streak" ];
myGuid = self.guid;
curTime = getTime();
if ( isBulletDamage( meansOfDeath ) )
{
if( self.lastKillTime == curTime )
{
self.bulletStreak++;
}
else
{
self.bulletStreak = 1;
}
}
else
{
self.bulletStreak = 0;
}
self.lastKillTime = getTime();
self.lastKilledPlayer = victim;
self.modifiers = [];
self.damagedPlayers[victimGuid] = undefined; // a player is either damaged, or killed; never both
// track multi kills
self thread updateRecentKills( killId, weapon );
if( !isKillstreakWeapon( weapon ) )
{
if( weapon == "none" )
return false;
if( isDefined( victim.throwingGrenade ) )
{
shortGrenade = maps\mp\_utility::strip_suffix( victim.throwingGrenade, "_lefthand" );
if( shortGrenade == "frag_grenade_mp" )
self.modifiers["cooking"] = true;
}
if( WeaponInventoryType(weapon) == "primary" )
{
self.segments["killDistanceTotal"] += Distance2D( self.origin, victim.origin );
self.segments["killDistanceCount"]++;
}
if( meansOfDeath == "MOD_HEAD_SHOT" )
self headShotEvent( killId, weapon, meansOfDeath );
if( level.numKills == 1 )
self firstBloodEvent( killId, weapon, meansOfDeath );
if( level.teamBased && ( (curTime - victim.lastKillTime) < 3000) && (victim.lastkilledplayer != self) )
self avengedPlayerEvent( killId, weapon, meansOfDeath );
if( !isAlive( self ) && (self != victim) && isDefined(self.deathtime) && ( (self.deathtime + 1200) < getTime() ) )
self postDeathKillEvent( killId );
if( self.pers["cur_death_streak"] > 3 )
self comeBackEvent( killId, weapon, meansOfDeath );
if ( isDefined(self.assistedSuicide) && self.assistedSuicide )
self assistedSuicideEvent( killId, weapon, meansOfDeath );
if( isLongShot( self, weapon, meansOfDeath, victim ) )
self longShotEvent( killId, weapon, meansOfDeath );
if( isResuce( victim, curTime ) )
self defendedPlayerEvent( killId, weapon, meansOfDeath );
if( (victimKillStreak > 0) && isBuzzKillEvent( victim ) )
self buzzKillEvent( killId, victim, weapon, meansOfDeath );
if( isOneShotKill( victim, weapon, meansOfDeath ) )
self oneShotKillEvent( killId, weapon, meansOfDeath );
if( isDefined(self.lastKilledBy) && (self.lastKilledBy == victim) )
{
self revengeEvent( killId );
}
if( victim.iDFlags & level.iDFLAGS_PENETRATION )
self bulletPenetrationEvent( killId, weapon );
if( isPointBlank( victim, meansOfDeath ) )
self pointBlankEvent( killId, weapon, meansOfDeath );
if( IsDefined(weapon) && (weapon == "boost_slam_mp") )
self boostSlamKillEvent( killId, weapon, meansOfDeath );
if( self.health < 20 && self.health > 0 ) // not near death if you are dead
self nearDeathKillEvent( weapon, meansOfDeath );
if( self.isSiliding )
{
self sprintSlideKillEvent( weapon, meansOfDeath );
self camoSprintSlideKillEvent( weapon, meansOfDeath );
}
if( self isFlashed() )
self flashedKillEvent( weapon, meansOfDeath );
if( isThinkFast( weapon, meansOfDeath ) )
self thinkFastEvent();
if( self.bulletStreak == 2 )
self multiKillOneBulletEvent();
if( isBackStabEvent( victim, weapon, meansOfDeath ) )
self backStabEvent();
if( isThrowBackEvent( victim, weapon, meansOfDeath ) )
self throwBackKillEvent();
if( IsDefined(self.pickedUpWeaponFrom[weapon]) && (self.pickedUpWeaponFrom[weapon] == victim) && !isMeleeMOD(meansOfDeath) )
self takeAndKillEvent();
if( IsDefined(weapon) && (weapon == "iw5_carrydrone_mp") )
self killWithBallEvent();
if ( IsDefined(victim) && victim _hasPerk("specialty_ballcarrier") )
self killedBallCarrierEvent();
if ( IsDefined( self.exoMostRecentTimeDeciSeconds["exo_dodge"] ) && ( 20 > ( getTimePassedDeciSecondsIncludingRounds() - self.exoMostRecentTimeDeciSeconds["exo_dodge"] ) ) )
{
self killAfterDodgeEvent(weapon);
}
self checkHighJumpEvents( victim, killId, weapon, meansOfDeath, eInflictor );
self checkHigherRankKillEvents( victim );
self checkWeaponSpecificKill( victim, weapon, meansOfDeath );
}
self checkStreakingEvents( victim );
if( !isDefined( self.killedPlayers[victimGuid] ) )
self.killedPlayers[victimGuid] = 0;
if( !isDefined( self.killedPlayersCurrent[victimGuid] ) )
self.killedPlayersCurrent[victimGuid] = 0;
if( !isDefined( victim.killedBy[myGuid] ) )
victim.killedBy[myGuid] = 0;
self.killedPlayers[victimGuid]++;
self.killedPlayersCurrent[victimGuid]++;
victim.killedBy[myGuid]++;
victim.lastKilledBy = self;
}
isPointBlank( victim, meansOfDeath )
{
if( isBulletDamage( meansOfDeath ) )
{
attackerPosition = self.origin;
weapDistSq = 96 * 96;
if( isDefined( victim.attackerPosition ) )
attackerPosition = victim.attackerPosition;
if( DistanceSquared(attackerPosition, victim.origin) < weapDistSq )
return true;
}
return false;
}
pointBlankEvent( killId, weapon, meansOfDeath )
{
self incPlayerStat( "pointblank", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "pointblank", self, weapon, undefined, meansOfDeath );
if(IsDefined(weapon))
{
baseWeapon = getBaseWeaponName( weapon );
if( isLootWeapon( baseWeapon ) )
baseWeapon = maps\mp\gametypes\_class::getBaseFromLootVersion( baseWeapon );
weaponClass = self maps\mp\gametypes\_missions::get_challenge_weapon_class(weapon, baseWeapon);
//camo challenge
if ( IsDefined (level.challengeInfo["ch_pointblank_" + baseWeapon ] ) )
self maps\mp\gametypes\_missions::processChallenge( "ch_pointblank_" + baseWeapon );
}
}
killedPlayerEvent( victim, weapon, sMeansOfDeath )
{
self incPlayerStat( "kills", 1 );
self incPersStat( "kills", 1 );
self.kills = self getPersStat( "kills" );
self maps\mp\gametypes\_persistence::statSetChild( "round", "kills", self.kills );
self updatePersRatio( "kdRatio", "kills", "deaths" );
event = "kill";
switch( weapon )
{
case "killstreak_orbital_laser_mp": // orbital laser
case "orbital_laser_fov_mp": // orbital laser
event = "vulcan_kill";
break;
case "warbird_remote_turret_mp": // warbird
case "warbird_player_turret_mp": // warbird
case "warbird_missile_mp": // warbird
case "paint_missile_killstreak_mp": // warbird
event = "warbird_kill";
break;
case "orbitalsupport_105mm_mp": // paladin
case "orbitalsupport_40mm_mp": // paladin
case "orbitalsupport_40mmbuddy_mp": // paladin
case "orbitalsupport_big_turret_mp": // paladin
case "orbitalsupport_medium_turret_mp": // paladin
case "orbitalsupport_small_turret_mp": // paladin
case "orbitalsupport_missile_mp": // paladin
event = "paladin_kill";
break;
case "airdrop_trap_explosive_mp": // care package trap
event = "airdrop_trap_kill";
break;
case "orbital_carepackage_pod_mp": // care package drop
event = "airdrop_kill";
break;
case "remotemissile_projectile_mp": // missile strike
case "remotemissile_projectile_gas_mp": // missile strike
case "remotemissile_projectile_cluster_parent_mp": // missile strike
case "remotemissile_projectile_cluster_child_mp": // missile strike
case "remotemissile_projectile_cluster_child_hellfire_mp": // missile strike
case "remotemissile_projectile_secondary_mp": // missile strike
case "killstreak_strike_missile_gas_mp": // missile strike
event = "missile_strike_kill";
break;
case "remote_turret_mp": // sentry gun
case "remote_energy_turret_mp": // sentry gun
case "sentry_minigun_mp": // sentry gun
case "killstreakmahem_mp": // sentry gun
case "turretheadmg_mp": // sentry gun
case "turretheadenergy_mp": // sentry gun
case "turretheadrocket_mp": // sentry gun
event = "sentry_gun_kill";
break;
case "stealth_bomb_mp": // strafing run
case "airstrike_missile_mp": // strafing run
case "orbital_carepackage_pod_plane_mp": // strafing run
event = "strafing_run_kill";
break;
case "drone_assault_remote_turret_mp": // assault drone
case "ugv_missile_mp": // assault drone
case "assaultdrone_c4_mp": // assault drone
event = "assault_drone_kill";
break;
case "juggernaut_sentry_mg_mp": // goliath
case "iw5_juggernautrockets_mp": // goliath
case "iw5_exoxmgjugg_mp_akimbo": // goliath
case "iw5_juggtitan45_mp": // goliath
case "iw5_exominigun_mp": // goliath
case "iw5_mechpunch_mp": // goliath
case "playermech_rocket_mp": // goliath
case "killstreak_goliathsd_mp": // goliath
case "orbital_carepackage_droppod_mp": // goliath
event = "goliath_kill";
break;
case "detroit_tram_turret_mp": // detroit turret
case "dam_turret_mp": // dam turret
case "killstreak_terrace_mp": // Terrace sniper
case "killstreak_solar_mp": // Solar beam
case "refraction_turret_mp": // Refraction turrets
case "killstreak_comeback_mp": // Comeback Tanks
case "mp_laser2_core": // Laser2 water
event = "map_killstreak_kill";
break;
}
if( event != "kill" )
{
self incPlayerStat( event, 1 );
self maps\mp\gametypes\_missions::ch_streak_kill( event );
}
if ( level.practiceRound )
self thread practiceRoundKillEvent( victim, event, weapon, sMeansOfDeath );
level thread maps\mp\gametypes\_rank::awardGameEvent( event, self, weapon, victim, sMeansOfDeath );
}
practiceRoundDialogValid()
{
return ( !IsDefined( self.next_pr_dialog_time ) || GetTime() > self.next_pr_dialog_time );
}
practiceRoundDialogPlayed()
{
self.next_pr_dialog_time = GetTime() + RandomIntRange( 20000, 40000 );
}
practiceRoundKillEvent( victim, event, weapon, sMeansOfDeath )
{
self endon( "disconnect" );
level endon( "game_ended" );
if ( IsBot( self ) )
return;
self playlocalsound( "ui_practice_round_kill" );
dialog_delay = 0.5;
// New personal best?
if ( !IsDefined( self.best_pr_kills ) )
self.best_pr_kills = self GetCommonPlayerData( "bests", "kills" );
if ( ( self.best_pr_kills > 0 ) && ( self.kills > self.best_pr_kills ) )
{
self practiceRoundDialogPlayed();
wait ( dialog_delay );
self leaderDialogOnPlayer( "ptr_new_best" );
self.best_pr_kills = 0; // So it never happens again this game.
}
else if ( event == "kill" && !isMeleeMOD( sMeansOfDeath ) )
{
if ( sMeansOfDeath == "MOD_HEAD_SHOT" )
{
self practiceRoundDialogPlayed();
wait ( dialog_delay );
self leaderDialogOnPlayer( "ptr_headshot" );
}
else
{
if ( !practiceRoundDialogValid() )
return;
practiceRoundDialogPlayed();
wait ( dialog_delay );
self leaderDialogOnPlayer( "ptr_greatshot" );
}
}
}
practiceRoundAssistEvent( victim )
{
self endon( "disconnect" );
level endon( "game_ended" );
if ( IsBot( self ) )
return;
dialog_delay = 0.5;
practiceRoundDialogPlayed();
wait ( dialog_delay );
self leaderDialogOnPlayer( "ptr_assist" );
}
isThinkFast( weapon, meansOfDeath )
{
if( meansOfDeath == "MOD_IMPACT" || meansOfDeath == "MOD_HEAD_SHOT" )
{
if( isThinkFastWeapon(weapon) )
return true;
}
return false;
}
isThinkFastWeapon(weapon)
{
switch( weapon )
{
case "semtex_mp":
case "frag_grenade_mp":
case "stun_grenade__mp":
case "stun_grenade_var_mp":
case "emp_grenade_mp":
case "emp_grenade_var_mp":
case "paint_grenade_mp":
case "paint_grenade_var_mp":
case "smoke_grenade_mp":
case "smoke_grenade_var_mp":
return true;
default:
return false;
}
}
thinkFastEvent()
{
self incPlayerStat( "think_fast", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "think_fast", self );
}
boostSlamKillEvent( killId, weapon, meansOfDeath )
{
self incPlayerStat( "boostslamkill", 1 );
self thread maps\mp\gametypes\_missions::processChallenge( "ch_limited_lookoutbelow", 1 );
self thread maps\mp\gametypes\_missions::processChallenge( "ch_exomech_hot", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "boostslamkill", self, weapon, undefined, meansOfDeath );
}
earnedKillStreakEvent( streakName, streakVal, modules, slotIndex )
{
self incPlayerStat( streakName + "_earned", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( streakName + "_earned", self );
self thread maps\mp\gametypes\_hud_message::killstreakSplashNotify( streakName, streakVal, undefined, modules, slotIndex );
self maps\mp\gametypes\_missions::processChallengeDaily( 22, streakName, undefined );
self maps\mp\gametypes\_missions::processChallengeDaily( 23, streakName, undefined );
}
bulletPenetrationEvent( killId, weapon )
{
self incPlayerStat( "bulletpenkills", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "bulletpen", self );
if(IsDefined(weapon))
{
baseWeapon = getBaseWeaponName( weapon );
if( isLootWeapon( baseWeapon ) )
baseWeapon = maps\mp\gametypes\_class::getBaseFromLootVersion( baseWeapon );
weaponClass = self maps\mp\gametypes\_missions::get_challenge_weapon_class(weapon, baseWeapon);
if(weaponClass == "weapon_sniper")
{
if( IsDefined( level.challengeInfo["ch_penetrate_" + baseWeapon ] ) )
self maps\mp\gametypes\_missions::processChallenge( "ch_penetrate_" + baseWeapon );
}
}
self maps\mp\gametypes\_missions::processChallenge( "ch_boot_xray" );
}
multiKillOneBulletEvent()
{
self incPlayerStat( "multiKillOneBullet", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "multiKillOneBullet", self );
}
checkHighJumpEvents( victim, killId, weapon, meansOfDeath, eInflictor )
{
if( IsDefined( eInflictor ) && IsDefined( eInflictor.ch_crossbow_player_jumping ) )
attackerIsJumping = eInflictor.ch_crossbow_player_jumping;
else
attackerIsJumping = self IsHighJumping();
if( IsDefined( eInflictor ) && IsDefined( eInflictor.ch_crossbow_victim_jumping ) )
victimIsJumping = eInflictor.ch_crossbow_victim_jumping;
else
victimIsJumping = victim IsHighJumping();
if( attackerIsJumping && victimIsJumping )
self airToAirEvent( killId, weapon, meansOfDeath );
if( attackerIsJumping && !victimIsJumping )
self airToGroundEvent( killId, weapon, meansOfDeath );
if( !attackerIsJumping && victimIsJumping )
self groundToAirEvent( killId, weapon, meansOfDeath );
}
checkWeaponSpecificKill( victim, weapon, meansOfDeath )
{
if( maps\mp\gametypes\_weapons::isRiotShield( weapon ) || (weapon == maps\mp\_exo_shield::get_exo_shield_weapon()) )
riotShieldKillEvent( weapon, meansOfDeath );
if( IsSubStr( weapon, "exoknife_mp" ) )
exoKnifeKillEvent( weapon, meansOfDeath, victim );
}
exoKnifeKillEvent( weapon, meansOfDeath, victim )
{
self incPlayerStat( "exo_knife_kill", 1 );
if( IsDefined(victim.wasRecall) && victim.wasRecall )
{
self incPlayerStat( "exo_knife_recall_kill", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "exo_knife_recall_kill", self, weapon, undefined, meansOfDeath );
self maps\mp\gametypes\_missions::processChallenge( "ch_humiliation_boomerang" );
}
else
{
level thread maps\mp\gametypes\_rank::awardGameEvent( "exo_knife_kill", self, weapon, undefined, meansOfDeath );
}
}
nearDeathKillEvent( weapon, meansOfDeath )
{
self incPlayerStat( "near_death_kill", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "near_death_kill", self, weapon, undefined, meansOfDeath );
}
sprintSlideKillEvent( weapon, meansOfDeath )
{
self incPlayerStat( "slide_kill", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "slide_kill", self, weapon, undefined, meansOfDeath );
}
flashedKillEvent( weapon, meansOfDeath )
{
self incPlayerStat( "flash_kill", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "flash_kill", self, weapon, undefined, meansOfDeath );
}
riotShieldKillEvent( weapon, meansOfDeath )
{
self incPlayerStat( "riot_kill", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "riot_kill", self, weapon, undefined, meansOfDeath );
}
airToAirEvent( killId, weapon, meansOfDeath )
{
self incPlayerStat( "air_to_air_kill", 1 );
self thread maps\mp\gametypes\_missions::processChallenge( "ch_limited_acepilot", 1 );
self thread maps\mp\gametypes\_missions::processChallenge( "ch_exomech_redbaron", 1 );
baseWeapon = getBaseWeaponName( weapon );
if( isLootWeapon( baseWeapon ) )
baseWeapon = maps\mp\gametypes\_class::getBaseFromLootVersion( baseWeapon );
weaponClass = self maps\mp\gametypes\_missions::get_challenge_weapon_class(weapon, baseWeapon);
if( isMeleeMOD(meansOfDeath) )
{
self incPlayerStat( "melee_air_to_air", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "melee_air_to_air", self, weapon, undefined, meansOfDeath );
}
else
{
level thread maps\mp\gametypes\_rank::awardGameEvent( "air_to_air_kill", self, weapon, undefined, meansOfDeath );
// camo check smg
if ( WeaponClass=="weapon_smg" || WeaponClass=="weapon_shotgun")
if(IsDefined( level.challengeInfo[ "ch_dogfight_" + baseWeapon ] ) )
self maps\mp\gametypes\_missions::processChallenge( "ch_dogfight_" + baseWeapon);
}
}
airToGroundEvent( killId, weapon, meansOfDeath )
{
self incPlayerStat( "air_to_ground_kill", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "air_to_ground_kill", self, weapon, undefined, meansOfDeath );
self thread maps\mp\gametypes\_missions::processChallenge( "ch_exomech_buzz" );
baseWeapon = getBaseWeaponName( weapon );
if( isLootWeapon( baseWeapon ) )
baseWeapon = maps\mp\gametypes\_class::getBaseFromLootVersion( baseWeapon );
weaponClass = self maps\mp\gametypes\_missions::get_challenge_weapon_class(weapon, baseWeapon);
// camo unlocks for assault and heavy
if( WeaponClass == "weapon_assault" || WeaponClass == "weapon_heavy" || IsSubStr( weapon, "exocrossbow" ) )
{
if( IsSubStr( baseWeapon, "dlcgun" ) && weaponClass == "weapon_assault" )
self maps\mp\gametypes\_missions::processChallenge( "ch_tier2_1_" + baseWeapon );
else
self maps\mp\gametypes\_missions::processChallenge( "ch_strafe_" + baseWeapon );
}
}
groundToAirEvent( killId, weapon, meansOfDeath )
{
self incPlayerStat( "ground_to_air_kill", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "ground_to_air_kill", self, weapon, undefined, meansOfDeath );
self thread maps\mp\gametypes\_missions::processChallenge( "ch_exomech_pull" );
// camo
baseWeapon = getBaseWeaponName( weapon );
if( isLootWeapon( baseWeapon ) )
baseWeapon = maps\mp\gametypes\_class::getBaseFromLootVersion( baseWeapon );
weaponClass = maps\mp\gametypes\_missions::get_challenge_weapon_class( weapon, baseWeapon );
if( weaponClass == "weapon_heavy" || IsSubStr( weapon, "exocrossbow" ) )
{
if( isDefined( level.challengeInfo["ch_skeet_" + baseWeapon] ) )
self maps\mp\gametypes\_missions::processChallenge( "ch_skeet_" + baseWeapon );
}
}
isOneShotKill( victim, weapon, meansOfDeath )
{
if( victim.attackers.size != 1 )
return false;
if( !IsDefined(victim.attackers[self.guid]) )
return false;
if( isMeleeMOD(meansOfDeath) )
return false;
if( getTime() != victim.attackerData[self.guid].firstTimeDamaged )
return false;
weaponClass = getWeaponClass( weapon );
if( (weaponClass == "weapon_sniper") || (weaponClass == "weapon_shotgun") )
return true;
return false;
}
isLongShot( attacker, weapon, meansOfDeath, victim )
{
if( IsDefined(victim.agentBody) )
return false;
attackerPosition = self.origin;
if( isDefined( victim.attackerPosition ) )
attackerPosition = victim.attackerPosition;
if( isAlive( attacker ) &&
!attacker isUsingRemote() &&
( meansOfDeath == "MOD_RIFLE_BULLET" || meansOfDeath == "MOD_PISTOL_BULLET" || meansOfDeath == "MOD_HEAD_SHOT" || IsSubStr( weapon, "exoknife_mp" ) || IsSubStr( weapon, "exocrossbow" ) || IsSubStr( weapon, "m990" ) ) &&
!isKillstreakWeapon( weapon ) && !isDefined( attacker.assistedSuicide ) )
{
thisWeaponClass = getWeaponClass( weapon );
switch( thisWeaponClass )
{
case "weapon_pistol":
weapDist = 800;
break;
case "weapon_smg":
weapDist = 1200;
break;
case "weapon_assault":
case "weapon_heavy":
weapDist = 1500;
break;
case "weapon_sniper":
weapDist = 2000;
break;
case "weapon_shotgun":
weapDist = 500;
break;
case "weapon_projectile":
default:
weapDist = 1536;
break;
}
if( IsSubStr( weapon, "exoknife_mp" ) || IsSubStr( weapon, "exocrossbow" ) ) // special case for spike drone and crossbow
weapDist = 1200;
weapDistSq = weapDist * weapDist;
if( DistanceSquared( attackerPosition, victim.origin ) > weapDistSq )
{
// if( attacker IsItemUnlocked( "specialty_holdbreath" ) && attacker _hasPerk( "specialty_holdbreath" ) )
// attacker maps\mp\gametypes\_missions::processChallenge( "ch_longdistance" );
return true;
}
}
return false;
}
isResuce( victim, curTime )
{
if( !level.teamBased )
return false;
foreach( guid, damageTime in victim.damagedPlayers )
{
if( (guid != self.guid) && (curTime - damageTime < 500) )
return true;
}
return false;
}
longShotEvent( killId, weapon, meansOfDeath )
{
self.modifiers["longshot"] = true;
self incPlayerStat( "longshots", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "longshot", self, weapon, undefined, meansOfDeath );
self thread maps\mp\_matchdata::logKillEvent( killId, "longshot" );
}
headShotEvent( killId, weapon, meansOfDeath )
{
self.modifiers["headshot"] = true;
self incPersStat( "headshots", 1 );
self incPlayerStat( "headshots", 1 );
self maps\mp\gametypes\_persistence::statSetChild( "round", "headshots", clampToShort( self.pers["headshots"] ) );
self.headshots = self getPersStat( "headshots" );
level thread maps\mp\gametypes\_rank::awardGameEvent( "headshot", self, weapon, undefined, meansOfDeath );
self thread maps\mp\_matchdata::logKillEvent( killId, "headshot" );
self maps\mp\gametypes\_missions::processChallenge( "ch_limited_headhunter" );
}
isThrowBackEvent( victim, weapon, meansOfDeath )
{
if( !IsExplosiveDamageMOD( meansOfDeath ) )
return false;
if( !isStrStart( weapon, "frag_" ) )
return false;
if( IsDefined( victim ) && IsDefined( victim.explosiveInfo ) && IsDefined( victim.explosiveInfo["throwbackKill"] ) && victim.explosiveInfo["throwbackKill"] )
return true;
return false;
}
throwBackKillEvent()
{
self incPlayerStat( "throwback_kill", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "throwback_kill", self );
}
fourPlayEvent()
{
self incPlayerStat( "four_play", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "four_play", self );
}
avengedPlayerEvent( killId, weapon, meansOfDeath )
{
self.modifiers["avenger"] = true;
self incPlayerStat( "avengekills", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "avenger", self, weapon, undefined, meansOfDeath );
self thread maps\mp\_matchdata::logKillEvent( killId, "avenger" );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_avenger" );
}
assistedSuicideEvent( killId, weapon, meansOfDeath )
{
self.modifiers["assistedsuicide"] = true;
self incPlayerStat( "assistedsuicide", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "assistedsuicide", self, weapon, undefined, meansOfDeath );
self thread maps\mp\_matchdata::logKillEvent( killId, "assistedsuicide" );
}
defendedPlayerEvent( killId, weapon, meansOfDeath )
{
self.modifiers["defender"] = true;
self incPlayerStat( "rescues", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "defender", self, weapon, undefined, meansOfDeath );
self thread maps\mp\_matchdata::logKillEvent( killId, "defender" );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_savior" );
}
defendObjectiveEvent( victim, killId )
{
self incPlayerStat( "defends", 1 );
self incPersStat( "defends", 1 );
self maps\mp\gametypes\_persistence::statSetChild( "round", "defends", self.pers["defends"] );
level thread maps\mp\gametypes\_rank::awardGameEvent( "defend", self );
victim thread maps\mp\_matchdata::logKillEvent( killId, "assaulting" );
}
assaultObjectiveEvent( victim, killId )
{
self incPlayerStat( "assault", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "assault", self );
victim thread maps\mp\_matchdata::logKillEvent( killId, "defending" );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_attacker" );
self maps\mp\gametypes\_missions::processChallengeDaily( 7, undefined, undefined );
}
postDeathKillEvent( killId )
{
self.modifiers["posthumous"] = true;
self incPlayerStat( "posthumous", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "posthumous", self );
self thread maps\mp\_matchdata::logKillEvent( killId, "posthumous" );
self maps\mp\gametypes\_missions::processChallenge( "ch_humiliation_afterlife" );
// camo
baseWeapon = getBaseWeaponName( self GetCurrentWeapon() );
if (baseWeapon == "iw5_microdronelauncher" || baseWeapon == "iw5_exocrossbow")
if(IsDefined( level.challengeInfo[ "ch_afterlife_" + baseWeapon ] ) )
self maps\mp\gametypes\_missions::processChallenge( "ch_afterlife_" + baseWeapon);
}
isBackStabEvent( victim, weapon, meansOfDeath )
{
if( !isMeleeMOD( meansOfDeath ) )
return false;
if( maps\mp\gametypes\_weapons::isRiotShield( weapon ) || (weapon == maps\mp\_exo_shield::get_exo_shield_weapon()) )
return false;
anglesOnDeath = victim GetPlayerAngles();
anglesOnKill = self GetPlayerAngles();
angleDiff = AngleClamp180( anglesOnDeath[1] - anglesOnKill[1] );
if( abs(angleDiff) < 75 )
return true;
return false;
}
backStabEvent( killId )
{
self incPlayerStat( "backstab", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "backstab", self );
self maps\mp\gametypes\_missions::processChallenge( "ch_humiliation_backstab" );
}
revengeEvent( killId )
{
self.modifiers["revenge"] = true;
self.lastKilledBy = undefined;
self incPlayerStat( "revengekills", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "revenge", self );
self thread maps\mp\_matchdata::logKillEvent( killId, "revenge" );
self maps\mp\gametypes\_missions::processChallenge( "ch_humiliation_revenge" );
}
multiKillEvent( killId, killCount, weapon, was_ads )
{
assert( killCount > 1 );
if( !IsDefined( was_ads ) )
was_ads = false;
weapon_class = maps\mp\gametypes\_missions::get_challenge_weapon_class( weapon );
baseWeapon = getBaseWeaponName( weapon );
if( isLootWeapon( baseWeapon ) )
baseWeapon = maps\mp\gametypes\_class::getBaseFromLootVersion( baseWeapon );
shortWeaponName = "";
if( string_starts_with( baseWeapon, "iw5_" ) )
shortWeaponName = GetSubStr( baseWeapon, 4 );
switch( killCount )
{
case 2:
level thread maps\mp\gametypes\_rank::awardGameEvent( "doublekill", self );
self incPlayerStat( "doublekill", 1 );
self maps\mp\gametypes\_missions::processChallenge( "ch_killer_double" );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_double" );
if( weapon_class == "weapon_smg" || weapon_class == "weapon_shotgun" || weapon_class == "weapon_sniper" || baseWeapon == "iw5_microdronelauncher" || baseWeapon == "iw5_exocrossbow" )
if( IsDefined( level.challengeInfo[ "ch_double_" + baseWeapon ] ) )
self maps\mp\gametypes\_missions::processChallenge( "ch_double_" + baseWeapon );
if( IsDefined( level.challengeInfo[ "ch_attach_unlock_double_" + shortWeaponName] ) )
self maps\mp\gametypes\_missions::processChallenge( "ch_attach_unlock_double_" + shortWeaponName );
break;
case 3:
level thread maps\mp\gametypes\_rank::awardGameEvent( "triplekill", self );
level thread teamPlayerCardSplash( "callout_3xkill", self );
self incPlayerStat( "triplekill", 1 );
self maps\mp\gametypes\_missions::processChallenge( "ch_killer_triple" );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_triple" );
if( maps\mp\gametypes\_missions::isAtBrinkOfDeath() )
self maps\mp\gametypes\_missions::processChallenge( "ch_precision_sitcrit" );
if( ( IsDefined( weapon_class ) && ( weapon_class == "weapon_smg" || weapon_class == "weapon_heavy" ) ) && was_ads == false )
self maps\mp\gametypes\_missions::processChallenge( "ch_precision_hello" );
break;
case 4:
level thread maps\mp\gametypes\_rank::awardGameEvent( "fourkill", self );
level thread teamPlayerCardSplash( "callout_4xkill", self );
self incPlayerStat( "fourkill", 1 );
self maps\mp\gametypes\_missions::processChallenge( "ch_killer_feed" );
self maps\mp\gametypes\_missions::processChallenge( "ch_killer_fury" );
self maps\mp\gametypes\_missions::processChallenge( "ch_limited_bloodshed_fury" );
break;
case 5:
level thread maps\mp\gametypes\_rank::awardGameEvent( "fivekill", self );
level thread teamPlayerCardSplash( "callout_5xkill", self );
self incPlayerStat( "fivekill", 1 );
self maps\mp\gametypes\_missions::processChallenge( "ch_killer_frenzy" );
break;
case 6:
level thread maps\mp\gametypes\_rank::awardGameEvent( "sixkill", self );
level thread teamPlayerCardSplash( "callout_6xkill", self );
self incPlayerStat( "sixkill", 1 );
self maps\mp\gametypes\_missions::processChallenge( "ch_killer_super" );
break;
case 7:
level thread maps\mp\gametypes\_rank::awardGameEvent( "sevenkill", self );
level thread teamPlayerCardSplash( "callout_7xkill", self );
self incPlayerStat( "sevenkill", 1 );
self maps\mp\gametypes\_missions::processChallenge( "ch_killer_mega" );
break;
case 8:
level thread maps\mp\gametypes\_rank::awardGameEvent( "eightkill", self );
level thread teamPlayerCardSplash( "callout_8xkill", self );
self incPlayerStat( "eightkill", 1 );
self maps\mp\gametypes\_missions::processChallenge( "ch_killer_ultra" );
break;
default:
level thread maps\mp\gametypes\_rank::awardGameEvent( "multikill", self );
thread teamPlayerCardSplash( "callout_9xpluskill", self );
self incPlayerStat( "multikill", 1 );
self maps\mp\gametypes\_missions::processChallenge( "ch_killer_chain" );
break;
}
self thread maps\mp\_matchdata::logMultiKill( killId, killCount );
}
takeAndKillEvent()
{
self incPlayerStat( "take_and_kill", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "take_and_kill", self );
self maps\mp\gametypes\_missions::processChallenge( "ch_humiliation_backfire" );
}
killedBallCarrierEvent()
{
self incPlayerStat( "killedBallCarrier", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "killedBallCarrier", self );
}
setUplinkStats()
{
uplinks = getPlayerStat( "fieldgoal" ) + ( getPlayerStat( "touchdown" ) * 2 );
self maps\mp\gametypes\_persistence::statSetChild( "round", "captures", uplinks );
self setExtraScore0( uplinks );
}
touchDownEvent(score)
{
self thread teamPlayerCardSplash( "callout_touchdown", self, undefined, score );
self incPlayerStat( "touchdown", 1 );
self setUplinkStats();
level thread maps\mp\gametypes\_rank::awardGameEvent( "touchdown", self );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_touchdown" );
self maps\mp\gametypes\_missions::processChallengeDaily( 13, score, undefined );
}
fieldGoalEvent(score)
{
self thread teamPlayerCardSplash( "callout_fieldgoal", self, undefined, score );
self incPlayerStat( "fieldgoal", 1 );
self setUplinkStats();
level thread maps\mp\gametypes\_rank::awardGameEvent( "fieldgoal", self );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_fieldgoal" );
self maps\mp\gametypes\_missions::processChallengeDaily( 13, score, undefined );
}
interceptionEvent()
{
self incPlayerStat( "interception", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "interception", self );
}
killWithBallEvent()
{
self incPlayerStat( "kill_with_ball", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "kill_with_ball", self );
}
ballScoreAssistEvent()
{
self incPlayerStat( "ball_score_assist", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "ball_score_assist", self );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_assist" );
}
passKillPickupEvent()
{
self incPlayerStat( "pass_kill_pickup", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "pass_kill_pickup", self );
}
flagPickUpEvent()
{
self thread teamPlayerCardSplash( "callout_flagpickup", self );
self incPlayerStat( "flagscarried", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "flag_pickup", self );
self thread maps\mp\_matchdata::logGameEvent( "pickup", self.origin );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_flag_carry" );
}
flagCaptureEvent()
{
self thread teamPlayerCardSplash( "callout_flagcapture", self );
self incPlayerStat( "flagscaptured", 1 );
self incPersStat( "captures", 1 );
self maps\mp\gametypes\_persistence::statSetChild( "round", "captures", self.pers["captures"] );
self setExtraScore0( self.pers[ "captures" ] );
level thread maps\mp\gametypes\_rank::awardGameEvent( "flag_capture", self );
self thread maps\mp\_matchdata::logGameEvent( "capture", self.origin );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_flag_capture" );
self maps\mp\gametypes\_missions::processChallengeDaily( 16, undefined, undefined );
}
flagReturnEvent()
{
self thread teamPlayerCardSplash( "callout_flagreturn", self );
self incPlayerStat( "flagsreturned", 1 );
self incPersStat( "returns", 1 );
self.assists = self.pers[ "returns" ];
self maps\mp\gametypes\_persistence::statSetChild( "round", "returns", self.pers["returns"] );
level thread maps\mp\gametypes\_rank::awardGameEvent( "flag_return", self );
self thread maps\mp\_matchdata::logGameEvent( "return", self.origin );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_flag_return" );
self maps\mp\gametypes\_missions::processChallengeDaily( 17, undefined, undefined );
}
killWithFlagEvent()
{
self incPlayerStat( "killsasflagcarrier", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "kill_with_flag", self );
}
killFlagCarrierEvent( killId )
{
self thread teamPlayerCardSplash( "callout_killflagcarrier", self );
self incPlayerStat( "flagcarrierkills", 1 );
self incPersStat( "defends", 1 );
self maps\mp\gametypes\_persistence::statSetChild( "round", "defends", self.pers["defends"] );
level thread maps\mp\gametypes\_rank::awardGameEvent( "kill_flag_carrier", self );
self thread maps\mp\_matchdata::logKillEvent( killId, "carrying" );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_flag_defend" );
}
killDeniedEvent( isTagOwner )
{
self incPlayerStat( "killsdenied", 1 );
self incPersStat( "denied", 1 );
self setExtraScore1( self.pers[ "denied" ] );
self maps\mp\gametypes\_persistence::statSetChild( "round", "denied", self.pers["denied"] );
event = "kill_denied";
if( isTagOwner )
{
event = "kill_denied_retrieved";
self incPlayerStat( "kill_denied_retrieved", 1 );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_save_yourself" );
}
level thread maps\mp\gametypes\_rank::awardGameEvent( event, self );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_denial" );
self maps\mp\gametypes\_missions::processChallengeDaily( 21, undefined, undefined );
}
killConfirmedEvent()
{
self incPlayerStat( "killsconfirmed", 1 );
self incPersStat( "confirmed", 1 );
self setExtraScore0( self.pers[ "confirmed" ] );
self maps\mp\gametypes\_persistence::statSetChild( "round", "confirmed", self.pers["confirmed"] );
level thread maps\mp\gametypes\_rank::awardGameEvent( "kill_confirmed", self );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_collector" );
self maps\mp\gametypes\_missions::processChallengeDaily( 4, undefined, undefined );
}
tagCollectorEvent()
{
self incPlayerStat( "tag_collector", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "tag_collector", self );
}
monitorTagCollector( player )
{
if( !IsPlayer(player) )
return;
player notify( "tagCollector" );
player endon( "tagCollector" );
if( !IsDefined(player.tagCollectorTotal) )
player.tagCollectorTotal = 0;
player.tagCollectorTotal++;
if( player.tagCollectorTotal > 2 )
{
player maps\mp\_events::tagCollectorEvent();
player.tagCollectorTotal = 0;
}
wait(2.5);
player.tagCollectorTotal = 0;
}
bombPlantEvent()
{
self incPlayerStat( "bombsplanted", 1 );
self incPersStat( "plants", 1 );
self maps\mp\gametypes\_persistence::statSetChild( "round", "plants", self.pers["plants"] );
self setExtraScore0( self.pers[ "plants" ] );
level thread teamPlayerCardSplash( "callout_bombplanted", self );
level thread maps\mp\gametypes\_rank::awardGameEvent( "plant", self );
self thread maps\mp\_matchdata::logGameEvent( "plant", self.origin );
}
bombDefuseEvent( defuseType )
{
self incPlayerStat( "bombsdefused", 1 );
self incPersStat( "defuses", 1 );
self maps\mp\gametypes\_persistence::statSetChild( "round", "defuses", self.pers["defuses"] );
self setExtraScore1( self.pers[ "defuses" ] );
level thread teamPlayerCardSplash( "callout_bombdefused", self );
if( (defuseType == "ninja_defuse") || (defuseType == "last_man_defuse") )
{
self incPlayerStat( defuseType, 1 );
if( defuseType == "last_man_defuse" )
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_ninja" );
}
level thread maps\mp\gametypes\_rank::awardGameEvent( defuseType, self );
self thread maps\mp\_matchdata::logGameEvent( "defuse", self.origin );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_bombdefuse" );
}
eliminatePlayerEvent( isLastPlayerAlive, victim )
{
self incPlayerStat( "elimination", 1 );
level thread teamPlayerCardSplash( "callout_eliminated", victim );
if( isLastPlayerAlive )
{
self incPlayerStat( "last_man_standing", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "last_man_standing", self );
}
else
{
level thread maps\mp\gametypes\_rank::awardGameEvent( "elimination", self );
}
}
reviveTagEvent( playerRevived )
{
self incPlayerStat( "sr_tag_revive", 1 );
self incPlayerStat( "killsdenied", 1 );
self incPersStat( "denied", 1 );
self maps\mp\gametypes\_persistence::statSetChild( "round", "denied", self.pers["denied"] );
self.assists = ( self.pers[ "denied" ] );
level thread teamPlayerCardSplash( "callout_tag_revive", playerRevived );
level thread maps\mp\gametypes\_rank::awardGameEvent( "sr_tag_revive", self );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_medic" );
}
eliminateTagEvent()
{
self incPlayerStat( "sr_tag_elimination", 1 );
self incPlayerStat( "killsconfirmed", 1 );
self incPersStat( "confirmed", 1 );
self maps\mp\gametypes\_persistence::statSetChild( "round", "confirmed", self.pers["confirmed"] );
level thread maps\mp\gametypes\_rank::awardGameEvent( "sr_tag_elimination", self );
}
bombDetonateEvent()
{
self incPlayerStat( "targetsdestroyed", 1 );
self incPersStat( "destructions", 1 );
self maps\mp\gametypes\_persistence::statSetChild( "round", "destructions", self.pers["destructions"] );
level thread maps\mp\gametypes\_rank::awardGameEvent( "destroy", self );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_destroyer" );
}
increaseGunLevelEvent()
{
self incPlayerStat( "levelup", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "gained_gun_score", self );
}
decreaseGunLevelEvent()
{
self incPlayerStat( "dejavu", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "dropped_gun_score", self );
}
setBackEnemyGunLevelEvent()
{
self incPlayerStat( "humiliation", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "dropped_enemy_gun_rank", self );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_regression" );
}
quickGunLevelEvent()
{
self incPlayerStat( "gunslinger", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "quick_gun_rank", self );
}
setBackFirstPlayerGunLevelEvent()
{
self incPlayerStat( "regicide", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "dropped_first_player_gun_rank", self );
}
firstInfectedEvent()
{
self incPlayerStat( "patientzero", 1 );
playSoundOnPlayers( "mp_enemy_obj_captured" );
level thread teamPlayerCardSplash( "callout_first_infected", self );
level thread maps\mp\gametypes\_rank::awardGameEvent( "first_infected", self );
self.patient_zero = 0;
}
finalSurvivorEvent()
{
self incPlayerStat( "omegaman", 1 );
playSoundOnPlayers( "mp_obj_captured" );
level thread teamPlayerCardSplash( "callout_final_survivor", self );
level thread maps\mp\gametypes\_rank::awardGameEvent( "final_survivor", self );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_survivor" );
}
gotInfectedEvent()
{
self incPlayerStat( "careless", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "got_infected", self );
}
plagueEvent()
{
self incPlayerStat( "plague", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "infected_plague", self );
}
infectedSurvivorEvent()
{
self incPlayerStat( "contagious", 1 );
level thread teamPlayerCardSplash( "callout_infected_survivor", self, "axis" );
level thread maps\mp\gametypes\_rank::awardGameEvent( "infected_survivor", self );
}
survivorEvent()
{
self incPlayerStat( "survivor", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "survivor", self );
}
domCaptureEvent( isOpeningMove )
{
self incPlayerStat( "pointscaptured", 1 );
self incPersStat( "captures", 1 );
self maps\mp\gametypes\_persistence::statSetChild( "round", "captures", self.pers["captures"] );
self setExtraScore0( self.pers[ "captures" ] );
event = "capture";
if( isOpeningMove )
{
event = "opening_move";
self incPlayerStat( "opening_move", 1 );
}
level thread maps\mp\gametypes\_rank::awardGameEvent( event, self );
self thread maps\mp\_matchdata::logGameEvent( "capture", self.origin );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_aggression" );
self maps\mp\gametypes\_missions::processChallengeDaily( 6, undefined, undefined );
}
domNeutralizeEvent()
{
level thread maps\mp\gametypes\_rank::awardGameEvent( "neutralize", self );
}
killWhileCapture( victim, killId )
{
self incPlayerStat( "assault", 1 );
self incPlayerStat( "kill_while_capture", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "kill_while_capture", self );
victim thread maps\mp\_matchdata::logKillEvent( killId, "defending" );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_defender" );
self maps\mp\gametypes\_missions::processChallengeDaily( 22, undefined, undefined );
}
secureHardPointEvent()
{
self incPlayerStat( "hp_secure", 1 );
self incPersStat( "captures", 1 );
self maps\mp\gametypes\_persistence::statSetChild( "round", "captures", self.pers["captures"] );
self setExtraScore0( self.pers["captures"] );
level thread teamPlayerCardSplash( "callout_hp_captured_by", self );
level thread maps\mp\gametypes\_rank::awardGameEvent( "hp_secure", self );
self thread maps\mp\_matchdata::logGameEvent( "capture", self.origin );
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype + "_aggression" );
}
firstBloodEvent( killId, weapon, meansOfDeath )
{
self.modifiers["firstblood"] = true;
self incPlayerStat( "firstblood", 1 );
self thread teamPlayerCardSplash( "callout_firstblood", self );
level thread maps\mp\gametypes\_rank::awardGameEvent( "firstblood", self, weapon, undefined, meansOfDeath );
self thread maps\mp\_matchdata::logKillEvent( killId, "firstblood" );
}
isBuzzKillEvent( victim )
{
foreach( streakName in victim.killstreaks )
{
if( maps\mp\killstreaks\_killstreaks::isSupportStreak( victim, streakName ) )
continue;
streakVal = maps\mp\killstreaks\_killstreaks::getStreakCost( streakName );
adrenaline = victim.adrenaline;
if( streakVal < adrenaline )
continue;
if( streakVal - adrenaline < 101 )
return true;
}
return false;
}
buzzKillEvent( killId, victim, weapon, meansOfDeath )
{
self.modifiers["buzzkill"] = victim.pers["cur_kill_streak"];
self incPlayerStat( "buzzkill", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "buzzkill", self, weapon, undefined, meansOfDeath );
self maps\mp\gametypes\_missions::processChallenge( "ch_humiliation_buzzkill" );
}
oneShotKillEvent( killId, weapon, meansOfDeath )
{
self.modifiers["oneshotkill"] = true;
self incPlayerStat( "oneshotkill", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "oneshotkill", self, weapon, undefined, meansOfDeath );
self maps\mp\gametypes\_missions::processChallenge( "ch_limited_deadeye" );
if( getWeaponClass( weapon ) == "weapon_sniper" )
self notify( "increment_sharpshooter_kills" );
else if( getWeaponClass( weapon ) == "weapon_shotgun" )
self notify( "increment_oneshotgun_kills" );
}
comeBackEvent( killId, weapon, meansOfDeath )
{
self.modifiers["comeback"] = true;
self incPlayerStat( "comebacks", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "comeback", self, weapon, undefined, meansOfDeath );
self thread maps\mp\_matchdata::logKillEvent( killId, "comeback" );
}
semtexStickEvent( victim )
{
self incPlayerStat( "semtex_stick", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "semtex_stick", self );
victim incPlayerStat( "stuck_with_explosive", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "stuck_with_explosive", victim );
self maps\mp\gametypes\_missions::processChallenge( "ch_humiliation_stuck" );
self notify( "increment_stuck_kills" );
}
crossbowStickEvent( victim )
{
self incPlayerStat( "crossbow_stick", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "crossbow_stick", self );
victim incPlayerStat( "stuck_with_explosive", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "stuck_with_explosive", victim );
self maps\mp\gametypes\_missions::processChallenge( "ch_humiliation_stuck" );
self notify( "increment_stuck_kills" );
}
disconnected()
{
myGuid = self.guid;
for ( entry = 0; entry < level.players.size; entry++ )
{
if ( isDefined( level.players[entry].killedPlayers[myGuid] ) )
level.players[entry].killedPlayers[myGuid] = undefined;
if ( isDefined( level.players[entry].killedPlayersCurrent[myGuid] ) )
level.players[entry].killedPlayersCurrent[myGuid] = undefined;
if ( isDefined( level.players[entry].killedBy[myGuid] ) )
level.players[entry].killedBy[myGuid] = undefined;
}
}
updateRecentKills( killId, weapon )
{
if( !IsDefined( weapon ) )
weapon = "";
self endon ( "disconnect" );
level endon ( "game_ended" );
self notify ( "updateRecentKills" );
self endon ( "updateRecentKills" );
self.recentKillCount++;
was_ads = false;
if( self PlayerAds() >= 0.2 )
was_ads = true;
wait ( 2.0 );
if ( self.recentKillCount > 1 )
self multiKillEvent( killId, self.recentKillCount, weapon, was_ads );
self.recentKillCount = 0;
}
hijackerEvent( owner )
{
self incPlayerStat( "hijacker", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "hijacker", self );
self thread maps\mp\gametypes\_missions::genericChallenge( "hijacker_airdrop" );
if( IsDefined( owner ) )
owner maps\mp\gametypes\_hud_message::playerCardSplashNotify( "hijacked_airdrop", self );
}
sharedEvent()
{
self incPlayerStat( "sharepackage", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "sharepackage", self );
}
mapKillStreakEvent()
{
mapStreaksReceived = getMatchData( "players", self.clientId, "numberOfMapstreaksReceived" );
mapStreaksReceived++;
setMatchData( "players", self.clientId, "numberOfMapstreaksReceived", clampToByte( mapStreaksReceived ) );
self incPlayerStat( "map_killstreak", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "map_killstreak", self );
}
killStreakTagEvent()
{
self incPlayerStat( "killstreak_tag", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "killstreak_tag", self );
}
killStreakJoinEvent()
{
coopStreakTime = GetTime();
nextAllowTime = self.lastCoopStreakTime + 10000;
if( nextAllowTime > coopStreakTime )
return;
self.lastCoopStreakTime = coopStreakTime;
self incPlayerStat( "killstreak_join", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "killstreak_join", self );
}
checkVandalismMedal( killer )
{
if( IsDefined(level.isHorde) )
return;
if ( !IsDefined( self.attackerList ) )
{
return;
}
if( !IsDefined(killer) )
killer = self;
owner = self.owner;
if( !IsDefined(owner) )
owner = self;
foreach( previousAttacker in self.attackerList )
{
if( !IsDefined(previousAttacker) )
continue;
if( previousAttacker == owner )
continue;
if( previousAttacker == killer )
continue;
previousAttacker incPlayerStat( "assist_killstreak_destroyed", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "assist_killstreak_destroyed", previousAttacker );
}
}
checkStreakingEvents( victim )
{
currentKillStreak = self.killstreakcount + 1;
// track multiples of 5s and all kills after 30
if( (currentKillStreak % 5) && (currentKillStreak < 30) )
return;
switch( currentKillStreak )
{
case 5:
level thread maps\mp\gametypes\_rank::awardGameEvent( "5killstreak", self );
self incPlayerStat( "5killstreak", 1 );
self maps\mp\gametypes\_missions::processChallenge( "ch_killer_blood");
if( IsDefined( self.challengeData["ch_limited_bloodshed"] ) && ( self.challengeData["ch_limited_bloodshed"] == 1 ) )
self maps\mp\gametypes\_missions::processChallenge( "ch_limited_bloodshed", 5 );
break;
case 10:
level thread maps\mp\gametypes\_rank::awardGameEvent( "10killstreak", self );
self incPlayerStat( "10killstreak", 1 );
self maps\mp\gametypes\_missions::processChallenge( "ch_killer_merciless");
self maps\mp\gametypes\_missions::processChallenge( "ch_" + level.gametype +"_merciless" );
if( IsDefined( self.challengeData["ch_limited_bloodshed"] ) && ( self.challengeData["ch_limited_bloodshed"] == 2 ) )
self maps\mp\gametypes\_missions::processChallenge( "ch_limited_bloodshed", 5 );
if( self.loadoutOffhand == "specialty_null" && self.loadoutEquipment == "specialty_null" )
self maps\mp\gametypes\_missions::processChallenge( "ch_precision_wetwork" );
break;
case 15:
level thread maps\mp\gametypes\_rank::awardGameEvent( "15killstreak", self );
self incPlayerStat( "15killstreak", 1 );
self maps\mp\gametypes\_missions::processChallenge( "ch_killer_ruthless");
if( IsDefined( self.challengeData["ch_limited_bloodshed"] ) && ( self.challengeData["ch_limited_bloodshed"] == 3 ) )
self maps\mp\gametypes\_missions::processChallenge( "ch_limited_bloodshed", 5 );
break;
case 20:
level thread maps\mp\gametypes\_rank::awardGameEvent( "20killstreak", self );
self incPlayerStat( "20killstreak", 1 );
self maps\mp\gametypes\_missions::processChallenge( "ch_killer_relentless");
if( IsDefined( self.challengeData["ch_limited_bloodshed"] ) && ( self.challengeData["ch_limited_bloodshed"] == 4 ) )
self maps\mp\gametypes\_missions::processChallenge( "ch_limited_bloodshed", 5 );
break;
case 25:
level thread maps\mp\gametypes\_rank::awardGameEvent( "25killstreak", self );
self incPlayerStat( "25killstreak", 1 );
self maps\mp\gametypes\_missions::processChallenge( "ch_killer_brutal");
if( IsDefined( self.challengeData["ch_limited_bloodshed"] ) && ( self.challengeData["ch_limited_bloodshed"] == 5 ) )
self maps\mp\gametypes\_missions::processChallenge( "ch_limited_bloodshed", 5 );
break;
case 30:
level thread maps\mp\gametypes\_rank::awardGameEvent( "30killstreak", self );
self incPlayerStat( "30killstreak", 1 );
if( IsDefined( self.challengeData["ch_limited_bloodshed"] ) && ( self.challengeData["ch_limited_bloodshed"] == 6 ) )
self maps\mp\gametypes\_missions::processChallenge( "ch_limited_bloodshed", 5 );
break;
default:
level thread maps\mp\gametypes\_rank::awardGameEvent( "30pluskillstreak", self );
self incPlayerStat( "30pluskillstreak", 1 );
break;
}
self thread teamPlayerCardSplash( "callout_kill_streaking", self, undefined, currentKillStreak );
}
checkHigherRankKillEvents( victim )
{
// only do this once the match has gone for a little while
if( getTimePassed() < ( 60 * 1.5 ) * 1000 )
return;
enemyList = level.players;
if( level.teamBased )
enemyList = level.teamList[ getOtherTeam( self.team ) ];
if( enemyList.size < 3 )
return;
enemiesSortedByRank = array_sort_with_func( enemyList, ::is_score_a_greater_than_b );
if( IsDefined(enemiesSortedByRank[0]) && (victim == enemiesSortedByRank[0]) )
{
self incPlayerStat( "firstplacekill", 1 );
level thread maps\mp\gametypes\_rank::awardGameEvent( "firstplacekill", self );
self maps\mp\gametypes\_missions::processChallenge( "ch_precision_highvalue" );
}
}
is_score_a_greater_than_b( a, b )
{
return ( a.score > b.score );
}
processAssistEvent( killedplayer, xpEventOverride )
{
if( IsDefined(level.assists_disabled) && level.assists_disabled )
return;
xpevent = "assist";
if( IsDefined(xpEventOverride) )
xpevent = xpEventOverride;
self endon("disconnect");
killedplayer endon("disconnect");
// don't ever run on the same frame as the playerkilled callback.
wait(0.05);
if( (self.team != "axis") && (self.team != "allies") )
return;
if( self.team == killedplayer.team )
return;
level thread maps\mp\gametypes\_rank::awardGameEvent( xpevent, self, undefined, killedplayer );
killedplayer maps\mp\_matchdata::logSpecialAssists( self, xpevent );
// only increment assist stats for normal assists
if( (xpevent == "assist") || (xpevent == "assist_riot_shield") )
{
self incPlayerStat( "assists", 1 );
self incPersStat( "assists", 1 );
self.assists = self getPersStat( "assists" );
if( xpevent == "assist_riot_shield" )
self incPlayerStat( "assist_riot_shield", 1 );
self maps\mp\gametypes\_persistence::statSetChild( "round", "assists", self.assists );
self thread maps\mp\gametypes\_missions::playerAssist();
if ( level.practiceRound )
self thread practiceRoundAssistEvent( killedplayer );
}
}
killAfterDodgeEvent( weapon )
{
self maps\mp\gametypes\_missions::processChallenge( "ch_exomech_evasive" );
// some more camo stuff
if( IsDefined( weapon) )
{
baseWeapon = getBaseWeaponName( weapon );
if( isLootWeapon( baseWeapon ) )
baseWeapon = maps\mp\gametypes\_class::getBaseFromLootVersion( baseWeapon );
weaponClass = self maps\mp\gametypes\_missions::get_challenge_weapon_class( weapon, baseWeapon );
if( WeaponClass == "weapon_assault" || WeaponClass == "weapon_pistol" )
{
if( IsSubStr( baseWeapon, "dlcgun" ) && weaponClass == "weapon_assault" )
self maps\mp\gametypes\_missions::processChallenge( "ch_tier2_3_" + baseWeapon );
else
self maps\mp\gametypes\_missions::processChallenge( "ch_dodge_" + baseWeapon );
}
}
}
camoSprintSlideKillEvent( weapon, meansOfDeath )
{
// only smg, shotgun, pistol,
baseWeapon = getBaseWeaponName( weapon );
if( isLootWeapon( baseWeapon ) )
{
baseWeapon = maps\mp\gametypes\_class::getBaseFromLootVersion( baseWeapon );
}
weaponClass = self maps\mp\gametypes\_missions::get_challenge_weapon_class(weapon, baseWeapon);
switch( weaponClass )
{
case "weapon_smg":
case "weapon_shotgun":
case "weapon_pistol":
if(IsDefined( level.challengeInfo[ "ch_slide_" + baseWeapon ] ))
self maps\mp\gametypes\_missions::processChallenge( "ch_slide_" + baseWeapon );
break;
}
}