1065 lines
33 KiB
Plaintext
1065 lines
33 KiB
Plaintext
#using scripts\codescripts\struct;
|
|
|
|
#using scripts\shared\callbacks_shared;
|
|
#using scripts\shared\hud_shared;
|
|
#using scripts\shared\scoreevents_shared;
|
|
#using scripts\shared\system_shared;
|
|
#using scripts\shared\util_shared;
|
|
|
|
|
|
|
|
|
|
|
|
#precache( "material", "white" );
|
|
#precache( "string", "MP_PLUS" );
|
|
|
|
#namespace rank;
|
|
|
|
function autoexec __init__sytem__() { system::register("rank",&__init__,undefined,undefined); }
|
|
|
|
function __init__()
|
|
{
|
|
callback::on_start_gametype( &init );
|
|
}
|
|
|
|
function init()
|
|
{
|
|
level.scoreInfo = [];
|
|
level.codPointsXpScale = GetDvarfloat( "scr_codpointsxpscale" );
|
|
level.codPointsMatchScale = GetDvarfloat( "scr_codpointsmatchscale" );
|
|
level.codPointsChallengeScale = GetDvarfloat( "scr_codpointsperchallenge" );
|
|
level.rankXpCap = GetDvarint( "scr_rankXpCap" );
|
|
level.codPointsCap = GetDvarint( "scr_codPointsCap" );
|
|
level.usingMomentum = true;
|
|
level.usingScoreStreaks = GetDvarInt( "scr_scorestreaks" ) != 0;
|
|
level.scoreStreaksMaxStacking = GetDvarInt( "scr_scorestreaks_maxstacking" );
|
|
level.maxInventoryScoreStreaks = GetDvarInt( "scr_maxinventory_scorestreaks", 3 );
|
|
level.usingRampage = !isdefined( level.usingScoreStreaks ) || !level.usingScoreStreaks;
|
|
level.rampageBonusScale = GetDvarFloat( "scr_rampagebonusscale" );
|
|
|
|
level.rankTable = [];
|
|
|
|
if ( SessionModeIsCampaignGame() )
|
|
{
|
|
level.xpScale = GetDvarFloat( "scr_xpscalecp" );
|
|
|
|
level.ranktable_name = "gamedata/tables/cp/cp_ranktable.csv";
|
|
level.rankicontable_name = "gamedata/tables/cp/cp_rankIconTable.csv";
|
|
}
|
|
else if ( SessionModeIsZombiesGame() )
|
|
{
|
|
level.xpScale = GetDvarFloat( "scr_xpscalezm" );
|
|
|
|
level.ranktable_name = "gamedata/tables/zm/zm_ranktable.csv";
|
|
level.rankicontable_name = "gamedata/tables/zm/zm_rankIconTable.csv";
|
|
}
|
|
else
|
|
{
|
|
level.xpScale = GetDvarFloat( "scr_xpscalemp" );
|
|
|
|
level.ranktable_name = "gamedata/tables/mp/mp_ranktable.csv";
|
|
level.rankicontable_name = "gamedata/tables/mp/mp_rankIconTable.csv";
|
|
}
|
|
|
|
initScoreInfo();
|
|
|
|
level.maxRank = int(tableLookup( level.ranktable_name, 0, "maxrank", 1 ));
|
|
level.maxRankStarterPack = int(tableLookup( level.ranktable_name, 0, "maxrankstarterpack", 1 ));
|
|
level.maxPrestige = int(tableLookup( level.rankicontable_name, 0, "maxprestige", 1 ));
|
|
|
|
rankId = 0;
|
|
rankName = tableLookup( level.ranktable_name, 0, rankId, 1 );
|
|
assert( isdefined( rankName ) && rankName != "" );
|
|
|
|
while ( isdefined( rankName ) && rankName != "" )
|
|
{
|
|
level.rankTable[rankId][1] = tableLookup( level.ranktable_name, 0, rankId, 1 );
|
|
level.rankTable[rankId][2] = tableLookup( level.ranktable_name, 0, rankId, 2 );
|
|
level.rankTable[rankId][3] = tableLookup( level.ranktable_name, 0, rankId, 3 );
|
|
level.rankTable[rankId][7] = tableLookup( level.ranktable_name, 0, rankId, 7 );
|
|
level.rankTable[rankId][14] = tableLookup( level.ranktable_name, 0, rankId, 14 );
|
|
|
|
if( SessionModeIsCampaignGame() )
|
|
{ //cp has an extra column that awards extra tokens per rank
|
|
level.rankTable[rankId][18] = tablelookup( level.ranktable_name, 0, rankId, 18 );
|
|
}
|
|
rankId++;
|
|
rankName = tableLookup( level.ranktable_name, 0, rankId, 1 );
|
|
}
|
|
|
|
callback::on_connect( &on_player_connect );
|
|
}
|
|
|
|
|
|
function initScoreInfo()
|
|
{
|
|
scoreInfoTableID = scoreevents::getScoreEventTableID();
|
|
|
|
assert( isdefined( scoreInfoTableID ) );
|
|
if ( !isdefined( scoreInfoTableID ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
scoreColumn = scoreevents::getScoreEventColumn( level.gameType );
|
|
xpColumn = scoreevents::getXPEventColumn( level.gameType );
|
|
|
|
assert( scoreColumn >= 0 );
|
|
if ( scoreColumn < 0 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
assert( xpColumn >= 0 );
|
|
if ( xpColumn < 0 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
for( row = 1; row < 512; row++ )
|
|
{
|
|
type = tableLookupColumnForRow( scoreInfoTableID, row, 0 );
|
|
if ( type != "" )
|
|
{
|
|
labelString = tableLookupColumnForRow( scoreInfoTableID, row, 1 );
|
|
label = undefined;
|
|
if ( labelString != "" )
|
|
{
|
|
label = tableLookupIString( scoreInfoTableID, 0, type, 1 );
|
|
}
|
|
|
|
teamScoreString = tableLookupColumnForRow( scoreInfoTableID, row, 4 );
|
|
teamscore_material = undefined;
|
|
if ( teamScorestring != "" )
|
|
{
|
|
teamscore_material = tableLookupIString( scoreInfoTableID, 0, type, 4 );
|
|
}
|
|
|
|
scoreValue = int( tableLookupColumnForRow( scoreInfoTableID, row, scoreColumn ) );
|
|
xpValue = int( tableLookupColumnForRow( scoreInfoTableID, row, xpColumn ) );
|
|
registerScoreInfo( type, scoreValue, xpValue, label, teamscore_material );
|
|
|
|
if ( !isdefined( game["ScoreInfoInitialized"] ) )
|
|
{
|
|
xpValue = float( tableLookupColumnForRow( scoreInfoTableID, row, xpColumn ) );
|
|
|
|
setDDLStat = tableLookupColumnForRow( scoreInfoTableID, row, 8 );
|
|
addPlayerStat = false;
|
|
if ( setDDLStat == "TRUE" )
|
|
{
|
|
addPlayerStat = true;
|
|
}
|
|
isMedal = false;
|
|
iString = tableLookupIString( scoreInfoTableID, 0, type, 2 );
|
|
if ( isdefined( iString ) && iString != &"" )
|
|
{
|
|
isMedal = true;
|
|
}
|
|
|
|
demoBookmarkPriority = int( tableLookupColumnForRow( scoreInfoTableID, row, 9 ) );
|
|
if ( !isdefined( demoBookmarkPriority ) )
|
|
{
|
|
demoBookmarkPriority = 0;
|
|
}
|
|
|
|
RegisterXP( type, xpValue, addPlayerStat, isMedal, demoBookmarkPriority, row );
|
|
}
|
|
|
|
allowKillstreakWeapons = tableLookupColumnForRow( scoreInfoTableID, row, 5 );
|
|
if ( allowKillstreakWeapons == "TRUE" )
|
|
{
|
|
level.scoreInfo[ type ][ "allowKillstreakWeapons" ] = true;
|
|
}
|
|
|
|
allowHero = tableLookupColumnForRow( scoreInfoTableID, row, 7 );
|
|
if ( allowHero == "TRUE" )
|
|
{
|
|
level.scoreInfo[ type ][ "allow_hero" ] = true;
|
|
}
|
|
|
|
combatEfficiencyEvent = tableLookupColumnForRow( scoreInfoTableID, row, 6 );
|
|
if( IsDefined( combatEfficiencyEvent ) && combatEfficiencyEvent != "" )
|
|
{
|
|
level.scoreInfo[ type ][ "combat_efficiency_event" ] = combatEfficiencyEvent;
|
|
}
|
|
}
|
|
}
|
|
|
|
game["ScoreInfoInitialized"] = true;
|
|
}
|
|
|
|
|
|
function getRankXPCapped( inRankXp )
|
|
{
|
|
if ( ( isdefined( level.rankXpCap ) ) && level.rankXpCap && ( level.rankXpCap <= inRankXp ) )
|
|
{
|
|
return level.rankXpCap;
|
|
}
|
|
|
|
return inRankXp;
|
|
}
|
|
|
|
function getCodPointsCapped( inCodPoints )
|
|
{
|
|
if ( ( isdefined( level.codPointsCap ) ) && level.codPointsCap && ( level.codPointsCap <= inCodPoints ) )
|
|
{
|
|
return level.codPointsCap;
|
|
}
|
|
|
|
return inCodPoints;
|
|
}
|
|
|
|
function registerScoreInfo( type, value, xp, label, teamscore_material )
|
|
{
|
|
overrideDvar = "scr_" + level.gameType + "_score_" + type;
|
|
if ( GetDvarString( overrideDvar ) != "" )
|
|
{
|
|
value = getDvarInt( overrideDvar );
|
|
}
|
|
|
|
if( type == "kill" )
|
|
{
|
|
multiplier = GetGametypeSetting( "killEventScoreMultiplier" );
|
|
level.scoreInfo[type]["value"] = value;
|
|
if ( multiplier > 0 )
|
|
{
|
|
level.scoreInfo[type]["value"] = int((multiplier) * value);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
level.scoreInfo[type]["value"] = value;
|
|
}
|
|
|
|
level.scoreInfo[type]["xp"] = xp;
|
|
|
|
if ( isdefined( label ) )
|
|
{
|
|
level.scoreInfo[type]["label"] = label;
|
|
}
|
|
|
|
if ( isdefined( teamscore_material ) )
|
|
{
|
|
level.scoreInfo[type]["team_icon"] = teamscore_material;
|
|
}
|
|
}
|
|
|
|
function getScoreInfoValue( type )
|
|
{
|
|
if ( isdefined( level.scoreInfo[type] ) )
|
|
{
|
|
n_score = level.scoreInfo[type]["value"];
|
|
if ( isdefined( level.scoreModifierCallback ) && isdefined( n_score ) )
|
|
{
|
|
n_score = [[level.scoreModifierCallback]](type, n_score);
|
|
}
|
|
|
|
return n_score;
|
|
}
|
|
}
|
|
|
|
function getScoreInfoXP( type )
|
|
{
|
|
if ( isdefined( level.scoreInfo[type] ) )
|
|
{
|
|
n_xp = level.scoreInfo[type]["xp"];
|
|
if ( isdefined( level.xpModifierCallback ) && isdefined( n_xp ) )
|
|
{
|
|
n_xp = [[level.xpModifierCallback]]( type, n_xp );
|
|
}
|
|
|
|
return n_xp;
|
|
}
|
|
}
|
|
|
|
function shouldSkipMomentumDisplay( type )
|
|
{
|
|
if( ( isdefined( level.disableMomentum ) && level.disableMomentum ) )
|
|
return true;
|
|
|
|
// If teamscore UI has been overridden, and this has a teamscore icon, don't display it in the momentum indicator.
|
|
//
|
|
if (isdefined(level.teamScoreUICallback) && isdefined( level.scoreInfo[type]["team_icon"] ))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function getScoreInfoLabel( type )
|
|
{
|
|
return ( level.scoreInfo[type]["label"] );
|
|
}
|
|
|
|
function getCombatEfficiencyEvent( type )
|
|
{
|
|
return ( level.scoreInfo[type]["combat_efficiency_event"] );
|
|
}
|
|
|
|
function doesScoreInfoCountTowardRampage( type )
|
|
{
|
|
return isdefined( level.scoreInfo[type]["rampage"] ) && level.scoreInfo[type]["rampage"];
|
|
}
|
|
|
|
function getRankInfoMinXP( rankId )
|
|
{
|
|
return int(level.rankTable[rankId][2]);
|
|
}
|
|
|
|
function getRankInfoXPAmt( rankId )
|
|
{
|
|
return int(level.rankTable[rankId][3]);
|
|
}
|
|
|
|
function getRankInfoMaxXp( rankId )
|
|
{
|
|
return int(level.rankTable[rankId][7]);
|
|
}
|
|
|
|
function getRankInfoFull( rankId )
|
|
{
|
|
return tableLookupIString( level.ranktable_name, 0, rankId, 16 );
|
|
}
|
|
|
|
function getRankInfoIcon( rankId, prestigeId )
|
|
{
|
|
return tableLookup( level.rankicontable_name, 0, rankId, prestigeId+1 );
|
|
}
|
|
|
|
function getRankInfoLevel( rankId )
|
|
{
|
|
return int( tableLookup( level.ranktable_name, 0, rankId, 13 ) );
|
|
}
|
|
|
|
function getRankInfoCodPointsEarned( rankId )
|
|
{
|
|
return int( tableLookup( level.ranktable_name, 0, rankId, 17 ) );
|
|
}
|
|
|
|
function shouldKickByRank()
|
|
{
|
|
if ( self IsHost() )
|
|
{
|
|
// don't try to kick the host
|
|
return false;
|
|
}
|
|
|
|
if (level.rankCap > 0 && self.pers["rank"] > level.rankCap)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if ( ( level.rankCap > 0 ) && ( level.minPrestige == 0 ) && ( self.pers["plevel"] > 0 ) )
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if ( level.minPrestige > self.pers["plevel"] )
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function getCodPointsStat()
|
|
{
|
|
codPoints = self GetDStat( "playerstatslist", "CODPOINTS", "StatValue" );
|
|
codPointsCapped = getCodPointsCapped( codPoints );
|
|
|
|
if ( codPoints > codPointsCapped )
|
|
{
|
|
self setCodPointsStat( codPointsCapped );
|
|
}
|
|
|
|
return codPointsCapped;
|
|
}
|
|
|
|
function setCodPointsStat( codPoints )
|
|
{
|
|
self SetDStat( "PlayerStatsList", "CODPOINTS", "StatValue", getCodPointsCapped( codPoints ) );
|
|
}
|
|
|
|
function getRankXpStat()
|
|
{
|
|
rankXp = self GetDStat( "playerstatslist", "RANKXP", "StatValue" );
|
|
rankXpCapped = getRankXPCapped( rankXp );
|
|
|
|
if ( rankXp > rankXpCapped )
|
|
{
|
|
self SetDStat( "playerstatslist", "RANKXP", "StatValue", rankXpCapped );
|
|
}
|
|
|
|
return rankXpCapped;
|
|
}
|
|
|
|
function getArenaPointsStat()
|
|
{
|
|
arenaSlot = ArenaGetSlot();
|
|
arenaPoints = self GetDStat( "arenaStats", arenaSlot, "points" );
|
|
|
|
//Increment arena points by 1, because we immediatly deduct a point from the player to prevent
|
|
//players leaving early without penalty.
|
|
return arenaPoints + 1;
|
|
}
|
|
|
|
function on_player_connect()
|
|
{
|
|
self.pers["rankxp"] = self getRankXpStat();
|
|
self.pers["codpoints"] = self getCodPointsStat();
|
|
self.pers["currencyspent"] = self GetDStat( "playerstatslist", "currencyspent", "StatValue" );
|
|
rankId = self getRankForXp( self getRankXP() );
|
|
self.pers["rank"] = rankId;
|
|
self.pers["plevel"] = self GetDStat( "playerstatslist", "PLEVEL", "StatValue" );
|
|
|
|
if ( self shouldKickByRank() )
|
|
{
|
|
kick( self getEntityNumber() );
|
|
return;
|
|
}
|
|
|
|
if(!isdefined(self.pers["participation"]))self.pers["participation"]=0;
|
|
|
|
self.rankUpdateTotal = 0;
|
|
|
|
// attempt to move logic out of menus as much as possible
|
|
self.cur_rankNum = rankId;
|
|
assert( isdefined(self.cur_rankNum), "rank: "+ rankId + " does not have an index, check " + level.ranktable_name );
|
|
|
|
prestige = self GetDStat( "playerstatslist", "plevel", "StatValue" );
|
|
self setRank( rankId, prestige );
|
|
self.pers["prestige"] = prestige;
|
|
|
|
if ( ( SessionModeIsMultiplayerGame() && GameModeIsUsingStats() ) || ( SessionModeIsZombiesGame() && SessionModeIsOnlineGame() ) )
|
|
{
|
|
paragonRank = self GetDStat( "playerstatslist", "paragon_rank", "StatValue" );
|
|
self setParagonRank( paragonRank );
|
|
self.pers["paragonrank"] = paragonRank;
|
|
|
|
paragonIconId = self GetDStat( "playerstatslist", "paragon_icon_id", "StatValue" );
|
|
self setParagonIconId( paragonIconId );
|
|
self.pers["paragoniconid"] = paragonIconId;
|
|
}
|
|
|
|
if ( !isdefined( self.pers["summary"] ) )
|
|
{
|
|
self.pers["summary"] = [];
|
|
self.pers["summary"]["xp"] = 0;
|
|
self.pers["summary"]["score"] = 0;
|
|
self.pers["summary"]["challenge"] = 0;
|
|
self.pers["summary"]["match"] = 0;
|
|
self.pers["summary"]["misc"] = 0;
|
|
self.pers["summary"]["codpoints"] = 0;
|
|
}
|
|
|
|
if( GameModeIsMode( 6 ) && !( self util::is_bot() ) )
|
|
{
|
|
arenaPoints = self getArenaPointsStat();
|
|
arenaPoints = int( min( arenaPoints, 100 ) ); // JATODO: 100 = max arena points, temp until TU4
|
|
|
|
self.pers["arenapoints"] = arenaPoints;
|
|
self setArenaPoints( arenaPoints );
|
|
}
|
|
|
|
if ( level.rankedMatch )
|
|
{
|
|
self SetDStat( "playerstatslist", "rank", "StatValue", rankId );
|
|
self SetDStat( "playerstatslist", "minxp", "StatValue", getRankInfoMinXp( rankId ) );
|
|
self SetDStat( "playerstatslist", "maxxp", "StatValue", getRankInfoMaxXp( rankId ) );
|
|
self SetDStat( "playerstatslist", "lastxp", "StatValue", getRankXPCapped( self.pers["rankxp"] ) );
|
|
}
|
|
|
|
self.explosiveKills[0] = 0;
|
|
|
|
callback::on_spawned( &on_player_spawned );
|
|
callback::on_joined_team( &on_joined_team );
|
|
callback::on_joined_spectate( &on_joined_spectators );
|
|
}
|
|
|
|
function on_joined_team()
|
|
{
|
|
self endon("disconnect");
|
|
|
|
self thread removeRankHUD();
|
|
}
|
|
|
|
function on_joined_spectators()
|
|
{
|
|
self endon("disconnect");
|
|
|
|
self thread removeRankHUD();
|
|
}
|
|
|
|
function on_player_spawned()
|
|
{
|
|
self endon("disconnect");
|
|
|
|
/*if ( !isdefined( self.hud_momentumupdate ) )
|
|
{
|
|
self.hud_momentumupdate = NewScoreHudElem(self);
|
|
self.hud_momentumupdate.horzAlign = "center";
|
|
self.hud_momentumupdate.vertAlign = "middle";
|
|
self.hud_momentumupdate.alignX = "center";
|
|
self.hud_momentumupdate.alignY = "middle";
|
|
self.hud_momentumupdate.x = 0;
|
|
if( self IsSplitscreen() )
|
|
self.hud_momentumupdate.y = -72;
|
|
else
|
|
self.hud_momentumupdate.y = -117;
|
|
self.hud_momentumupdate.baseY = self.hud_momentumupdate.y;
|
|
self.hud_momentumupdate.font = "default";
|
|
self.hud_momentumupdate.fontscale = 1.5;
|
|
self.hud_momentumupdate.archived = false;
|
|
self.hud_momentumupdate.color = (1,1,0.5);
|
|
self.hud_momentumupdate.alpha = 0;
|
|
self.hud_momentumupdate.sort = 50;
|
|
}*/
|
|
|
|
if(!isdefined(self.hud_rankscroreupdate))
|
|
{
|
|
self.hud_rankscroreupdate = NewScoreHudElem(self);
|
|
self.hud_rankscroreupdate.horzAlign = "center";
|
|
self.hud_rankscroreupdate.vertAlign = "middle";
|
|
self.hud_rankscroreupdate.alignX = "center";
|
|
self.hud_rankscroreupdate.alignY = "middle";
|
|
self.hud_rankscroreupdate.x = 0;
|
|
if( self IsSplitscreen() )
|
|
self.hud_rankscroreupdate.y = -15;
|
|
else
|
|
self.hud_rankscroreupdate.y = -60;
|
|
self.hud_rankscroreupdate.font = "default";
|
|
self.hud_rankscroreupdate.fontscale = 2.0;
|
|
self.hud_rankscroreupdate.archived = false;
|
|
self.hud_rankscroreupdate.color = (1,1,0.5);
|
|
self.hud_rankscroreupdate.alpha = 0;
|
|
self.hud_rankscroreupdate.sort = 50;
|
|
self.hud_rankscroreupdate hud::font_pulse_init();
|
|
}
|
|
|
|
/*if(!isdefined(self.hud_momentumreason))
|
|
{
|
|
self.hud_momentumreason = NewScoreHudElem(self);
|
|
self.hud_momentumreason.horzAlign = "center";
|
|
self.hud_momentumreason.vertAlign = "middle";
|
|
self.hud_momentumreason.alignX = "center";
|
|
self.hud_momentumreason.alignY = "middle";
|
|
self.hud_momentumreason.x = 0;
|
|
if( self IsSplitscreen() )
|
|
self.hud_momentumreason.y = -32;
|
|
else
|
|
self.hud_momentumreason.y = -77;
|
|
self.hud_momentumreason.font = "default";
|
|
self.hud_momentumreason.fontscale = 1.5;
|
|
self.hud_momentumreason.archived = false;
|
|
self.hud_momentumreason.color = (1,1,1);
|
|
self.hud_momentumreason.alpha = 0;
|
|
self.hud_momentumreason.sort = 50;
|
|
self.hud_momentumreason hud::font_pulse_init();
|
|
self.hud_momentumreason.maxFontScale = 6.3;
|
|
self.hud_momentumreason.outFrames = self.hud_momentumreason.inFrames + self.hud_momentumreason.outFrames;
|
|
self.hud_momentumreason.inFrames = 0;
|
|
}*/
|
|
}
|
|
|
|
function incCodPoints( amount )
|
|
{
|
|
if( !util::isRankEnabled() )
|
|
return;
|
|
|
|
if( !level.rankedMatch )
|
|
return;
|
|
|
|
newCodPoints = getCodPointsCapped( self.pers["codpoints"] + amount );
|
|
if ( newCodPoints > self.pers["codpoints"] )
|
|
{
|
|
self.pers["summary"]["codpoints"] += ( newCodPoints - self.pers["codpoints"] );
|
|
}
|
|
self.pers["codpoints"] = newCodPoints;
|
|
|
|
setCodPointsStat( int( newCodPoints ) );
|
|
}
|
|
|
|
function atLeastOnePlayerOnEachTeam( )
|
|
{
|
|
foreach( team in level.teams )
|
|
{
|
|
if ( !level.playerCount[team] )
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function giveRankXP( type, value, devAdd )
|
|
{
|
|
self endon("disconnect");
|
|
|
|
// TODO: will enable it after zombies ranking system is working
|
|
if( SessionModeIsZombiesGame() )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( level.teamBased && (!atLeastOnePlayerOnEachTeam()) && !isdefined( devAdd ) )
|
|
return;
|
|
else if ( !level.teamBased && ( util::totalPlayerCount() < 2) && !isdefined( devAdd ) )
|
|
return;
|
|
|
|
if( !util::isRankEnabled() )
|
|
return;
|
|
|
|
pixbeginevent("giveRankXP");
|
|
|
|
if ( !isdefined( value ) )
|
|
value = getScoreInfoValue( type );
|
|
|
|
// Blackbox
|
|
if( level.rankedMatch )
|
|
{
|
|
bbPrint( "mpplayerxp", "gametime %d, player %s, type %s, delta %d", getTime(), self.name, type, value );
|
|
}
|
|
|
|
// this switch statement should be inverted. I am pretty sure there are fewer
|
|
// things that we dont want to scale then there are that we do.
|
|
switch( type )
|
|
{
|
|
case "kill":
|
|
case "headshot":
|
|
case "assist":
|
|
case "assist_25":
|
|
case "assist_50":
|
|
case "assist_75":
|
|
case "helicopterassist":
|
|
case "helicopterassist_25":
|
|
case "helicopterassist_50":
|
|
case "helicopterassist_75":
|
|
case "helicopterkill":
|
|
case "rcbombdestroy":
|
|
case "spyplanekill":
|
|
case "spyplaneassist":
|
|
case "dogkill":
|
|
case "dogassist":
|
|
case "capture":
|
|
case "defend":
|
|
case "return":
|
|
case "pickup":
|
|
case "plant":
|
|
case "defuse":
|
|
case "destroyer":
|
|
case "assault":
|
|
case "assault_assist":
|
|
case "revive":
|
|
case "medal":
|
|
value = int( value * level.xpScale );
|
|
break;
|
|
default:
|
|
if ( level.xpScale == 0 )
|
|
value = 0;
|
|
break;
|
|
}
|
|
|
|
xpIncrease = self incRankXP( value );
|
|
|
|
if ( level.rankedMatch )
|
|
{
|
|
self updateRank();
|
|
}
|
|
|
|
// Set the XP stat after any unlocks, so that if the final stat set gets lost the unlocks won't be gone for good.
|
|
if ( value != 0 )
|
|
{
|
|
self syncXPStat();
|
|
}
|
|
|
|
if ( isdefined( self.enableText ) && self.enableText && !level.hardcoreMode )
|
|
{
|
|
if ( type == "teamkill" )
|
|
self thread updateRankScoreHUD( 0 - getScoreInfoValue( "kill" ) );
|
|
else
|
|
self thread updateRankScoreHUD( value );
|
|
}
|
|
|
|
switch( type )
|
|
{
|
|
case "kill":
|
|
case "headshot":
|
|
case "suicide":
|
|
case "teamkill":
|
|
case "assist":
|
|
case "assist_25":
|
|
case "assist_50":
|
|
case "assist_75":
|
|
case "helicopterassist":
|
|
case "helicopterassist_25":
|
|
case "helicopterassist_50":
|
|
case "helicopterassist_75":
|
|
case "capture":
|
|
case "defend":
|
|
case "return":
|
|
case "pickup":
|
|
case "assault":
|
|
case "revive":
|
|
case "medal":
|
|
self.pers["summary"]["score"] += value;
|
|
incCodPoints( round_this_number( value * level.codPointsXPScale ) );
|
|
break;
|
|
|
|
case "win":
|
|
case "loss":
|
|
case "tie":
|
|
self.pers["summary"]["match"] += value;
|
|
incCodPoints( round_this_number( value * level.codPointsMatchScale ) );
|
|
break;
|
|
|
|
case "challenge":
|
|
self.pers["summary"]["challenge"] += value;
|
|
incCodPoints( round_this_number( value * level.codPointsChallengeScale ) );
|
|
break;
|
|
|
|
default:
|
|
self.pers["summary"]["misc"] += value; //keeps track of ungrouped match xp reward
|
|
self.pers["summary"]["match"] += value;
|
|
incCodPoints( round_this_number( value * level.codPointsMatchScale ) );
|
|
break;
|
|
}
|
|
|
|
self.pers["summary"]["xp"] += xpIncrease;
|
|
|
|
pixendevent();
|
|
}
|
|
|
|
function round_this_number( value )
|
|
{
|
|
value = int( value + 0.5 );
|
|
return value;
|
|
}
|
|
|
|
function updateRank()
|
|
{
|
|
newRankId = self getRank();
|
|
if ( newRankId == self.pers["rank"] )
|
|
return false;
|
|
|
|
oldRank = self.pers["rank"];
|
|
rankId = self.pers["rank"];
|
|
self.pers["rank"] = newRankId;
|
|
|
|
// This function is a bit 'funny' - it decides to handle all of the unlocks for the current rank
|
|
// before handling all of the unlocks for any new ranks - it's probably as a safety to handle the
|
|
// case where unlocks have not happened for the current rank (which should only be the case for rank 0)
|
|
// This will hopefully go away once the new ranking system is in place fully
|
|
while ( rankId <= newRankId )
|
|
{
|
|
self SetDStat( "playerstatslist", "rank", "StatValue", rankId );
|
|
self SetDStat( "playerstatslist", "minxp", "StatValue", int(level.rankTable[rankId][2]) );
|
|
self SetDStat( "playerstatslist", "maxxp", "StatValue", int(level.rankTable[rankId][7]) );
|
|
|
|
// tell lobby to popup promotion window instead
|
|
self.setPromotion = true;
|
|
if ( level.rankedMatch && level.gameEnded && !self IsSplitscreen() )
|
|
self setDStat( "AfterActionReportStats", "lobbyPopup", "promotion" );
|
|
|
|
// Don't add CoD Points for the old rank - only add when actually ranking up
|
|
if ( rankId != oldRank )
|
|
{
|
|
codPointsEarnedForRank = getRankInfoCodPointsEarned( rankId );
|
|
|
|
incCodPoints( codPointsEarnedForRank );
|
|
|
|
|
|
if ( !isdefined( self.pers["rankcp"] ) )
|
|
{
|
|
self.pers["rankcp"] = 0;
|
|
}
|
|
|
|
self.pers["rankcp"] += codPointsEarnedForRank;
|
|
}
|
|
|
|
rankId++;
|
|
}
|
|
/#print( "promoted from " + oldRank + " to " + newRankId + " timeplayed: " + self GetDStat( "playerstatslist", "time_played_total", "StatValue" ) ); #/
|
|
|
|
self setRank( newRankId );
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
function CodeCallback_RankUp( rank, prestige, unlockTokensAdded )
|
|
{
|
|
//No campaign notifications, handled in AAR
|
|
if( SessionModeIsCampaignGame() )
|
|
{
|
|
// If extra tokens should be awarded at this player level, award them immediately.
|
|
n_extra_tokens = level.rankTable[rank][18];
|
|
|
|
if (isdefined(n_extra_tokens) && n_extra_tokens != "" )
|
|
{
|
|
self GiveUnlockToken(int(n_extra_tokens));
|
|
}
|
|
|
|
UploadStats( self );
|
|
return;
|
|
}
|
|
|
|
if( SessionModeIsMultiplayerGame() )
|
|
{
|
|
if ( rank > 53 )
|
|
{
|
|
self GiveAchievement( "MP_REACH_ARENA" );// Reach Commander (Level 55) in Multiplayer by playing in Public Match and/or Arena.
|
|
}
|
|
if ( rank > 8 )
|
|
{
|
|
self GiveAchievement( "MP_REACH_SERGEANT" );// Welcome to the Club Reach Sergeant (Level 10) in Multiplayer by playing in Public Match and/or Arena.
|
|
}
|
|
}
|
|
|
|
self LUINotifyEvent( &"rank_up", 3, rank, prestige, unlockTokensAdded );
|
|
self LUINotifyEventToSpectators( &"rank_up", 3, rank, prestige, unlockTokensAdded );
|
|
|
|
if ( isdefined( level.playPromotionReaction ) )
|
|
{
|
|
self thread [[level.playPromotionReaction]]();
|
|
}
|
|
}
|
|
|
|
function getItemIndex( refString )
|
|
{
|
|
statsTableName = util::getStatsTableName();
|
|
itemIndex = int( tableLookup( statsTableName, 4, refString, 0 ) );
|
|
assert( itemIndex > 0, "statsTable refstring " + refString + " has invalid index: " + itemIndex );
|
|
|
|
return itemIndex;
|
|
}
|
|
|
|
function endGameUpdate()
|
|
{
|
|
player = self;
|
|
}
|
|
|
|
function updateRankScoreHUD( amount )
|
|
{
|
|
self endon( "disconnect" );
|
|
self endon( "joined_team" );
|
|
self endon( "joined_spectators" );
|
|
|
|
if ( isdefined( level.usingMomentum ) && level.usingMomentum )
|
|
{
|
|
return; // Disabled because this is now handled in updateMomentumHUD function
|
|
}
|
|
|
|
if ( amount == 0 )
|
|
return;
|
|
|
|
self notify( "update_score" );
|
|
self endon( "update_score" );
|
|
|
|
self.rankUpdateTotal += amount;
|
|
|
|
{wait(.05);};
|
|
|
|
if( isdefined( self.hud_rankscroreupdate ) )
|
|
{
|
|
if ( self.rankUpdateTotal < 0 )
|
|
{
|
|
self.hud_rankscroreupdate.label = &"";
|
|
self.hud_rankscroreupdate.color = (0.73,0.19,0.19);
|
|
}
|
|
else
|
|
{
|
|
self.hud_rankscroreupdate.label = &"MP_PLUS";
|
|
self.hud_rankscroreupdate.color = (1,1,0.5);
|
|
}
|
|
|
|
self.hud_rankscroreupdate setValue(self.rankUpdateTotal);
|
|
|
|
self.hud_rankscroreupdate.alpha = 0.85;
|
|
self.hud_rankscroreupdate thread hud::font_pulse( self );
|
|
|
|
wait 1;
|
|
self.hud_rankscroreupdate fadeOverTime( 0.75 );
|
|
self.hud_rankscroreupdate.alpha = 0;
|
|
|
|
self.rankUpdateTotal = 0;
|
|
}
|
|
}
|
|
|
|
function updateMomentumHUD( amount, reason, reasonValue )
|
|
{
|
|
self endon( "disconnect" );
|
|
self endon( "joined_team" );
|
|
self endon( "joined_spectators" );
|
|
|
|
if ( amount == 0 )
|
|
return;
|
|
|
|
self notify( "update_score" );
|
|
self endon( "update_score" );
|
|
|
|
self.rankUpdateTotal += amount;
|
|
|
|
if( isdefined( self.hud_rankscroreupdate ) )
|
|
{
|
|
if ( self.rankUpdateTotal < 0 )
|
|
{
|
|
self.hud_rankscroreupdate.label = &"";
|
|
self.hud_rankscroreupdate.color = (0.73,0.19,0.19);
|
|
}
|
|
else
|
|
{
|
|
self.hud_rankscroreupdate.label = &"MP_PLUS";
|
|
self.hud_rankscroreupdate.color = (1,1,0.5);
|
|
}
|
|
|
|
self.hud_rankscroreupdate setValue( self.rankUpdateTotal );
|
|
|
|
self.hud_rankscroreupdate.alpha = 0.85;
|
|
self.hud_rankscroreupdate thread hud::font_pulse( self );
|
|
|
|
/*if ( isdefined( self.hud_momentumupdate ) && ( amount != self.rankUpdateTotal ) )
|
|
{
|
|
self.hud_momentumupdate.label = &"MP_PLUS";
|
|
self.hud_momentumupdate setValue( amount );
|
|
self.hud_momentumupdate.alpha = 1;
|
|
self.hud_momentumupdate.y = self.hud_momentumupdate.baseY;
|
|
self.hud_momentumupdate FadeOverTime( 0.5 );
|
|
self.hud_momentumupdate MoveOverTime( 0.5 );
|
|
self.hud_momentumupdate.y -= 20;
|
|
self.hud_momentumupdate.alpha = 0;
|
|
}*/
|
|
|
|
if ( isdefined( self.hud_momentumreason ) )
|
|
{
|
|
if ( isdefined( reason ) )
|
|
{
|
|
if ( isdefined( reasonValue ) )
|
|
{
|
|
self.hud_momentumreason.label = reason;
|
|
self.hud_momentumreason setValue( reasonValue );
|
|
}
|
|
else
|
|
{
|
|
/*self.hud_momentumreason.label = &"";
|
|
self.hud_momentumreason SetText( reason );*/
|
|
self.hud_momentumreason.label = reason;
|
|
self.hud_momentumreason setValue( amount );
|
|
}
|
|
self.hud_momentumreason.alpha = 0.85;
|
|
self.hud_momentumreason thread hud::font_pulse( self );
|
|
}
|
|
else
|
|
{
|
|
self.hud_momentumreason fadeOverTime( 0.01 );
|
|
self.hud_momentumreason.alpha = 0;
|
|
}
|
|
}
|
|
|
|
wait 1;
|
|
self.hud_rankscroreupdate fadeOverTime( 0.75 );
|
|
self.hud_rankscroreupdate.alpha = 0;
|
|
|
|
if ( isdefined( self.hud_momentumreason ) && isdefined( reason ) )
|
|
{
|
|
self.hud_momentumreason fadeOverTime( 0.75 );
|
|
self.hud_momentumreason.alpha = 0;
|
|
}
|
|
|
|
wait 0.75;
|
|
|
|
self.rankUpdateTotal = 0;
|
|
}
|
|
}
|
|
|
|
function removeRankHUD()
|
|
{
|
|
if(isdefined(self.hud_rankscroreupdate))
|
|
self.hud_rankscroreupdate.alpha = 0;
|
|
|
|
if ( isdefined( self.hud_momentumreason ) )
|
|
{
|
|
self.hud_momentumreason.alpha = 0;
|
|
}
|
|
}
|
|
|
|
function getRank()
|
|
{
|
|
rankXp = getRankXPCapped( self.pers["rankxp"] );
|
|
rankId = self.pers["rank"];
|
|
|
|
if ( rankXp < (getRankInfoMinXP( rankId ) + getRankInfoXPAmt( rankId )) )
|
|
return rankId;
|
|
else
|
|
return self getRankForXp( rankXp );
|
|
}
|
|
|
|
function getRankForXp( xpVal )
|
|
{
|
|
rankId = 0;
|
|
rankName = level.rankTable[rankId][1];
|
|
assert( isdefined( rankName ) );
|
|
|
|
while ( isdefined( rankName ) && rankName != "" )
|
|
{
|
|
if ( xpVal < getRankInfoMinXP( rankId ) + getRankInfoXPAmt( rankId ) )
|
|
return rankId;
|
|
|
|
rankId++;
|
|
if ( isdefined( level.rankTable[rankId] ) )
|
|
rankName = level.rankTable[rankId][1];
|
|
else
|
|
rankName = undefined;
|
|
}
|
|
|
|
rankId--;
|
|
return rankId;
|
|
}
|
|
|
|
function getSPM()
|
|
{
|
|
rankLevel = self getRank() + 1;
|
|
return (3 + (rankLevel * 0.5))*10;
|
|
}
|
|
|
|
function getRankXP()
|
|
{
|
|
return getRankXPCapped( self.pers["rankxp"] );
|
|
}
|
|
|
|
function incRankXP( amount )
|
|
{
|
|
if ( !level.rankedMatch )
|
|
return 0;
|
|
|
|
xp = self getRankXP();
|
|
newXp = getRankXPCapped( xp + amount );
|
|
|
|
if ( self.pers["rank"] == level.maxRank && newXp >= getRankInfoMaxXP( level.maxRank ) )
|
|
newXp = getRankInfoMaxXP( level.maxRank );
|
|
|
|
if ( self IsStarterPack() && self.pers["rank"] >= level.maxRankStarterPack && newXp >= getRankInfoMinXP( level.maxRankStarterPack ) )
|
|
newXp = getRankInfoMinXP( level.maxRankStarterPack );
|
|
|
|
xpIncrease = getRankXPCapped( newXp ) - self.pers["rankxp"];
|
|
|
|
if ( xpIncrease < 0 )
|
|
{
|
|
xpIncrease = 0;
|
|
}
|
|
|
|
self.pers["rankxp"] = getRankXPCapped( newXp );
|
|
|
|
return xpIncrease;
|
|
}
|
|
|
|
function syncXPStat()
|
|
{
|
|
xp = getRankXPCapped( self getRankXP() );
|
|
|
|
cp = getCodPointsCapped( int( self.pers["codpoints"] ) );
|
|
|
|
self SetDStat( "playerstatslist", "rankxp", "StatValue", xp );
|
|
|
|
self SetDStat( "playerstatslist", "codpoints", "StatValue", cp );
|
|
}
|