534 lines
18 KiB
Plaintext
534 lines
18 KiB
Plaintext
#using scripts\shared\callbacks_shared;
|
|
#using scripts\shared\rank_shared;
|
|
#using scripts\shared\scoreevents_shared;
|
|
#using scripts\shared\system_shared;
|
|
#using scripts\shared\util_shared;
|
|
|
|
#using scripts\shared\bots\_bot;
|
|
|
|
|
|
|
|
#namespace persistence;
|
|
|
|
function autoexec __init__sytem__() { system::register("persistence",&__init__,undefined,undefined); }
|
|
|
|
function __init__()
|
|
{
|
|
callback::on_start_gametype( &init );
|
|
callback::on_connect( &on_player_connect );
|
|
}
|
|
|
|
function init()
|
|
{
|
|
level.can_set_aar_stat = true;
|
|
level.persistentDataInfo = [];
|
|
level.maxRecentStats = 10;
|
|
level.maxHitLocations = 19;
|
|
|
|
//level thread _properks::init();
|
|
|
|
level thread initialize_stat_tracking();
|
|
level thread upload_global_stat_counters();
|
|
}
|
|
|
|
function on_player_connect()
|
|
{
|
|
self.enableText = true;
|
|
}
|
|
|
|
function initialize_stat_tracking()
|
|
{
|
|
level.globalExecutions = 0;
|
|
level.globalChallenges = 0;
|
|
level.globalSharePackages = 0;
|
|
level.globalContractsFailed = 0;
|
|
level.globalContractsPassed = 0;
|
|
level.globalContractsCPPaid = 0;
|
|
level.globalKillstreaksCalled = 0;
|
|
level.globalKillstreaksDestroyed = 0;
|
|
level.globalKillstreaksDeathsFrom = 0;
|
|
level.globalLarrysKilled = 0;
|
|
level.globalBuzzKills = 0;
|
|
level.globalRevives = 0;
|
|
level.globalAfterlifes = 0;
|
|
level.globalComebacks = 0;
|
|
level.globalPaybacks = 0;
|
|
level.globalBackstabs = 0;
|
|
level.globalBankshots = 0;
|
|
level.globalSkewered = 0;
|
|
level.globalTeamMedals = 0;
|
|
level.globalFeetFallen = 0;
|
|
level.globalDistanceSprinted = 0;
|
|
level.globalDemBombsProtected = 0;
|
|
level.globalDemBombsDestroyed = 0;
|
|
level.globalBombsDestroyed = 0;
|
|
level.globalFragGrenadesFired = 0;
|
|
level.globalSatchelChargeFired = 0;
|
|
level.globalShotsFired = 0;
|
|
level.globalCrossbowFired = 0;
|
|
level.globalCarsDestroyed = 0;
|
|
level.globalBarrelsDestroyed = 0;
|
|
|
|
level.globalBombsDestroyedByTeam = [];
|
|
|
|
foreach( team in level.teams )
|
|
{
|
|
level.globalBombsDestroyedByTeam[team] = 0;
|
|
}
|
|
}
|
|
|
|
function upload_global_stat_counters()
|
|
{
|
|
level waittill("game_ended");
|
|
|
|
if ( !level.rankedMatch && !level.wagerMatch )
|
|
return;
|
|
|
|
totalKills = 0;
|
|
totalDeaths = 0;
|
|
totalAssists = 0;
|
|
totalHeadshots = 0;
|
|
totalSuicides = 0;
|
|
totalTimePlayed = 0;
|
|
totalFlagsCaptured = 0;
|
|
totalFlagsReturned = 0;
|
|
totalHQsDestroyed = 0;
|
|
totalHQsCaptured = 0;
|
|
totalSDDefused = 0;
|
|
totalSDPlants = 0;
|
|
totalHumiliations = 0;
|
|
|
|
totalSabDestroyedByTeam = [];
|
|
foreach ( team in level.teams )
|
|
{
|
|
totalSabDestroyedByTeam[team] = 0;
|
|
}
|
|
|
|
switch ( level.gameType )
|
|
{
|
|
case "dem":
|
|
{
|
|
bombZonesLeft = 0;
|
|
|
|
for ( index = 0; index < level.bombZones.size; index++ )
|
|
{
|
|
if ( !isdefined( level.bombZones[index].bombExploded ) || !level.bombZones[index].bombExploded )
|
|
level.globalDemBombsProtected++;
|
|
else
|
|
level.globalDemBombsDestroyed++;
|
|
}
|
|
}
|
|
break;
|
|
case "sab":
|
|
{
|
|
foreach ( team in level.teams )
|
|
{
|
|
totalSabDestroyedByTeam[team] = level.globalBombsDestroyedByTeam[team];
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
players = GetPlayers();
|
|
for( i = 0; i < players.size; i++)
|
|
{
|
|
player = players[i];
|
|
if ( isdefined( player.timePlayed ) && isdefined( player.timePlayed["total"] ) )
|
|
{
|
|
totalTimePlayed += min( player.timePlayed["total"], level.timeplayedcap );
|
|
}
|
|
}
|
|
|
|
if ( !util::wasLastRound() )
|
|
return;
|
|
|
|
{wait(.05);};
|
|
|
|
players = GetPlayers();
|
|
for( i = 0; i < players.size; i++)
|
|
{
|
|
player = players[i];
|
|
totalKills += player.kills;
|
|
totalDeaths += player.deaths;
|
|
totalAssists += player.assists;
|
|
totalHeadshots += player.headshots;
|
|
totalSuicides += player.suicides;
|
|
totalHumiliations += player.humiliated;
|
|
if ( isdefined( player.timePlayed ) && isdefined( player.timePlayed["alive"] ) )
|
|
{
|
|
totalTimePlayed += int( min( player.timePlayed["alive"], level.timeplayedcap ) );
|
|
}
|
|
|
|
switch ( level.gameType )
|
|
{
|
|
case "ctf":
|
|
{
|
|
totalFlagsCaptured += player.captures;
|
|
totalFlagsReturned += player.returns;
|
|
}
|
|
break;
|
|
case "koth":
|
|
{
|
|
totalHQsDestroyed += player.destructions;
|
|
totalHQsCaptured += player.captures;
|
|
}
|
|
break;
|
|
case "sd":
|
|
{
|
|
totalSDDefused += player.defuses;
|
|
totalSDPlants += player.plants;
|
|
}
|
|
break;
|
|
case "sab":
|
|
{
|
|
if ( isdefined(player.team) && isdefined( level.teams[ player.team ] ) )
|
|
{
|
|
totalSabDestroyedByTeam[player.team] += player.destructions;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// ==========================================
|
|
// Script persistent data functions
|
|
// These are made for convenience, so persistent data can be tracked by strings.
|
|
// They make use of code functions which are prototyped below.
|
|
|
|
function stat_get_with_gametype( dataName )
|
|
{
|
|
if( isdefined( level.noPersistence ) && level.noPersistence )
|
|
return 0;
|
|
|
|
if ( !level.onlineGame )
|
|
return 0;
|
|
|
|
return ( self getdstat( "PlayerStatsByGameType", get_gametype_name(), dataName, "StatValue" ) );
|
|
}
|
|
|
|
function get_gametype_name()
|
|
{
|
|
if ( !isdefined( level.fullGameTypeName ) )
|
|
{
|
|
if ( isdefined( level.hardcoreMode ) && level.hardcoreMode && is_party_gamemode() == false )
|
|
{
|
|
prefix = "HC";
|
|
}
|
|
else
|
|
{
|
|
prefix = "";
|
|
}
|
|
|
|
level.fullGameTypeName = toLower( prefix + level.gametype );
|
|
}
|
|
|
|
return level.fullGameTypeName;
|
|
|
|
}
|
|
|
|
function is_party_gamemode()
|
|
{
|
|
switch( level.gametype )
|
|
{
|
|
case "gun":
|
|
case "oic":
|
|
case "shrp":
|
|
case "sas":
|
|
return true;
|
|
break;
|
|
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function is_stat_modifiable( dataName )
|
|
{
|
|
return level.rankedMatch || level.wagerMatch;
|
|
}
|
|
|
|
function stat_set_with_gametype( dataName, value, incValue )
|
|
{
|
|
if( isdefined( level.noPersistence ) && level.noPersistence )
|
|
return 0;
|
|
|
|
if ( !is_stat_modifiable( dataName ) )
|
|
return;
|
|
|
|
if ( level.disableStatTracking )
|
|
{
|
|
return;
|
|
}
|
|
|
|
self setdstat( "PlayerStatsByGameType", get_gametype_name(), dataName, "StatValue", value );
|
|
}
|
|
|
|
function adjust_recent_stats()
|
|
{
|
|
/#
|
|
if( GetDvarint( "scr_writeconfigstrings" ) == 1 || GetDvarint( "scr_hostmigrationtest" ) == 1 )
|
|
return;
|
|
#/
|
|
|
|
initialize_match_stats();
|
|
}
|
|
|
|
function get_recent_stat( isGlobal, index, statName )
|
|
{
|
|
if( level.wagerMatch )
|
|
{
|
|
return self getdstat( "RecentEarnings", index, statName );
|
|
}
|
|
else if( isGlobal )
|
|
{
|
|
modeName = util::GetCurrentGameMode();
|
|
return self getdstat( "gameHistory", modeName, "matchHistory", index, statName );
|
|
}
|
|
else
|
|
{
|
|
return self getdstat( "PlayerStatsByGameType", get_gametype_name(), "prevScores" , index, statName );
|
|
}
|
|
}
|
|
|
|
function set_recent_stat( isGlobal, index, statName, value )
|
|
{
|
|
if ( !isGlobal )
|
|
{
|
|
index = self GetDStat( "PlayerStatsByGameType", get_gametype_name(), "prevScoreIndex" );
|
|
|
|
if ( index < 0 || index > 9 )
|
|
return;
|
|
}
|
|
|
|
if( isdefined( level.noPersistence ) && level.noPersistence )
|
|
return;
|
|
|
|
if ( !level.onlineGame )
|
|
return;
|
|
|
|
if ( !is_stat_modifiable( statName ) )
|
|
return;
|
|
|
|
if( level.wagerMatch )
|
|
{
|
|
self setdstat( "RecentEarnings", index, statName, value );
|
|
}
|
|
else if( isGlobal )
|
|
{
|
|
modeName = util::GetCurrentGameMode();
|
|
self setdstat( "gameHistory", modeName, "matchHistory", "" + index, statName, value );
|
|
}
|
|
else
|
|
{
|
|
self setdstat( "PlayerStatsByGameType", get_gametype_name(), "prevScores", index, statName, value );
|
|
}
|
|
}
|
|
|
|
function add_recent_stat( isGlobal, index, statName, value )
|
|
{
|
|
if( isdefined( level.noPersistence ) && level.noPersistence )
|
|
return;
|
|
|
|
if ( !level.onlineGame )
|
|
return;
|
|
|
|
if ( !is_stat_modifiable( statName ) )
|
|
return;
|
|
|
|
if ( !isGlobal )
|
|
{
|
|
index = self GetDStat( "PlayerStatsByGameType", get_gametype_name(), "prevScoreIndex" );
|
|
|
|
if ( index < 0 || index > 9 )
|
|
return;
|
|
}
|
|
|
|
currStat = get_recent_stat( isGlobal, index, statName );
|
|
set_recent_stat( isGlobal, index, statName, currStat + value );
|
|
}
|
|
|
|
function set_match_history_stat( statName, value )
|
|
{
|
|
modeName = util::GetCurrentGameMode();
|
|
historyIndex = self GetDStat( "gameHistory", modeName, "currentMatchHistoryIndex" );
|
|
|
|
set_recent_stat( true, historyIndex, statName, value );
|
|
}
|
|
|
|
function add_match_history_stat( statName, value )
|
|
{
|
|
modeName = util::GetCurrentGameMode();
|
|
historyIndex = self GetDStat( "gameHistory", modeName, "currentMatchHistoryIndex" );
|
|
|
|
add_recent_stat( true, historyIndex, statName, value );
|
|
}
|
|
|
|
function initialize_match_stats()
|
|
{
|
|
if( isdefined( level.noPersistence ) && level.noPersistence )
|
|
return;
|
|
|
|
if ( !level.onlineGame )
|
|
return;
|
|
|
|
if ( !( level.rankedMatch || level.wagerMatch || level.leagueMatch ) )
|
|
return;
|
|
|
|
self.pers["lastHighestScore"] = self getDStat( "HighestStats", "highest_score" );
|
|
|
|
if (SessionModeIsMultiplayerGame())
|
|
{
|
|
self.pers["lastHighestKills"] = self getDStat( "HighestStats", "highest_kills" );
|
|
self.pers["lastHighestKDRatio"] = self getDStat( "HighestStats", "highest_kdratio" );
|
|
}
|
|
|
|
currGameType = get_gametype_name();
|
|
self GameHistoryStartMatch( getGameTypeEnumFromName( currGameType, level.hardcoreMode ) );
|
|
}
|
|
|
|
function can_set_aar_stat()
|
|
{
|
|
return level.can_set_aar_stat;
|
|
}
|
|
|
|
function set_after_action_report_player_stat( playerIndex, statName, value )
|
|
{
|
|
if ( can_set_aar_stat() )
|
|
{
|
|
self setdstat( "AfterActionReportStats", "playerStats", playerIndex, statName, value );
|
|
}
|
|
}
|
|
|
|
function set_after_action_report_player_medal( playerIndex, medalIndex, value )
|
|
{
|
|
if ( can_set_aar_stat() )
|
|
{
|
|
self setdstat( "AfterActionReportStats", "playerStats", playerIndex, "medals", medalIndex, value );
|
|
}
|
|
}
|
|
|
|
function set_after_action_report_stat( statName, value, index )
|
|
{
|
|
if( self util::is_bot() )
|
|
return;
|
|
|
|
/#
|
|
if( GetDvarint( "scr_writeconfigstrings" ) == 1 || GetDvarint( "scr_hostmigrationtest" ) == 1 )
|
|
return;
|
|
#/
|
|
|
|
if ( can_set_aar_stat() )
|
|
{
|
|
if ( isdefined( index ) )
|
|
self setAARStat( statName, index, value );
|
|
else
|
|
self setAARStat( statName, value );
|
|
}
|
|
}
|
|
|
|
function CodeCallback_ChallengeComplete( rewardXP, maxVal, row, tableNumber, challengeType, itemIndex, challengeIndex )
|
|
{
|
|
params = Spawnstruct();
|
|
params.rewardXP = rewardXP;
|
|
params.maxVal = maxVal;
|
|
params.row = row;
|
|
params.tableNumber = tableNumber;
|
|
params.challengeType = challengeType;
|
|
params.itemIndex = itemIndex;
|
|
params.challengeIndex = challengeIndex;
|
|
|
|
//No campaign notifications, handled in AAR
|
|
if ( SessionModeIsCampaignGame() )
|
|
{
|
|
if( isdefined( self.challenge_callback_cp ) )
|
|
{
|
|
[[ self.challenge_callback_cp ]]( rewardXP, maxVal, row, tableNumber, challengeType, itemIndex, challengeIndex );
|
|
}
|
|
return;
|
|
}
|
|
|
|
callback::callback( #"on_challenge_complete", params );
|
|
|
|
self LUINotifyEvent( &"challenge_complete", 7, challengeIndex, itemIndex, challengeType, tableNumber, row, maxVal, rewardXP );
|
|
self LUINotifyEventToSpectators( &"challenge_complete", 7, challengeIndex, itemIndex, challengeType, tableNumber, row, maxVal, rewardXP );
|
|
|
|
tableNumber = tableNumber + 1;
|
|
tableName = "gamedata/stats/mp/statsmilestones" + tableNumber + ".csv";
|
|
challengeString = tableLookupColumnForRow( tableName, row, 5 );
|
|
challengeTier = int( tableLookupColumnForRow( tableName, row, 1 ) );
|
|
|
|
matchRecordLogChallengeComplete( self, tableNumber, challengeTier, itemIndex, challengeString );
|
|
|
|
/#
|
|
if ( GetDvarInt( "scr_debugchallenges", 0 ) != 0 )
|
|
{
|
|
challengeDescString = challengeString + "_DESC";
|
|
challengeTierNext = int( tableLookupColumnForRow( tableName, row+1, 1 ) );
|
|
tierText = "CHALLENGE_TIER_" + challengeTier;
|
|
statstableName = "gamedata/stats/mp/mp_statstable.csv";
|
|
|
|
heroString = tablelookup( statsTableName, 0, itemIndex, 3 );
|
|
|
|
if ( GetDvarInt( "scr_debugchallenges") == 1 )
|
|
{
|
|
iprintlnbold( makelocalizedstring( challengeString ) + " 1:" + maxVal + " 2:" + makelocalizedstring( heroString ) );
|
|
}
|
|
else if ( GetDvarInt( "scr_debugchallenges" ) == 2 )
|
|
{
|
|
self iprintlnbold( makelocalizedstring( challengeString ) + " 1:" + maxVal + " 2:" + makelocalizedstring( heroString ) );
|
|
}
|
|
else if ( GetDvarInt( "scr_debugchallenges") == 3 )
|
|
{
|
|
iprintln( makelocalizedstring( challengeString ) + " 1:" + maxVal + " 2:" + makelocalizedstring( heroString ) );
|
|
}
|
|
}
|
|
#/
|
|
}
|
|
|
|
function CodeCallback_GunChallengeComplete( rewardXP, attachmentIndex, itemIndex, rankID, isLastRank )
|
|
{
|
|
if ( SessionModeIsCampaignGame() )
|
|
{
|
|
self notify("gun_level_complete", rewardXP, attachmentIndex, itemIndex, rankID, isLastRank);
|
|
return;
|
|
}
|
|
|
|
self LUINotifyEvent( &"gun_level_complete", 4, rankID, itemIndex, attachmentIndex, rewardXP );
|
|
self LUINotifyEventToSpectators( &"gun_level_complete", 4, rankID, itemIndex, attachmentIndex, rewardXP );
|
|
}
|
|
|
|
function check_contract_expirations()
|
|
{
|
|
}
|
|
|
|
function increment_contract_times( timeInc )
|
|
{
|
|
}
|
|
|
|
function add_contract_to_queue( index, passed )
|
|
{
|
|
}
|
|
|
|
function upload_stats_soon()
|
|
{
|
|
self notify( "upload_stats_soon" );
|
|
self endon( "upload_stats_soon" );
|
|
self endon( "disconnect" );
|
|
|
|
wait 1;
|
|
UploadStats( self );
|
|
}
|
|
|
|
function CodeCallback_OnAddPlayerStat(dataName, value)
|
|
{
|
|
}
|
|
|
|
function CodeCallback_OnAddWeaponStat(weapon, dataName, value)
|
|
{
|
|
}
|
|
|
|
function process_contracts_on_add_stat(statType, dataName, value, weapon)
|
|
{
|
|
}
|