2025-05-21 16:23:17 +02:00

782 lines
27 KiB
Plaintext

#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include maps\mp\perks\_perkfunctions;
init()
{
level.perkFuncs = [];
level.specialty_finalstand_icon = "specialty_s1_temp";
level.specialty_c4_death_icon = "specialty_s1_temp";
level.specialty_compassping_revenge_icon = "specialty_s1_temp";
level.specialty_juiced_icon = "specialty_s1_temp";
level.spawnGlowModel["enemy"] = "static_tactical_insertion_device";
level.spawnGlowModel["friendly"] = "static_tactical_insertion_device";
level.spawnGlow["enemy"] = loadfx( "vfx/props/tac_insert_enemy" );
level.spawnGlow["friendly"] = loadfx( "vfx/props/tac_insert_friendly" );
level.spawnFire = loadfx( "vfx/explosion/mp_tac_explosion" );
level._effect["ricochet"] = loadfx( "fx/impacts/large_metalhit_1" );
// perks that currently only exist in script: these will error if passed to "setPerk", etc... CASE SENSITIVE! must be lower
level.scriptPerks = [];
level.perkSetFuncs = [];
level.perkUnsetFuncs = [];
level.scriptPerks["specialty_blastshield"] = true;
level.scriptPerks["_specialty_blastshield"] = true;
level.scriptPerks["specialty_akimbo"] = true;
level.scriptPerks["specialty_falldamage"] = true;
level.scriptPerks["specialty_shield"] = true;
level.scriptPerks["specialty_feigndeath"] = true;
level.scriptPerks["specialty_shellshock"] = true;
level.scriptPerks["specialty_delaymine"] = true;
level.scriptPerks["specialty_localjammer"] = true;
level.scriptPerks["specialty_thermal"] = true;
level.scriptPerks["specialty_blackbox"] = true;
level.scriptPerks["specialty_steelnerves"] = true;
level.scriptPerks["specialty_flashgrenade"] = true;
level.scriptPerks["specialty_smokegrenade"] = true;
level.scriptPerks["specialty_concussiongrenade"] = true;
level.scriptPerks["specialty_saboteur"] = true;
level.scriptPerks["specialty_endgame"] = true;
level.scriptPerks["specialty_rearview"] = true;
level.scriptPerks["specialty_hardline"] = true;
level.scriptPerks["specialty_onemanarmy"] = true;
level.scriptPerks["specialty_primarydeath"] = true;
level.scriptPerks["specialty_secondarybling"] = true;
level.scriptPerks["specialty_explosivedamage"] = true;
level.scriptPerks["specialty_laststandoffhand"] = true;
level.scriptPerks["specialty_dangerclose"] = true;
level.scriptPerks["specialty_hardjack"] = true;
level.scriptPerks["specialty_extraspecialduration"] = true;
level.scriptPerks["specialty_rollover"] = true;
level.scriptPerks["specialty_armorpiercing"] = true;
level.scriptPerks["specialty_omaquickchange"] = true;
level.scriptPerks["_specialty_rearview"] = true;
level.scriptPerks["_specialty_onemanarmy"] = true;
level.scriptPerks["specialty_steadyaimpro"] = true;
level.scriptPerks["specialty_stun_resistance"] = true;
level.scriptPerks["specialty_double_load"] = true;
level.scriptPerks["specialty_regenspeed"] = true;
level.scriptPerks["specialty_twoprimaries"] = true;
level.scriptPerks["specialty_autospot"] = true;
level.scriptPerks["specialty_overkillpro"] = true;
level.scriptPerks["specialty_anytwo"] = true;
level.scriptPerks["specialty_fasterlockon"] = true;
level.scriptPerks["specialty_paint"] = true;
level.scriptPerks["specialty_paint_pro"] = true;
level.scriptPerks["specialty_silentkill"] = true;
// Blacksmith New PERKS
level.scriptPerks["specialty_crouchmovement"] = true;
level.scriptPerks["specialty_personaluav"] = true;
level.scriptPerks["specialty_unwrapper"] = true;
level.scriptPerks["specialty_class_blindeye"] = true;
level.scriptPerks["specialty_class_lowprofile"] = true;
level.scriptPerks["specialty_class_coldblooded"] = true;
level.scriptPerks["specialty_class_hardwired"] = true;
level.scriptPerks["specialty_class_scavenger"] = true;
level.scriptPerks["specialty_class_hoarder"] = true;
level.scriptPerks["specialty_class_gungho"] = true;
level.scriptPerks["specialty_class_steadyhands"] = true;
level.scriptPerks["specialty_class_hardline"] = true;
level.scriptPerks["specialty_class_peripherals"] = true;
level.scriptPerks["specialty_class_quickdraw"] = true;
level.scriptPerks["specialty_class_toughness"] = true;
level.scriptPerks["specialty_class_lightweight"] = true;
level.scriptPerks["specialty_class_engineer"] = true;
level.scriptPerks["specialty_class_dangerclose"] = true;
//horde
level.scriptPerks["specialty_horde_weaponsfree"] = true;
level.scriptPerks["specialty_horde_dualprimary"] = true;
// weapon buffs
level.scriptPerks["specialty_marksman"] = true;
level.scriptPerks["specialty_sharp_focus"] = true;
level.scriptPerks["specialty_moredamage"] = true;
// death streaks
level.scriptPerks["specialty_copycat"] = true;
level.scriptPerks["specialty_finalstand"] = true;
level.scriptPerks["specialty_juiced"] = true;
level.scriptPerks["specialty_light_armor"] = true;
level.scriptPerks["specialty_carepackage"] = true;
level.scriptPerks["specialty_stopping_power"] = true;
level.scriptPerks["specialty_uav"] = true;
// equipment
level.scriptPerks["bouncingbetty_mp"] = true;
level.scriptPerks["c4_mp"] = true;
level.scriptPerks["claymore_mp"] = true;
level.scriptPerks["frag_grenade_mp"] = true;
level.scriptPerks["semtex_mp"] = true;
level.scriptPerks["tracking_drone_mp"] = true;
level.scriptPerks["throwingknife_mp"] = true;
level.scriptPerks["exoknife_mp"] = true;
level.scriptPerks["exoknife_jug_mp"] = true;
level.scriptPerks["paint_grenade_mp"] = true;
level.scriptPerks["tri_drone_mp"] = true;
level.scriptPerks["explosive_gel_mp"] = true;
level.scriptPerks["frag_grenade_var_mp"] = true;
level.scriptPerks["contact_grenade_var_mp"] = true;
level.scriptPerks["semtex_grenade_var_mp"] = true;
level.scriptPerks["stun_grenade_var_mp"] = true;
level.scriptPerks["emp_grenade_var_mp"] = true;
level.scriptPerks["paint_grenade_var_mp"] = true;
level.scriptPerks["smoke_grenade_var_mp"] = true;
level.scriptPerks["explosive_drone_mp"] = true;
// special grenades
level.scriptPerks["concussion_grenade_mp"] = true;
level.scriptPerks["flash_grenade_mp"] = true;
level.scriptPerks["stun_grenade_mp"] = true;
level.scriptPerks["smoke_grenade_mp"] = true;
level.scriptPerks["emp_grenade_mp"] = true;
level.scriptPerks["portable_radar_mp"] = true;
level.scriptPerks["scrambler_mp"] = true;
level.scriptPerks["trophy_mp"] = true;
level.scriptPerks["s1_tactical_insertion_device_mp"] = true;
// wildcards
level.scriptPerks["specialty_wildcard_perkslot1"] = true;
level.scriptPerks["specialty_wildcard_perkslot2"] = true;
level.scriptPerks["specialty_wildcard_perkslot3"] = true;
level.scriptPerks["specialty_wildcard_primaryattachment"] = true;
level.scriptPerks["specialty_wildcard_secondaryattachment"] = true;
level.scriptPerks["specialty_wildcard_extrastreak"] = true;
// specialty_null is assigned as a perk sometimes and it's not a code perk
level.scriptPerks["specialty_null"] = true;
level.perkSetFuncs["specialty_blastshield"] = ::setBlastShield;
level.perkUnsetFuncs["specialty_blastshield"] = ::unsetBlastShield;
level.perkSetFuncs["specialty_falldamage"] = ::setFreefall;
level.perkUnsetFuncs["specialty_falldamage"] = ::unsetFreefall;
level.perkSetFuncs["specialty_localjammer"] = ::setLocalJammer;
level.perkUnsetFuncs["specialty_localjammer"] = ::unsetLocalJammer;
level.perkSetFuncs["specialty_thermal"] = ::setThermal;
level.perkUnsetFuncs["specialty_thermal"] = ::unsetThermal;
level.perkSetFuncs["specialty_blackbox"] = ::setBlackBox;
level.perkUnsetFuncs["specialty_blackbox"] = ::unsetBlackBox;
level.perkSetFuncs["specialty_lightweight"] = ::setLightWeight;
level.perkUnsetFuncs["specialty_lightweight"] = ::unsetLightWeight;
level.perkSetFuncs["specialty_steelnerves"] = ::setSteelNerves;
level.perkUnsetFuncs["specialty_steelnerves"] = ::unsetSteelNerves;
level.perkSetFuncs["specialty_delaymine"] = ::setDelayMine;
level.perkUnsetFuncs["specialty_delaymine"] = ::unsetDelayMine;
level.perkSetFuncs["specialty_saboteur"] = ::setSaboteur;
level.perkUnsetFuncs["specialty_saboteur"] = ::unsetSaboteur;
level.perkSetFuncs["specialty_endgame"] = ::setEndGame;
level.perkUnsetFuncs["specialty_endgame"] = ::unsetEndGame;
level.perkSetFuncs["specialty_rearview"] = ::setRearView;
level.perkUnsetFuncs["specialty_rearview"] = ::unsetRearView;
level.perkSetFuncs["specialty_onemanarmy"] = ::setOneManArmy;
level.perkUnsetFuncs["specialty_onemanarmy"] = ::unsetOneManArmy;
level.perkSetFuncs["specialty_steadyaimpro"] = ::setSteadyAimPro;
level.perkUnsetFuncs["specialty_steadyaimpro"] = ::unsetSteadyAimPro;
level.perkSetFuncs["specialty_stun_resistance"] = ::setStunResistance;
level.perkUnsetFuncs["specialty_stun_resistance"] = ::unsetStunResistance;
level.perkSetFuncs["specialty_marksman"] = ::setMarksman;
level.perkUnsetFuncs["specialty_marksman"] = ::unsetMarksman;
level.perkSetFuncs["specialty_double_load"] = ::setDoubleLoad;
level.perkUnsetFuncs["specialty_double_load"] = ::unsetDoubleLoad;
level.perkSetFuncs["specialty_sharp_focus"] = ::setSharpFocus;
level.perkUnsetFuncs["specialty_sharp_focus"] = ::unsetSharpFocus;
level.perkSetFuncs["specialty_regenspeed"] = ::setRegenSpeed;
level.perkUnsetFuncs["specialty_regenspeed"] = ::unsetRegenSpeed;
level.perkSetFuncs["specialty_autospot"] = ::setAutoSpot;
level.perkUnsetFuncs["specialty_autospot"] = ::unsetAutoSpot;
level.perkSetFuncs["specialty_empimmune"] = ::setEmpImmune;
level.perkUnsetFuncs["specialty_empimmune"] = ::unsetEmpImmune;
level.perkSetFuncs["specialty_overkill_pro"] = ::setOverkillPro;
level.perkUnsetFuncs["specialty_overkill_pro"] = ::unsetOverkillPro;
level.perkSetFuncs["specialty_personaluav"] = ::setPersonalUav;
level.perkUnsetFuncs["specialty_personaluav"] = ::unsetPersonalUav;
level.perkSetFuncs["specialty_crouchmovement"] = ::setCrouchMovement;
level.perkUnsetFuncs["specialty_crouchmovement"] = ::unsetCrouchMovement;
level.perkSetFuncs["specialty_light_armor"] = ::setLightArmor;
level.perkUnsetFuncs["specialty_light_armor"] = ::unsetLightArmor;
// death streaks
level.perkSetFuncs["specialty_finalstand"] = ::setFinalStand;
level.perkUnsetFuncs["specialty_finalstand"] = ::unsetFinalStand;
level.perkSetFuncs["specialty_juiced"] = ::setJuiced;
level.perkUnsetFuncs["specialty_juiced"] = ::unsetJuiced;
level.perkSetFuncs["specialty_carepackage"] = ::setCarePackage;
level.perkUnsetFuncs["specialty_carepackage"] = ::unsetCarePackage;
level.perkSetFuncs["specialty_stopping_power"] = ::setStoppingPower;
level.perkUnsetFuncs["specialty_stopping_power"] = ::unsetStoppingPower;
level.perkSetFuncs["specialty_uav"] = ::setUAV;
level.perkUnsetFuncs["specialty_uav"] = ::unsetUAV;
// end death streaks
initPerkDvars();
level thread onPlayerConnect();
}
// Don't call this on equipment.
validatePerk( perkIndex, perkName )
{
if ( getDvarInt ( "scr_game_perks" ) == 0 )
{
return "specialty_null";
}
/* Old validation of the perkTable. Just hard-coding for now since we missed this for ship and it needs to be in the FFOTD.
* Next game (or in the TU) we can change to use a perkTable column properly.
if ( tableLookup( "mp/perkTable.csv", 1, perkName, 5 ) != ("perk"+perkIndex) )
{
println( "^1Warning: (" + self.name + ") Perk " + perkName + " is not allowed for perk slot index " + perkIndex + "; replacing with no perk" );
return "specialty_null";
}
*/
if ( perkIndex == 0 || perkIndex == 1 )
{
switch ( perkName )
{
case "specialty_extended_battery":
case "specialty_class_lowprofile":
case "specialty_class_flakjacket":
case "specialty_class_lightweight":
case "specialty_class_dangerclose":
return perkName;
default:
return "specialty_null";
}
}
else if ( perkIndex == 2 || perkIndex == 3 )
{
switch ( perkName )
{
case "specialty_class_blindeye":
case "specialty_class_coldblooded":
case "specialty_class_peripherals":
case "specialty_class_fasthands":
case "specialty_class_dexterity":
return perkName;
default:
return "specialty_null";
}
}
else if ( perkIndex == 4 || perkIndex == 5 )
{
switch ( perkName )
{
case "specialty_class_hardwired":
case "specialty_class_toughness":
case "specialty_class_scavenger":
case "specialty_class_hardline":
case "specialty_exo_blastsuppressor":
return perkName;
default:
return "specialty_null";
}
}
return perkName;
}
getEmptyPerks()
{
perks=[];
for (i=0; i<6; i++)
perks[i] = "specialty_null";
return perks;
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
player thread onPlayerSpawned();
}
}
onPlayerSpawned()
{
self endon( "disconnect" );
self.perks = [];
self.weaponList = [];
self.omaClassChanged = false;
for( ;; )
{
self waittill( "spawned_player" );
self.omaClassChanged = false;
self thread maps\mp\gametypes\_scrambler::scramblerProximityTracker();
}
}
cac_modified_damage( victim, attacker, damage, meansofdeath, weapon, impactPoint, impactDir, hitLoc, inflictor )
{
assert( isPlayer( victim ) || isAgent( victim ) );
assert( isDefined( victim.team ) );
damageAdd = 0;
shortWeapon = maps\mp\_utility::strip_suffix( weapon, "_lefthand" );
if( isBulletDamage( meansOfDeath ) )
{
assert( isDefined( attacker ) );
// show the victim on the minimap for N seconds
if( IsPlayer( attacker ) && attacker _hasPerk( "specialty_paint_pro" ) && !isKillstreakWeapon( weapon ) && IsPlayer( victim ) && !victim _hasPerk( "specialty_class_lowprofile" ) )
{
// make sure they aren't already painted before we process the challenge
if( !victim isPainted() )
attacker maps\mp\gametypes\_missions::processChallenge( "ch_bulletpaint" );
if( attacker.trackrounds.has_trackrounds )
victim thread maps\mp\_trackrounds::set_painted_trackrounds( attacker );
victim thread maps\mp\perks\_perkfunctions::setPainted( attacker );
}
//20% damage reduction for using silencer on sniper since range reduction has no effect on snipers.
if( IsPlayer( attacker ) && isDefined( weapon ) && getWeaponClass( weapon ) == "weapon_sniper" && isSubStr( weapon, "silencer" ) )
damage *= 0.75;
// stopping power and armor vest cancel each other out
if( IsPlayer( attacker ) &&
( attacker _hasPerk( "specialty_bulletdamage" ) && victim _hasPerk( "specialty_armorvest" ) ) )
{
damageAdd += 0;
}
// if the attacker has the stopping power or has the more damage weapon buff
else if( IsPlayer( attacker ) &&
( attacker _hasPerk( "specialty_bulletdamage" ) ||
attacker _hasPerk( "specialty_moredamage" ) ) )
{
damageAdd += damage * level.bulletDamageMod;
}
// if the victim has armor vest take some damage off
else if ( victim _hasPerk( "specialty_armorvest" ) )
{
damageAdd -= damage * level.armorVestMod;
}
// let's handle juggernaut damaging here
if( victim isJuggernaut() )
{
weakToHeadShots = IsDefined( victim.juggernautWeak ) && victim.juggernautWeak && ( hitLoc == "head" || hitLoc == "helmet" );
if ( !weakToHeadShots )
damage *= level.juggernautMod;
// TODO: maybe bring this back if we think jugg needs a good counter
//// player shooting jugg
//if( IsPlayer( attacker ) )
//{
// if( weaponInheritsPerks( weapon ) )
// {
// if( attacker _hasPerk( "specialty_armorpiercing" ) )
// {
// damage = damage * level.armorPiercingMod;
// }
// }
//}
}
}
else if( IsExplosiveDamageMOD( meansOfDeath ) )
{
// show the victim on the minimap for N seconds
if( IsPlayer( attacker ) &&
attacker != victim &&
( attacker IsItemUnlocked( "specialty_paint" ) && attacker _hasPerk( "specialty_paint" ) ) && !isKillstreakWeapon( weapon ) )
{
if( !victim isPainted() )
attacker maps\mp\gametypes\_missions::processChallenge( "ch_paint_pro" );
victim thread maps\mp\perks\_perkfunctions::setPainted( attacker );
}
if ( isPlayer( attacker ) && weaponInheritsPerks( weapon ) &&
( ( attacker _hasPerk( "specialty_explosivedamage" ) ) && victim _hasPerk( "_specialty_blastshield" ) ) )
{
damageAdd += 0;
}
else if ( isPlayer( attacker ) && weaponInheritsPerks( weapon ) &&
( attacker _hasPerk( "specialty_explosivedamage" ) ) )
{
damageAdd += damage*level.explosiveDamageMod;
}
else if ( victim _hasPerk( "_specialty_blastshield" ) && IsDefined( victim.specialty_blastshield_bonus ) && ( shortWeapon != "semtex_mp" || damage < 125 ) )
{
damageAdd -= int( damage * victim.specialty_blastshield_bonus );
}
if ( isKillstreakWeapon( weapon ) && isPlayer( attacker ) &&
( attacker _hasPerk( "specialty_explosivedamage" ) ) )
{
damageAdd += damage*level.explosiveDamageMod;
}
// let's handle juggernaut damaging here
if( victim isJuggernaut() )
{
switch( weapon )
{
case "ac130_25mm_mp": // this is because the 25mm shoots a bunch of bullets and can do over 1000 with multiple hits at once
damage *= level.juggernautMod;
break;
// make a direct hit from the main missile strike missiles immediately kill the goliath, the child missiles do regular damage scaling
case "remotemissile_projectile_mp":
case "remotemissile_projectile_cluster_parent_mp":
case "remotemissile_projectile_gas_mp":
if ( damage < 350 )
{
if ( damage > 1 )
damage *= level.juggernautMod;
}
break;
default:
if ( damage < 1000 )
{
if ( damage > 1 )
damage *= level.juggernautMod;
}
break;
}
}
//fix for grenade spam at start of round
if ( maps\mp\gametypes\_weapons::inGrenadeGracePeriod() )
damage *= level.juggernautMod;
}
else if( meansOfDeath == "MOD_FALLING" )
{
if( victim IsItemUnlocked( "specialty_falldamage" ) && victim _hasPerk( "specialty_falldamage" ) )
{
// if( damage > 0 )
// victim maps\mp\gametypes\_missions::processChallenge( "ch_falldamage" );
//eventually set a msg to do a roll
damageAdd = 0;
damage = 0;
}
}
else if( isMeleeMOD(meansOfDeath) )
{
if ( isDefined( victim.hasLightArmor ) && victim.hasLightArmor )
{
if ( IsSubStr( weapon, "riotshield" ) || weapon == "exoshield_equipment_mp" )
damage = Int(victim.maxHealth*0.66);
else //knife
damage = victim.maxHealth+1;
}
// let's handle juggernaut damaging here
if( victim isJuggernaut() )
{
damage = 20;
damageAdd = 0;
}
}
else if( meansOfDeath == "MOD_IMPACT" )
{
// let's handle juggernaut damaging here
if( victim isJuggernaut() )
{
switch( shortWeapon )
{
case "concussion_grenade_mp":
case "flash_grenade_mp":
case "smoke_grenade_mp":
case "smoke_grenade_var_mp":
case "frag_grenade_mp":
case "semtex_mp":
case "stun_grenade_mp":
case "stun_grenade_var_mp":
case "stun_grenade_horde_mp":
damage = 5;
break;
default:
if( damage < 1000 )
damage = 25;
break;
}
damageAdd = 0;
}
}
// Handle armor damage
baseweaponname = GetWeaponBaseName(weapon);
if( IsDefined( victim.lightArmorHP ) && IsDefined(baseweaponname) )
{
switch( baseweaponname )
{
case "exoknife_mp":
case "exoknife_jug_mp":
{
damage = victim.health;
damageAdd = 0;
break;
}
case "semtexproj_mp":
case "semtex_mp":
{
if( IsDefined( inflictor ) && IsDefined( inflictor.stuckEnemyEntity ) && inflictor.stuckEnemyEntity == victim )
{
damage = victim.health;
damageAdd = 0;
}
break;
}
default:
{
// Handle Armor Damage
// no armor damage in case of falling, melee, fmj or head shots
if ( meansofdeath != "MOD_FALLING"
&& !isMeleeMOD( meansofdeath )
&& !isHeadShot( baseweaponname, hitLoc, meansofdeath, attacker )
&& !isFMJDamage( baseweaponname, meansofdeath, attacker )
)
{
victim setLightArmorHP( victim.lightArmorHP - ( damage + damageAdd ) );
damage = 0;
damageAdd = 0;
if ( victim.lightArmorHP <= 0 )
{
// since the light armor is gone, adjust the damage to be the excess damage that happens after the light armor hp is reduced
damage = abs( victim.lightArmorHP );
damageAdd = 0;
unsetLightArmor();
}
}
break;
}
}
}
/#
if ( getDvar( "scr_devPrintDamage" ) != "" )
{
IPrintLn( damage + damageAdd );
}
#/
if ( damage <= 1 )
{
damage = 1;
return damage;
}
else
return int( damage + damageAdd );
}
initPerkDvars()
{
level.juggernautMod = 8/100; // percentage of damage juggernaut takes
level.juggernatuDefMod = 8/100; // percentage of damage juggernaut takes
level.armorPiercingMod = 1.5; // increased bullet damage * this on vehicles and juggernauts
level.regenHealthMod = 0.25; // regen health at a percent of the normal speed
level.bulletDamageMod = getIntProperty( "perk_bulletDamage", 12 )/100; // increased bullet damage by this % //using 12% of base 30 change 4 - 3 rnds to kill
level.explosiveDamageMod = getIntProperty( "perk_explosiveDamage", 10 )/100; // increased explosive damage by this %
level.riotShieldMod = getIntProperty( "perk_riotShield", 100 )/100;
level.armorVestMod = getIntProperty( "perk_armorVest", 20 )/100; // percentage of damage subtracted from total damage
}
// CAC: Selector function, calls the individual cac features according to player's class settings
// Info: Called every time player spawns during loadout stage
cac_selector()
{
/*
self.detectExplosives = false;
if ( self _hasPerk( "specialty_detectexplosive" ) )
self.detectExplosives = true;
maps\mp\gametypes\_weapons::setupBombSquad();
*/
}
giveBlindEyeAfterSpawn()
{
self endon( "death" );
self endon( "disconnect" );
self givePerk( "specialty_blindeye", false );
self.spawnPerk = true;
while( self.avoidKillstreakOnSpawnTimer > 0 )
{
self.avoidKillstreakOnSpawnTimer -= 0.05;
wait( 0.05 );
}
self _unsetPerk( "specialty_blindeye" );
self.spawnPerk = false;
}
applyPerks()
{
self SetViewKickScale( 0.5 );
//============================================
// Tier 1 Perks
//============================================
//######## OVER CHARGED EXO ########
if( self _hasPerk( "specialty_extended_battery" ) ) // Grants extra battery energy (currently 50%).
{
self givePerk( "specialty_exo_slamboots", false ); // Boost slam applies additional concussion effect.
}
//######## LOW PROFILE ########
if( self _hasPerk( "specialty_class_lowprofile" ) ) // Grants immunity to track rounds.
{
self givePerk( "specialty_radarimmune", false ); // Immune to UAV while moving.
self givePerk( "specialty_exoping_immune", false ); // Immune to Exo Ping.
}
//######## FLAK JACKET ########
if( self _hasPerk( "specialty_class_flakjacket" ) )
{
self givePerk( "specialty_hard_shell", false ); // No slowdown after taking explosive damage.
self givePerk( "specialty_throwback", false ); // Reset frag grenade fuse on throwback.
self givePerk( "_specialty_blastshield", false ); // Take less explosive damage.
self.specialty_blastshield_bonus = getIntProperty( "perk_blastShieldScale", 45 ) / 100;
if( IsDefined( level.hardcoreMode ) && level.hardcoreMode )
self.specialty_blastshield_bonus = getIntProperty( "perk_blastShieldScale_HC", 90 ) / 100;
}
//######## LIGHTWEIGHT ########
if( self _hasPerk( "specialty_class_lightweight" ) )
{
self givePerk( "specialty_lightweight", false ); // Increases movement speed.
}
//######## DANGER CLOSE ########
if( self _hasPerk( "specialty_class_dangerclose" ) )
{
self givePerk( "specialty_explosivedamage", false ); // Do extra explosive damage. Canceled by _specialty_blastshield.
}
//============================================
// Tier 2 Perks
//============================================
//######## BLIND EYE ########
if( self _hasPerk( "specialty_class_blindeye" ) )
{
self givePerk( "specialty_blindeye", false ); // Untargetable to Tracking Drones, Explosive Drones, AI-controlled scorestreaks (e.g. warbird).
self givePerk( "specialty_plainsight", false); // Immune to FOF overlay of Player-controlled score streaks
}
//######## COLDBLOODED ########
if( self _hasPerk( "specialty_class_coldblooded" ) )
{
self givePerk( "specialty_coldblooded", false ); // Immune to Thermal, target enhancer, paint grenade, battlechatter
self givePerk( "specialty_spygame", false); // Crosshair doesn't appear red to enemies (and your name doesn't draw overhead )
self givePerk( "specialty_heartbreaker", false ); // Immune to hearbeat sensor. Name doesn't draw overhead (see autospot in code)?
}
//######## PERIPHERALS ########
if( self _hasPerk( "specialty_class_peripherals" ) || practiceRoundGame() )
{
self givePerk( "specialty_moreminimap", false ); // Increases minimap coverage.
self givePerk( "specialty_silentkill", false ); // Your kills do not show death icons to enemy players.
}
//######## FAST HANDS ########
if( self _hasPerk( "specialty_class_fasthands" ) )
{
self givePerk( "specialty_quickswap", false ); // Swap weapons faster.
self givePerk( "specialty_fastoffhand", false ); // Use equipment faster.
self givePerk( "specialty_sprintreload", false ); // Enables reloading while sprinting.
}
//######## GUNG-HO ########
if( self _hasPerk( "specialty_class_dexterity" ) )
{
//self givePerk( "specialty_fastsprintrecovery", false ); // Increases weapon readiness for hip-fire after sprinting. This doesn't help the player at all when paired with sprintfire.
self givePerk( "specialty_sprintfire", false ); // Enables firing while sprinting and sliding.
}
//============================================
// Tier 3 Perks
//============================================
//######## HARD WIRED ########
if( self _hasPerk( "specialty_class_hardwired" ) )
{
self givePerk( "specialty_empimmune", false ); // Immune to EMP grenades and the EMP Scorestreak. Code: immune to portable radar and jammer.
self givePerk( "specialty_stun_resistance", false ); // Immune to missile strike gas (nano swarm). Immune to stun grenade (see setStunResistance()).
self.stunScaler = 0.1;
}
//######## TOUGHNESS ########
if( self _hasPerk( "specialty_class_toughness" ) )
self setViewKickScale( 0.2 ); // Reducing view kick when shot.
//######## SCAVENGER ########
if( self _hasPerk( "specialty_class_scavenger" ) )
{
self.ammopickup_scalar = 0.2;
self givePerk( "specialty_scavenger", false ); // Enables scavenger pack drops in code. Must be given for any of the resupply perks to work.
self givePerk( "specialty_bulletresupply", false ); // Resupplies bullet weapons.
//self givePerk( "specialty_lethalresupply", false ); // Resupplies grenades (tactical and lethal grenades).
//self givePerk( "specialty_tacticalresupply", false ); // Resupplies Exo Abilities.
//self givePerk( "specialty_explosiveammoresupply", false ); // Resupplies rocket launchers.
self givePerk( "specialty_extraammo", false ); // Spawn with extra ammo.
}
//######## HARD LINE ########
if( self _hasPerk( "specialty_class_hardline" ) )
self givePerk( "specialty_hardline", false ); // Decreases Scorestreak cost by 100 points.
//######## BLAST SUPPRESSOR #########
// Suppresses minimap ping when performing Exo movement mechanics.
}