1106 lines
26 KiB
Plaintext
1106 lines
26 KiB
Plaintext
#include maps\mp\_utility;
|
|
#include maps\mp\gametypes\_hud_util;
|
|
#include common_scripts\utility;
|
|
|
|
init()
|
|
{
|
|
initAwards();
|
|
|
|
level thread onPlayerConnect();
|
|
level thread monitorMovementDistance();
|
|
level thread monitorEnemyDistance();
|
|
}
|
|
|
|
onPlayerConnect()
|
|
{
|
|
for(;;)
|
|
{
|
|
level waittill( "connected", player );
|
|
|
|
// Reset player awards to none
|
|
|
|
if ( !isDefined( player.pers["stats"] ) )
|
|
player.pers["stats"] = [];
|
|
|
|
player.stats = player.pers["stats"];
|
|
|
|
if ( !player.stats.size )
|
|
{
|
|
player setPlayerData( "round", "awardCount", 0 );
|
|
|
|
// Initialize player stats
|
|
foreach ( ref, award in level.awards )
|
|
{
|
|
if ( isDefined( level.awards[ ref ].defaultvalue ) )
|
|
player initPlayerStat( ref, level.awards[ ref ].defaultvalue );
|
|
else
|
|
player initPlayerStat( ref );
|
|
}
|
|
}
|
|
|
|
player.prevPos = player.origin;
|
|
player.previousDeaths = 0;
|
|
player.altitudePolls = 0;
|
|
player.totalAltitudeSum = 0;
|
|
player.usedWeapons = [];
|
|
|
|
player thread onPlayerSpawned();
|
|
player thread monitorPositionCamping();
|
|
player thread monitorClassChange();
|
|
}
|
|
}
|
|
|
|
onPlayerSpawned()
|
|
{
|
|
self endon( "disconnect" );
|
|
|
|
for(;;)
|
|
{
|
|
self waittill( "spawned_player" );
|
|
|
|
self thread monitorReloads();
|
|
self thread monitorShotsFired();
|
|
self thread monitorSwaps();
|
|
self thread monitorExplosionsSurvived();
|
|
self thread monitorShieldBlocks();
|
|
self thread monitorFlashHits();
|
|
self thread monitorStunHits();
|
|
self thread monitorStanceTime();
|
|
}
|
|
}
|
|
|
|
initAwards()
|
|
{
|
|
if ( isDefined( level.initGametypeAwards ) )
|
|
[[ level.initGametypeAwards ]]();
|
|
|
|
// flags generated from other stats, these are not awards,
|
|
// but are checked against for the assignment of some awards
|
|
initAwardFlag( "10kills", ::isAtleast, 10, "kills" );
|
|
initAwardFlag( "1death", ::isAtleast, 1, "deaths" );
|
|
initAwardFlag( "nodeaths", ::isAtMost, 0, "deaths" );
|
|
initAwardFlag( "nokills", ::isAtMost, 0, "kills" );
|
|
|
|
// ordered in priority assigned
|
|
// TODO: should decouple dependency processing order from order assigned
|
|
initMultiAward( "mvp", "kills", "deaths" );
|
|
initMultiAward( "highlander", "10kills", "nodeaths" );
|
|
initThresholdAward( "kdratio10", ::isAtleast, 10, "kdratio" );
|
|
initMultiAward( "punisher", "kills", "killstreak" );
|
|
initMultiAward( "overkill", "kills", "headshots" );
|
|
initDerivedAward( "killedotherteamonelife" );
|
|
initStatAward( "kdratio", 0, ::highestWins );
|
|
initStatAward( "kills", 0, ::highestWins );
|
|
initStatAward( "higherrankkills", 0, ::highestWins );
|
|
initStatAward( "deaths", 0, ::lowestWithHalfPlayedTime );
|
|
initStatAward( "killstreak", 0, ::highestWins );
|
|
initStatAward( "headshots", 0, ::highestWins );
|
|
initDerivedAward( "finalkill" );
|
|
initDerivedAward( "killedotherteam" );
|
|
initStatAward( "closertoenemies", 0, ::highestWins );
|
|
initStatAward( "throwingknifekills", 0, ::highestWins );
|
|
initStatAward( "grenadekills", 0, ::highestWins );
|
|
initStatAward( "helicopters", 0, ::highestWins );
|
|
initStatAward( "airstrikes", 0, ::highestWins );
|
|
initStatAward( "uavs", 0, ::highestWins );
|
|
initStatAward( "mostmultikills", 0, ::highestWins );
|
|
initStatAward( "multikill", 0, ::highestWins );
|
|
initStatAward( "knifekills", 0, ::highestWins );
|
|
initStatAward( "flankkills", 0, ::highestWins );
|
|
initStatAward( "bulletpenkills", 0, ::highestWins );
|
|
initStatAward( "laststandkills", 0, ::highestWins );
|
|
initStatAward( "laststanderkills", 0, ::highestWins );
|
|
initStatAward( "assists", 0, ::highestWins );
|
|
initStatAward( "c4kills", 0, ::highestWins );
|
|
initStatAward( "claymorekills", 0, ::highestWins );
|
|
initStatAward( "fragkills", 0, ::highestWins );
|
|
initStatAward( "semtexkills", 0, ::highestWins );
|
|
initStatAward( "explosionssurvived",0, ::highestWins );
|
|
initStatAward( "mosttacprevented", 0, ::highestWins );
|
|
initStatAward( "avengekills", 0, ::highestWins );
|
|
initStatAward( "rescues", 0, ::highestWins );
|
|
initStatAward( "longshots", 0, ::highestWins );
|
|
initStatAward( "adskills", 0, ::highestWins );
|
|
initStatAward( "hipfirekills", 0, ::highestWins );
|
|
initStatAward( "revengekills", 0, ::highestWins );
|
|
initStatAward( "longestlife", 0, ::highestWins );
|
|
initStatAward( "throwbacks", 0, ::highestWins );
|
|
initStatAward( "thumperkills", 0, ::highestWins );
|
|
initStatAward( "otherweaponkills", 0, ::highestWins );
|
|
initStatAward( "killedsameplayer", 0, ::highestWins, 2 );
|
|
initStatAward( "mostweaponsused", 0, ::highestWins, 3 );
|
|
initStatAward( "distancetraveled", 0, ::highestWins );
|
|
initStatAward( "mostreloads", 0, ::highestWins );
|
|
initStatAward( "mostswaps", 0, ::highestWins );
|
|
initStat( "flankdeaths", 0 );
|
|
initDerivedAward( "noflankdeaths", ::isAtMostWithHalfPlayedTime, 0, "flankdeaths" );
|
|
initStatAward( "thermalkills", 0, ::highestWins );
|
|
initStatAward( "mostcamperkills", 0, ::highestWins );
|
|
initStatAward( "fbhits", 0, ::highestWins );
|
|
initStatAward( "stunhits", 0, ::highestWins );
|
|
initStatAward( "scopedkills", 0, ::highestWins );
|
|
initStatAward( "arkills", 0, ::highestWins );
|
|
initStatAward( "arheadshots", 0, ::highestWins );
|
|
initStatAward( "lmgkills", 0, ::highestWins );
|
|
initStatAward( "lmgheadshots", 0, ::highestWins );
|
|
initStatAward( "sniperkills", 0, ::highestWins );
|
|
initStatAward( "sniperheadshots", 0, ::highestWins );
|
|
initStatAward( "shieldblocks", 0, ::highestWins );
|
|
initStatAward( "shieldkills", 0, ::highestWins );
|
|
initStatAward( "smgkills", 0, ::highestWins );
|
|
initStatAward( "smgheadshots", 0, ::highestWins );
|
|
initStatAward( "shotgunkills", 0, ::highestWins );
|
|
initStatAward( "shotgunheadshots", 0, ::highestWins );
|
|
initStatAward( "pistolkills", 0, ::highestWins );
|
|
initStatAward( "pistolheadshots", 0, ::highestWins );
|
|
initStatAward( "rocketkills", 0, ::highestWins );
|
|
initStatAward( "equipmentkills", 0, ::highestWins );
|
|
initStatAward( "mostclasseschanged",0, ::highestWins );
|
|
initStatAward( "lowerrankkills", 0, ::highestWins );
|
|
initStatAward( "sprinttime", 0, ::highestWins, 1 );
|
|
initStatAward( "crouchtime", 0, ::highestWins );
|
|
initStatAward( "pronetime", 0, ::highestWins );
|
|
initStatAward( "comebacks", 0, ::highestWins );
|
|
initStatAward( "mostshotsfired", 0, ::highestWins );
|
|
initStatAward( "timeinspot", 0, ::highestWins );
|
|
initStatAward( "killcamtimewatched",0, ::highestWins );
|
|
initStatAward( "greatestavgalt", 0, ::highestWins );
|
|
initStatAward( "leastavgalt", 9999999, ::lowestWins );
|
|
|
|
// Offline/private match only awards
|
|
if ( !matchMakingGame() )
|
|
{
|
|
initStatAward( "killcamskipped", 0, ::highestWins );
|
|
initStatAward( "killsteals", 0, ::highestWins );
|
|
if ( !getGametypeNumLives() )
|
|
initStatAward( "deathstreak", 0, ::highestWins );
|
|
initStatAward( "shortestlife", 9999999, ::lowestWins );
|
|
initStatAward( "suicides", 0, ::highestWins );
|
|
initStatAward( "mostff", 0, ::highestWins );
|
|
initStatAward( "shotgundeaths", 0, ::highestWins );
|
|
initStatAward( "shielddeaths", 0, ::highestWins );
|
|
initStatAward( "flankdeaths", 0, ::highestWins ); // sets the process property of the "stat only" init above
|
|
initMultiAward( "participant", "nokills", "1death" );
|
|
initMultiAward( "afk", "nokills", "nodeaths" );
|
|
|
|
// special case post process award
|
|
initDerivedAward( "noawards" );
|
|
}
|
|
}
|
|
|
|
initBaseAward( ref )
|
|
{
|
|
assert( isDefined( ref ) );
|
|
|
|
level.awards[ ref ] = spawnStruct();
|
|
level.awards[ ref ].winners = [];
|
|
level.awards[ ref ].exclusive = true; // For now just make all awards exclusive
|
|
}
|
|
|
|
initAwardProcess( ref, process, var1, var2 )
|
|
{
|
|
if ( isDefined( process ) )
|
|
level.awards[ ref ].process = process;
|
|
|
|
if ( isDefined( var1 ) )
|
|
level.awards[ ref ].var1 = var1;
|
|
|
|
if ( isDefined( var2 ) )
|
|
level.awards[ ref ].var2 = var2;
|
|
}
|
|
|
|
initStat( ref, defaultvalue )
|
|
{
|
|
initBaseAward( ref );
|
|
level.awards[ ref ].defaultvalue = defaultvalue;
|
|
level.awards[ ref ].type = "stat";
|
|
}
|
|
|
|
initStatAward( ref, defaultvalue, process, var1, var2 )
|
|
{
|
|
initBaseAward( ref );
|
|
initAwardProcess( ref, process, var1, var2 );
|
|
level.awards[ ref ].defaultvalue = defaultvalue;
|
|
level.awards[ ref ].type = "stat";
|
|
}
|
|
|
|
initDerivedAward( ref, process, var1, var2 )
|
|
{
|
|
initBaseAward( ref );
|
|
initAwardProcess( ref, process, var1, var2 );
|
|
level.awards[ ref ].type = "derived";
|
|
}
|
|
|
|
initAwardFlag( ref, process, var1, var2 )
|
|
{
|
|
initBaseAward( ref );
|
|
initAwardProcess( ref, process, var1, var2 );
|
|
level.awards[ ref ].type = "flag";
|
|
}
|
|
|
|
initMultiAward( ref, award1_ref, award2_ref )
|
|
{
|
|
assert( isDefined( award1_ref ) );
|
|
assert( isDefined( award2_ref ) );
|
|
|
|
initBaseAward( ref );
|
|
level.awards[ ref ].award1_ref = award1_ref;
|
|
level.awards[ ref ].award2_ref = award2_ref;
|
|
level.awards[ ref ].type = "multi";
|
|
}
|
|
|
|
initThresholdAward( ref, process, var1, var2 )
|
|
{
|
|
initBaseAward( ref );
|
|
initAwardProcess( ref, process, var1, var2 );
|
|
level.awards[ ref ].type = "threshold";
|
|
}
|
|
|
|
setMatchRecordIfGreater( ref )
|
|
{
|
|
playerValue = self getPlayerStat( ref );
|
|
playerTime = self getPlayerStatTime( ref );
|
|
recordValue = getAwardRecord( ref );
|
|
recordTime = getAwardRecordTime( ref );
|
|
|
|
if ( !IsDefined( recordValue ) || ( playerValue > recordValue ) )
|
|
{
|
|
clearAwardWinners( ref );
|
|
addAwardWinner( ref, self.clientid );
|
|
setAwardRecord( ref, playerValue, playerTime );
|
|
}
|
|
else if ( playerValue == recordValue )
|
|
{
|
|
if ( isAwardExclusive( ref ) )
|
|
{
|
|
if ( !IsDefined( recordTime ) || ( playerTime < recordTime ) )
|
|
{
|
|
clearAwardWinners( ref );
|
|
addAwardWinner( ref, self.clientid );
|
|
setAwardRecord( ref, playerValue, playerTime );
|
|
}
|
|
}
|
|
else
|
|
addAwardWinner( ref, self.clientid );
|
|
}
|
|
}
|
|
|
|
setMatchRecordIfLower( ref )
|
|
{
|
|
playerValue = self getPlayerStat( ref );
|
|
playerTime = self getPlayerStatTime( ref );
|
|
recordValue = getAwardRecord( ref );
|
|
recordTime = getAwardRecordTime( ref );
|
|
|
|
if ( !IsDefined( recordValue ) || ( playerValue < recordValue ) )
|
|
{
|
|
clearAwardWinners( ref );
|
|
addAwardWinner( ref, self.clientid );
|
|
setAwardRecord( ref, playerValue, playerTime );
|
|
}
|
|
else if ( playerValue == recordValue )
|
|
{
|
|
if ( isAwardExclusive( ref ) )
|
|
{
|
|
if ( !IsDefined( recordTime ) || ( playerTime < recordTime ) )
|
|
{
|
|
clearAwardWinners( ref );
|
|
addAwardWinner( ref, self.clientid );
|
|
setAwardRecord( ref, playerValue, playerTime );
|
|
}
|
|
}
|
|
else
|
|
addAwardWinner( ref, self.clientid );
|
|
}
|
|
}
|
|
|
|
getDecodedRatio( value )
|
|
{
|
|
loVal = getRatioLoVal( value );
|
|
hiVal = getRatioHiVal( value );
|
|
|
|
if ( !loVal )
|
|
return ( hiVal + 0.001 ); // favor the "n:0" case
|
|
|
|
return ( hiVal / loVal );
|
|
}
|
|
|
|
setPersonalBestIfGreater( ref )
|
|
{
|
|
recordValue = self getPlayerData( "bests", ref );
|
|
playerValue = self getPlayerStat( ref );
|
|
|
|
if ( recordValue == 0 || ( playervalue > recordValue ) )
|
|
{
|
|
playerValue = getFormattedValue( ref, playerValue );
|
|
self setPlayerData( "bests", ref, playerValue );
|
|
}
|
|
}
|
|
|
|
setPersonalBestIfLower( ref )
|
|
{
|
|
recordvalue = self getPlayerData( "bests", ref );
|
|
playervalue = self getPlayerStat( ref );
|
|
|
|
if ( recordValue == 0 || ( playervalue < recordvalue ) )
|
|
{
|
|
playerValue = getFormattedValue( ref, playerValue );
|
|
self setPlayerData( "bests", ref, playerValue );
|
|
}
|
|
}
|
|
|
|
incPlayerRecord( ref )
|
|
{
|
|
recordValue = self getPlayerData( "awards", ref );
|
|
self setPlayerData( "awards", ref, recordValue + 1 );
|
|
|
|
/#
|
|
if ( !isDefined( self.statprint ) )
|
|
self.statprint = [];
|
|
|
|
if ( hasDisplayValue( ref ) )
|
|
value = self getPlayerStat( ref );
|
|
else
|
|
value = true;
|
|
|
|
stat = spawnstruct();
|
|
stat.ref = ref;
|
|
stat.value = value;
|
|
|
|
self.statprint[ self.statprint.size ] = stat;
|
|
#/
|
|
}
|
|
|
|
addAwardWinner( ref, clientid )
|
|
{
|
|
foreach ( winner in level.awards[ ref ].winners )
|
|
{
|
|
if ( winner == clientid )
|
|
return;
|
|
}
|
|
|
|
level.awards[ ref ].winners[ level.awards[ ref ].winners.size ] = clientid;
|
|
}
|
|
|
|
getAwardWinners( ref )
|
|
{
|
|
return level.awards[ ref ].winners;
|
|
}
|
|
|
|
clearAwardWinners( ref )
|
|
{
|
|
level.awards[ ref ].winners = [];
|
|
}
|
|
|
|
setAwardRecord( ref, value, time )
|
|
{
|
|
level.awards[ ref ].value = value;
|
|
level.awards[ ref ].time = time;
|
|
}
|
|
|
|
getAwardRecord( ref )
|
|
{
|
|
return level.awards[ ref ].value;
|
|
}
|
|
|
|
getAwardRecordTime( ref )
|
|
{
|
|
return level.awards[ ref ].time;
|
|
}
|
|
|
|
// does this work correctly for roundbased games?
|
|
assignAwards()
|
|
{
|
|
println( "Awards: Assigning" );
|
|
|
|
// Special case handling of awards which get stat values updated at the end of a game
|
|
foreach ( player in level.players )
|
|
{
|
|
kills = player getPlayerStat( "kills" );
|
|
deaths = player getPlayerStat( "deaths" );
|
|
|
|
if ( deaths == 0 )
|
|
deaths = 1;
|
|
|
|
player setPlayerStat( "kdratio", ( kills / deaths ) );
|
|
|
|
if ( isAlive( player ) )
|
|
{
|
|
timeAlive = getTime() - player.spawnTime;
|
|
player setPlayerStatIfGreater( "longestlife", timeAlive );
|
|
}
|
|
}
|
|
|
|
// process end of match stats
|
|
foreach ( ref, award in level.awards )
|
|
{
|
|
if ( !isDefined( level.awards[ ref ].process ) )
|
|
continue;
|
|
|
|
process = level.awards[ ref ].process;
|
|
var1 = level.awards[ ref ].var1;
|
|
var2 = level.awards[ ref ].var2;
|
|
|
|
if ( isDefined( var1 ) && isDefined( var2 ) )
|
|
[[ process ]]( ref, var1, var2 );
|
|
else if ( isDefined( var1 ) )
|
|
[[ process ]]( ref, var1 );
|
|
else
|
|
[[ process ]]( ref );
|
|
}
|
|
|
|
// set multi-award winners
|
|
foreach ( ref, award in level.awards )
|
|
{
|
|
if ( !isMultiAward( ref ) )
|
|
continue;
|
|
|
|
award1_ref = level.awards[ ref ].award1_ref;
|
|
award2_ref = level.awards[ ref ].award2_ref;
|
|
award1_winners = getAwardWinners( award1_ref );
|
|
award2_winners = getAwardWinners( award2_ref );
|
|
|
|
if ( !isDefined( award1_winners ) || !isDefined( award2_winners ) )
|
|
continue;
|
|
|
|
foreach ( winner1 in award1_winners )
|
|
{
|
|
foreach ( winner2 in award2_winners )
|
|
{
|
|
if ( winner1 == winner2 )
|
|
{
|
|
addAwardWinner( ref, winner1 );
|
|
player = playerForClientId( winner1 );
|
|
stat1 = player getPlayerStat( award1_ref );
|
|
stat2 = player getPlayerStat( award2_ref );
|
|
player setPlayerStat( ref, encodeRatio( stat1, stat2 ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// assign awards
|
|
foreach ( ref, award in level.awards )
|
|
{
|
|
if ( !isAwardFlag( ref ) )
|
|
assignAward( ref );
|
|
}
|
|
|
|
// assign "noawards" winners
|
|
if ( !matchMakingGame() )
|
|
{
|
|
foreach ( player in level.players )
|
|
{
|
|
awardCount = player getPlayerData( "round", "awardCount" );
|
|
if ( awardCount == 0 )
|
|
player giveAward( "noawards" );
|
|
}
|
|
}
|
|
|
|
foreach ( player in level.players )
|
|
{
|
|
awardCount = player getPlayerData( "round", "awardCount" );
|
|
|
|
println( "Awards: [", player.name, "] won ", awardCount, " awards" );
|
|
|
|
for ( i = 0; (i < awardCount && i < 3 ); i++ )
|
|
{
|
|
award = player getPlayerData( "round", "awards", i, "award" );
|
|
value = player getPlayerData( "round", "awards", i, "value" );
|
|
|
|
println( "Awards: [", player.name, "][", i, "] ", award, " ", value );
|
|
}
|
|
|
|
/#
|
|
if ( isDefined( player.statprint ) )
|
|
{
|
|
for ( i = 3; i < player.statprint.size; i++ )
|
|
println( "Awards: [", player.name, "][", i, "] ", player.statprint[i].ref, " ", player.statprint[i].value );
|
|
}
|
|
#/
|
|
}
|
|
|
|
println( "Awards: Finished assigning" );
|
|
}
|
|
|
|
assignAward( ref )
|
|
{
|
|
winners = getAwardWinners( ref );
|
|
if ( !isDefined( winners ) )
|
|
return;
|
|
|
|
foreach ( winner in winners )
|
|
{
|
|
foreach ( player in level.players )
|
|
{
|
|
if ( player.clientid == winner )
|
|
{
|
|
player giveAward( ref );
|
|
// /# player writeAwardLine( ref ); #/
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
getAwardType( ref )
|
|
{
|
|
if ( isDefined( level.awards[ ref ].type ) )
|
|
return level.awards[ ref ].type;
|
|
else
|
|
return "none";
|
|
}
|
|
|
|
isMultiAward( ref )
|
|
{
|
|
return ( getAwardType( ref ) == "multi" );
|
|
}
|
|
|
|
isStatAward( ref )
|
|
{
|
|
return ( getAwardType( ref ) == "stat" );
|
|
}
|
|
|
|
isThresholdAward( ref )
|
|
{
|
|
return ( getAwardType( ref ) == "threshold" );
|
|
}
|
|
|
|
isAwardFlag( ref )
|
|
{
|
|
return ( getAwardType( ref ) == "flag" );
|
|
}
|
|
|
|
isAwardExclusive( ref )
|
|
{
|
|
if ( isDefined( level.awards[ ref ].exclusive ) )
|
|
return level.awards[ ref ].exclusive;
|
|
else
|
|
return true;
|
|
}
|
|
|
|
hasDisplayValue( ref )
|
|
{
|
|
type = getAwardType( ref );
|
|
switch ( type )
|
|
{
|
|
case "derived":
|
|
hasDisplayValue = false;
|
|
break;
|
|
case "stat":
|
|
case "multi":
|
|
default:
|
|
hasDisplayValue = true;
|
|
break;
|
|
}
|
|
|
|
return ( hasDisplayValue );
|
|
}
|
|
|
|
giveAward( ref )
|
|
{
|
|
awardCount = self getPlayerData( "round", "awardCount" );
|
|
self incPlayerRecord( ref );
|
|
|
|
if ( hasDisplayValue( ref ) )
|
|
{
|
|
if ( isStatAward( ref ) )
|
|
assertex( self getPlayerStat( ref ) == getAwardRecord( ref ), "Ref is: " + ref + ", PlayerStat is: " + self getPlayerStat( ref ) + ", MatchRecord is: " + getAwardRecord( ref ) );
|
|
|
|
value = self getPlayerStat( ref );
|
|
}
|
|
else
|
|
value = true;
|
|
|
|
value = getFormattedValue( ref, value );
|
|
|
|
if ( awardCount < 3 )
|
|
{
|
|
self setPlayerData( "round", "awards", awardCount, "award", ref );
|
|
self setPlayerData( "round", "awards", awardCount, "value", value );
|
|
}
|
|
|
|
awardCount++;
|
|
self SetPlayerData( "round", "awardCount", awardCount );
|
|
|
|
if ( awardCount == 1 )
|
|
maps\mp\_highlights::giveHighlight( ref, value );
|
|
}
|
|
|
|
getFormattedValue( ref, value )
|
|
{
|
|
awardFormat = tableLookup( "mp/awardTable.csv", 1, ref, 7 );
|
|
switch ( awardFormat )
|
|
{
|
|
case "float":
|
|
value = limitDecimalPlaces( value, 2 );
|
|
value = value * 100;
|
|
break;
|
|
case "ratio":
|
|
case "multi":
|
|
case "count":
|
|
case "time":
|
|
case "distance":
|
|
case "none":
|
|
default:
|
|
break;
|
|
}
|
|
|
|
value = int( value );
|
|
return ( value );
|
|
}
|
|
|
|
highestWins( ref, minAwardable )
|
|
{
|
|
foreach ( player in level.players )
|
|
{
|
|
if ( player statValueChanged( ref ) && ( !isDefined( minAwardable ) || player getPlayerStat( ref ) >= minAwardable ) )
|
|
{
|
|
player setMatchRecordIfGreater( ref );
|
|
if ( !isAwardFlag( ref ) )
|
|
player setPersonalBestIfGreater( ref );
|
|
}
|
|
}
|
|
}
|
|
|
|
lowestWins( ref, maxAwardable)
|
|
{
|
|
foreach ( player in level.players )
|
|
{
|
|
if ( player statValueChanged( ref ) && ( !isDefined( maxAwardable ) || player getPlayerStat( ref ) <= maxAwardable ) )
|
|
{
|
|
player setMatchRecordIfLower( ref );
|
|
if ( !isAwardFlag( ref ) )
|
|
player setPersonalBestIfLower( ref );
|
|
}
|
|
}
|
|
}
|
|
|
|
lowestWithHalfPlayedTime( ref )
|
|
{
|
|
gameLength = getTimePassed() / 1000;
|
|
halfGameLength = gameLength * 0.5;
|
|
|
|
foreach ( player in level.players )
|
|
{
|
|
// hasSpawned check is required or players who pick a team and never spawn can win awards
|
|
if ( player.hasSpawned && player.timePlayed["total"] >= halfGameLength )
|
|
{
|
|
player setMatchRecordIfLower( ref );
|
|
if ( !isAwardFlag( ref ) )
|
|
player setPersonalBestIfLower( ref );
|
|
}
|
|
}
|
|
}
|
|
|
|
statValueChanged( ref )
|
|
{
|
|
playervalue = self getPlayerStat( ref );
|
|
defaultvalue = level.awards[ ref ].defaultvalue;
|
|
|
|
if ( playervalue == defaultvalue )
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
|
|
|
|
isAtLeast( ref, minimum, checkAwardRef )
|
|
{
|
|
foreach ( player in level.players )
|
|
{
|
|
playerValue = player getPlayerStat( checkAwardRef );
|
|
checkValue = playerValue;
|
|
|
|
if ( checkValue >= minimum )
|
|
addAwardWinner( ref, player.clientid );
|
|
|
|
// TODO: Instead of copying the value, reference the other stat directly
|
|
if ( isThresholdAward( ref ) || isAwardFlag( ref ) )
|
|
player setPlayerStat( ref, playerValue );
|
|
}
|
|
}
|
|
|
|
|
|
isAtMost( ref, maximum, award_ref )
|
|
{
|
|
foreach ( player in level.players )
|
|
{
|
|
playerValue = player getPlayerStat( award_ref );
|
|
|
|
if ( playerValue <= maximum )
|
|
addAwardWinner( ref, player.clientid );
|
|
}
|
|
}
|
|
|
|
|
|
isAtMostWithHalfPlayedTime( ref, maximum, award_ref )
|
|
{
|
|
gameLength = getTimePassed() / 1000;
|
|
halfGameLength = gameLength * 0.5;
|
|
|
|
foreach ( player in level.players )
|
|
{
|
|
// hasSpawned check is required or players who pick a team and never spawn can win awards
|
|
if ( player.hasSpawned && player.timePlayed["total"] >= halfGameLength )
|
|
{
|
|
playerValue = player getPlayerStat( award_ref );
|
|
|
|
if ( playerValue <= maximum )
|
|
addAwardWinner( ref, player.clientid );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
setRatio( ref, award1_ref, award2_ref )
|
|
{
|
|
foreach ( player in level.players )
|
|
{
|
|
playerValue1 = player getPlayerStat( award1_ref );
|
|
playerValue2 = player getPlayerStat( award2_ref );
|
|
|
|
if ( playerValue2 == 0 )
|
|
player setPlayerStat( ref, playerValue1 );
|
|
else
|
|
{
|
|
ratio = playerValue1 / playerValue2;
|
|
player setPlayerStat( ref, ratio );
|
|
}
|
|
}
|
|
}
|
|
|
|
getKillstreakAwardRef( streakName )
|
|
{
|
|
switch( streakName )
|
|
{
|
|
case "uav":
|
|
case "double_uav":
|
|
case "counter_uav":
|
|
return "uavs";
|
|
case "airstrike":
|
|
case "precision_airstrike":
|
|
case "stealth_airstrike":
|
|
case "harrier_airstrike":
|
|
case "super_airstrike":
|
|
return "airstrikes";
|
|
case "helicopter":
|
|
case "helicopter_minigun":
|
|
case "helicopter_mk19":
|
|
case "helicopter_blackbox":
|
|
case "helicopter_flares":
|
|
return "helicopters";
|
|
default:
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
monitorReloads()
|
|
{
|
|
level endon( "game_ended" );
|
|
self endon( "spawned_player" );
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
|
|
for ( ;; )
|
|
{
|
|
self waittill( "reload" );
|
|
self incPlayerStat( "mostreloads", 1 );
|
|
}
|
|
}
|
|
|
|
monitorShotsFired()
|
|
{
|
|
level endon( "game_ended" );
|
|
self endon( "spawned_player" );
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
|
|
for ( ;; )
|
|
{
|
|
self waittill( "weapon_fired" );
|
|
self incPlayerStat( "mostshotsfired", 1 );
|
|
}
|
|
}
|
|
|
|
monitorSwaps()
|
|
{
|
|
level endon( "game_ended" );
|
|
self endon( "spawned_player" );
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
|
|
lastWeapon = "none";
|
|
|
|
for ( ;; )
|
|
{
|
|
self waittill( "weapon_change", weapon );
|
|
|
|
if ( lastWeapon == weapon )
|
|
continue;
|
|
|
|
if ( weapon == "none" )
|
|
continue;
|
|
|
|
if ( ! maps\mp\gametypes\_weapons::isPrimaryWeapon( weapon ) )
|
|
continue;
|
|
|
|
lastWeapon = weapon;
|
|
|
|
self incPlayerStat( "mostswaps", 1 );
|
|
|
|
alreadyUsed = false;
|
|
|
|
//creates an array of weapons used
|
|
foreach( usedWeapon in self.usedWeapons )
|
|
{
|
|
if ( weapon == usedWeapon )
|
|
{
|
|
alreadyUsed = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( !alreadyUsed )
|
|
{
|
|
self.usedWeapons[self.usedWeapons.size] = weapon;
|
|
self incPlayerStat( "mostweaponsused", 1 );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
monitorMovementDistance()
|
|
{
|
|
level endon( "game_ended" );
|
|
self endon( "disconnect" );
|
|
|
|
for ( ;; )
|
|
{
|
|
foreach ( player in level.players )
|
|
{
|
|
if ( !isAlive( Player ) )
|
|
continue;
|
|
|
|
if ( player.deaths != player.previousDeaths )
|
|
{
|
|
player.prevPos = player.origin;
|
|
player.previousDeaths = player.deaths;
|
|
}
|
|
|
|
distanceTraveled = Distance( player.origin, player.prevPos );
|
|
player incPlayerStat( "distancetraveled", distanceTraveled );
|
|
|
|
player.prevPos = player.origin;
|
|
|
|
player.altitudePolls++;
|
|
player.totalAltitudeSum += player.origin[2];
|
|
avgAltitude = player.totalAltitudeSum / player.altitudePolls;
|
|
player setPlayerStat( "leastavgalt", avgAltitude );
|
|
player setPlayerStat( "greatestavgalt", avgAltitude );
|
|
|
|
wait( 0.05 );
|
|
}
|
|
wait( 0.05 );
|
|
}
|
|
}
|
|
|
|
monitorPositionCamping()
|
|
{
|
|
level endon( "game_ended" );
|
|
self endon( "disconnect" );
|
|
|
|
self.lastCampChecked = getTime();
|
|
self.positionArray = [];
|
|
|
|
CAMPTHRESHOLD = 512;
|
|
|
|
for ( ;; )
|
|
{
|
|
if ( !isAlive( self ) )
|
|
{
|
|
wait( 0.5 );
|
|
self.lastCampChecked = getTime();
|
|
self.positionArray = [];
|
|
continue;
|
|
}
|
|
self.positionArray[self.positionArray.size] = self.origin;
|
|
|
|
if ( ( getTime() - self.lastCampChecked ) >= 15000 )
|
|
{
|
|
if ( Distance( self.positionArray[0], self.origin ) < CAMPTHRESHOLD && Distance( self.positionArray[1], self.positionArray[0] ) < CAMPTHRESHOLD )
|
|
{
|
|
timeCamping = getTime() - self.lastCampChecked;
|
|
self incPlayerStat( "timeinspot", timeCamping );
|
|
}
|
|
|
|
self.positionArray = [];
|
|
|
|
self.lastCampChecked = getTime();
|
|
}
|
|
wait( 5 );
|
|
}
|
|
}
|
|
|
|
encodeRatio( value1, value2 )
|
|
{
|
|
return ( value1 + (value2 << 16) );
|
|
}
|
|
|
|
getRatioHiVal( value )
|
|
{
|
|
return (value & 65535);
|
|
}
|
|
|
|
getRatioLoVal( value )
|
|
{
|
|
return (value >> 16);
|
|
}
|
|
|
|
monitorEnemyDistance()
|
|
{
|
|
level endon( "game_ended" );
|
|
self endon( "disconnect" );
|
|
|
|
while( level.players.size < 3 )
|
|
wait( 1 );
|
|
|
|
prof_begin( "EnemyDistance" );
|
|
for ( ;; )
|
|
{
|
|
foreach ( player in level.players )
|
|
{
|
|
|
|
if ( !isdefined( player ) )
|
|
continue;
|
|
|
|
if ( player.team == "spectator" )
|
|
continue;
|
|
|
|
if ( !isAlive( player ) )
|
|
continue;
|
|
|
|
sortedPlayersByDistance = SortByDistance( level.players, player.origin );
|
|
|
|
if( !sortedPlayersByDistance.size )
|
|
{
|
|
wait( 0.05 );
|
|
continue;
|
|
}
|
|
|
|
if ( sortedPlayersByDistance.size < 2 )
|
|
{
|
|
wait( 0.05 );
|
|
continue;
|
|
}
|
|
|
|
if ( sortedPlayersByDistance[1].team != player.team )
|
|
player incPlayerStat( "closertoenemies", 0.05 );
|
|
|
|
wait( 0.05 );
|
|
}
|
|
|
|
wait( 0.05);
|
|
}
|
|
|
|
prof_end( "EnemyDistance" );
|
|
}
|
|
|
|
monitorClassChange()
|
|
{
|
|
level endon( "game_ended" );
|
|
self endon( "disconnect" );
|
|
|
|
for(;;)
|
|
{
|
|
self waittill( "spawned" );
|
|
|
|
if ( self.team == "spectator" )
|
|
continue;
|
|
|
|
if( isDefined( self.lastClass ) && self.lastClass != "" && self.lastClass != self.class )
|
|
{
|
|
self incPlayerStat( "mostclasseschanged", 1 );
|
|
}
|
|
|
|
self.lastClass = self.class;
|
|
}
|
|
}
|
|
|
|
monitorExplosionsSurvived()
|
|
{
|
|
level endon( "game_ended" );
|
|
self endon( "spawned_player" );
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
|
|
for(;;)
|
|
{
|
|
self waittill( "survived_explosion" );
|
|
self incPlayerStat( "explosionssurvived", 1 );
|
|
wait( 0.05 );
|
|
}
|
|
}
|
|
|
|
monitorShieldBlocks()
|
|
{
|
|
level endon( "game_ended" );
|
|
self endon( "spawned_player" );
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
|
|
for(;;)
|
|
{
|
|
self waittill( "shield_blocked" );
|
|
self incPlayerStat( "shieldblocks", 1 );
|
|
wait( 0.05 );
|
|
}
|
|
}
|
|
|
|
monitorFlashHits()
|
|
{
|
|
level endon( "game_ended" );
|
|
self endon( "spawned_player" );
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
|
|
for(;;)
|
|
{
|
|
self waittill( "flash_hit" );
|
|
self incPlayerStat( "fbhits", 1 );
|
|
wait( 0.05 );
|
|
}
|
|
}
|
|
|
|
monitorStunHits()
|
|
{
|
|
level endon( "game_ended" );
|
|
self endon( "spawned_player" );
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
|
|
for(;;)
|
|
{
|
|
self waittill( "stun_hit" );
|
|
self incPlayerStat( "stunhits", 1 );
|
|
wait( 0.05 );
|
|
}
|
|
}
|
|
|
|
//this approximates a players time spent in crouch or prone.
|
|
monitorStanceTime()
|
|
{
|
|
level endon( "game_ended" );
|
|
self endon( "spawned_player" );
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
|
|
for(;;)
|
|
{
|
|
if ( self GetStance() == "crouch" )
|
|
self incPlayerStat( "crouchtime", 500 );
|
|
else if ( self GetStance() == "prone" )
|
|
self incPlayerStat( "pronetime", 500 );
|
|
|
|
wait( 0.5 );
|
|
}
|
|
} |