1283 lines
32 KiB
Text
1283 lines
32 KiB
Text
const DEFAULT_SILENT_MODE = 0
|
|
const PROMO_WIN = 1
|
|
const PROMO_CONT = 0
|
|
const PROMO_LOSE = -1
|
|
const RATING_GOALS = 5
|
|
const SECRET_SOCIETY_ICON_ALPHA = 255
|
|
|
|
function main()
|
|
{
|
|
if ( IsUI() )
|
|
PrecacheRankIcons()
|
|
|
|
Globalize( GetContributionMapping )
|
|
Globalize( GetContributionScoreNames )
|
|
Globalize( GetContributionXpTypes )
|
|
Globalize( GetContributionContTypes )
|
|
Globalize( GetRankInviteMode )
|
|
|
|
Globalize( ContributionLossForPilotDeath )
|
|
Globalize( GetContributionMappingForGamemode )
|
|
Globalize( PlaylistSupportsRankedPlay )
|
|
Globalize( GameModeSupportsRankedPlay )
|
|
Globalize( GetPlayerRank )
|
|
Globalize( GetPlayerOldRank )
|
|
Globalize( GetPlayerDivision )
|
|
Globalize( GetPlayerTier )
|
|
Globalize( GetNextRank )
|
|
Globalize( GetPreviousRank )
|
|
Globalize( GetPlayerGemScore )
|
|
Globalize( GetPlayerGemState )
|
|
Globalize( GetPlayerTotalCompletedGems )
|
|
Globalize( GetPreviousPlayerTotalCompletedGems )
|
|
Globalize( GetPlayerSponsorshipsRemaining )
|
|
Globalize( PlayerQualifiedForRanked )
|
|
Globalize( PlayerAcceptedRankInvite )
|
|
Globalize( GetRankImage )
|
|
Globalize( GetPlayerTimeTillNextGemDecay )
|
|
Globalize( GetRankedDecayRate )
|
|
Globalize( GetPlayerGemDecayTime )
|
|
Globalize( GetRankedSeason )
|
|
Globalize( GetCurrentSeasonStartTime )
|
|
Globalize( GetCurrentSeasonEndTime )
|
|
Globalize( MatchSupportsRankedPlay )
|
|
Globalize( TooLateForRanked )
|
|
Globalize( RankedWinLossOnly )
|
|
Globalize( RankedWinLossPercent )
|
|
Globalize( RankedAlwaysLoseGem )
|
|
// Each supported game mode needs to be added here, and needs to be added to the next few functions as well
|
|
level.rankedInitFuncs <- {}
|
|
level.rankedInitFuncs[ ATTRITION ] <- null
|
|
level.rankedInitFuncs[ LAST_TITAN_STANDING ] <- null
|
|
level.rankedInitFuncs[ TEAM_DEATHMATCH ] <- null
|
|
level.rankedInitFuncs[ PILOT_SKIRMISH ] <- null
|
|
level.rankedInitFuncs[ CAPTURE_POINT ] <- null
|
|
level.rankedInitFuncs[ CAPTURE_THE_FLAG ] <- null
|
|
level.rankedInitFuncs[ MARKED_FOR_DEATH ] <- null
|
|
level.rankedInitFuncs[ MARKED_FOR_DEATH_PRO ] <- null
|
|
|
|
IncludeFile( "_ranked_gems" )
|
|
|
|
RegisterSignal( "NewPerformanceUpdate" )
|
|
|
|
if ( IsUI() || IsClient() )
|
|
{
|
|
level.currentPerformance <- 0
|
|
}
|
|
|
|
if ( IsUI() )
|
|
{
|
|
RegisterSignal( "CompletedProgressTally" )
|
|
RegisterSignal( "CapturedGem" )
|
|
GEM_DIST <- 0.30
|
|
}
|
|
else
|
|
{
|
|
GEM_DIST <- 0.32
|
|
level.rankedPlayEnabled <- MatchSupportsRankedPlay()
|
|
if ( level.rankedPlayEnabled )
|
|
file.rankedMapping <- InitContributionMappingForGameMode( GAMETYPE )
|
|
|
|
if ( IsServer() )
|
|
{
|
|
IncludeFile( "mp/_ranked" )
|
|
// IncludeFile( "mp/_ranked_gamemodes" )
|
|
|
|
}
|
|
|
|
else
|
|
{
|
|
Globalize( GetContributionHint )
|
|
if ( level.rankedPlayEnabled )
|
|
{
|
|
IncludeFile( "client/cl_ranked" )
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( IsUI() )
|
|
{
|
|
function PrecacheRankIcons()
|
|
{
|
|
for ( local i = 0; i <= 24; i++ )
|
|
PrecacheHUDMaterial( GetRankImage( i ) )
|
|
|
|
PrecacheHUDMaterial( "../ui/menu/rank_menus/ranked_game_icon_next" )
|
|
PrecacheHUDMaterial( "../ui/menu/rank_menus/ranked_game_icon_damaged" )
|
|
PrecacheHUDMaterial( "../ui/menu/rank_menus/ranked_game_icon_success" )
|
|
PrecacheHUDMaterial( "../ui/menu/rank_menus/ranked_game_icon_lost" )
|
|
}
|
|
Globalize( PrecacheRankIcons )
|
|
|
|
function GameModeAssaultDefenseDescription( gameMode )
|
|
{
|
|
// this returns the string for gamemodes that care about player "score", ie assault/defense points
|
|
switch ( gameMode )
|
|
{
|
|
default:
|
|
Assert( 0, "No descriptive string for gamemode " + gamemode )
|
|
}
|
|
}
|
|
Globalize( GameModeAssaultDefenseDescription )
|
|
|
|
function GameModeAssaultDescription( gameMode )
|
|
{
|
|
// this returns the string for gamemodes that care about player "score", ie assault/defense points
|
|
switch ( gameMode )
|
|
{
|
|
case ATTRITION:
|
|
return "#RANKED_POINT_DESC_ATTR_POINTS"
|
|
case CAPTURE_POINT:
|
|
return "#RANKED_POINT_DESC_ASSAULT_POINTS"
|
|
case COOPERATIVE:
|
|
return "#RANKED_POINT_DESC_COOP_POINTS"
|
|
default:
|
|
Assert( 0, "No descriptive string for gamemode " + gamemode )
|
|
}
|
|
}
|
|
Globalize( GameModeAssaultDescription )
|
|
|
|
function GameModeDefenseDescription( gameMode )
|
|
{
|
|
// this returns the string for gamemodes that care about player "score", ie assault/defense points
|
|
switch ( gameMode )
|
|
{
|
|
case CAPTURE_POINT:
|
|
return "#RANKED_POINT_DESC_DEFENSE_POINTS"
|
|
default:
|
|
Assert( 0, "No descriptive string for gamemode " + gamemode )
|
|
}
|
|
}
|
|
Globalize( GameModeDefenseDescription )
|
|
|
|
}
|
|
|
|
function GetContributionMappingForGamemode( gamemode )
|
|
{
|
|
return InitContributionMappingForGameMode( gamemode )
|
|
}
|
|
|
|
function GetContributionMapping()
|
|
{
|
|
return file.rankedMapping.mapping
|
|
}
|
|
|
|
function GetContributionScoreNames()
|
|
{
|
|
return file.rankedMapping.scoreNames
|
|
}
|
|
|
|
function GetContributionXpTypes()
|
|
{
|
|
return file.rankedMapping.xpTypes
|
|
}
|
|
|
|
function GetContributionContTypes()
|
|
{
|
|
return file.rankedMapping.contTypes
|
|
}
|
|
|
|
if ( IsClient() )
|
|
{
|
|
// only client has this function
|
|
function GetContributionHint()
|
|
{
|
|
return file.rankedMapping.introHint
|
|
}
|
|
}
|
|
|
|
function InitContributionMappingForGameMode( gamemode )
|
|
{
|
|
local table = CreateContributionMappingForGamemode( gamemode )
|
|
if ( !( "mapping" in table ) )
|
|
table.mapping <- []
|
|
if ( !( "xpTypes" in table ) )
|
|
table.xpTypes <- {}
|
|
if ( !( "scoreNames" in table ) )
|
|
table.scoreNames <- {}
|
|
|
|
table.contTypes <- {}
|
|
foreach ( contType in table.mapping )
|
|
{
|
|
table.contTypes[ contType ] <- true
|
|
}
|
|
|
|
Assert( ScoreEventsAreInMapping( table ) )
|
|
|
|
if ( IsClient() )
|
|
table.introHint <- AssignHintMessageForMapping( table )
|
|
|
|
|
|
// print the table for debugging
|
|
|
|
|
|
return table
|
|
}
|
|
|
|
function ScoreEventsAreInMapping( table )
|
|
{
|
|
local hasMapping = {}
|
|
foreach ( contType in table.mapping )
|
|
{
|
|
hasMapping[ contType ] <- true
|
|
}
|
|
|
|
foreach ( scoreEvent, contType in table.scoreNames )
|
|
{
|
|
Assert( contType in hasMapping, "Missing contType " + contType + " for " + scoreEvent )
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
function AssignHintMessageForMapping( table )
|
|
{
|
|
if ( "AttritionPoints" in table.scoreNames )
|
|
return "#RANKED_ANNOUNCE_ATTRITION"
|
|
|
|
local hasMapping = {}
|
|
foreach ( contType in table.mapping )
|
|
{
|
|
hasMapping[ contType ] <- true
|
|
}
|
|
|
|
if ( eRankedContributionType.ASSAULT in hasMapping && eRankedContributionType.DEFENSE in hasMapping )
|
|
return "#RANKED_ANNOUNCE_ASSAULT_DEFENSE"
|
|
|
|
if ( eRankedContributionType.DAMAGED_TITAN in hasMapping )
|
|
return "#RANKED_ANNOUNCE_TITAN_DAMAGE"
|
|
|
|
if ( XP_TYPE.PILOT_KILL in table.xpTypes && XP_TYPE.PILOT_ASSIST in table.xpTypes )
|
|
{
|
|
if ( table.scoreNames.len() == 0 )
|
|
return "#RANKED_ANNOUNCE_PILOT_KILLS_ASSISTS"
|
|
|
|
if ( "MarkedTargetKilled" in table.scoreNames )
|
|
return "#RANKED_ANNOUNCE_MFD"
|
|
|
|
if ( "FlagCapture" in table.scoreNames )
|
|
return "#RANKED_ANNOUNCE_CTF"
|
|
|
|
return "#RANKED_ANNOUNCE_GAMEMODE_AND_KILLS"
|
|
}
|
|
|
|
return "GAME MODE NEEDS MAPPING STRING!"
|
|
}
|
|
|
|
function RankedWinLossOnly( gamemode )
|
|
{
|
|
switch ( gamemode )
|
|
{
|
|
case CAPTURE_THE_FLAG:
|
|
if ( GetCurrentPlaylistVar( "ranked_ctf_winloss" ) == "on" )
|
|
return true
|
|
|
|
return false
|
|
|
|
case CAPTURE_POINT:
|
|
if ( GetCurrentPlaylistVar( "ranked_cp_winloss" ) == "on" )
|
|
return true
|
|
|
|
return false
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
function RankedWinLossPercent( gamemode )
|
|
{
|
|
if ( IsUI() && !IsFullyConnected() )
|
|
return 0.0
|
|
|
|
switch ( gamemode )
|
|
{
|
|
case CAPTURE_THE_FLAG:
|
|
return GetCurrentPlaylistVarFloat( "ranked_wlpct_ctf", 0.15 )
|
|
|
|
case CAPTURE_POINT:
|
|
return GetCurrentPlaylistVarFloat( "ranked_wlpct_cp", 0.15 )
|
|
|
|
case TEAM_DEATHMATCH:
|
|
case PILOT_SKIRMISH:
|
|
return GetCurrentPlaylistVarFloat( "ranked_wlpct_ps", 0.05 )
|
|
|
|
case ATTRITION:
|
|
return GetCurrentPlaylistVarFloat( "ranked_wlpct_at", 0.05 )
|
|
|
|
case LAST_TITAN_STANDING:
|
|
return GetCurrentPlaylistVarFloat( "ranked_wlpct_lts", 0.15 )
|
|
|
|
case MARKED_FOR_DEATH:
|
|
case MARKED_FOR_DEATH_PRO:
|
|
return GetCurrentPlaylistVarFloat( "ranked_wlpct_mfd", 0.10 )
|
|
|
|
default:
|
|
return GetCurrentPlaylistVarFloat( "ranked_wlpct_def", 0.10 )
|
|
}
|
|
|
|
return 0.0
|
|
}
|
|
|
|
function CreateContributionMappingForGamemode( gamemode )
|
|
{
|
|
if ( RankedWinLossOnly( gamemode ) )
|
|
return {}
|
|
|
|
switch ( gamemode )
|
|
{
|
|
case ATTRITION:
|
|
return {
|
|
mapping =
|
|
[
|
|
eRankedContributionType.ASSAULT // from GetAssaultScore()
|
|
eRankedContributionType.LOSS_PILOT_DEATH // manually credited in _ranked_gamemodes
|
|
]
|
|
|
|
scoreNames =
|
|
{
|
|
AttritionPoints = eRankedContributionType.ASSAULT
|
|
}
|
|
}
|
|
|
|
case LAST_TITAN_STANDING:
|
|
return {
|
|
mapping =
|
|
[
|
|
eRankedContributionType.DAMAGED_TITAN // scored automatically by _ranked
|
|
eRankedContributionType.LTS_PILOT_KILL // scored manually in _ranked_gamemodes
|
|
]
|
|
}
|
|
|
|
case TEAM_DEATHMATCH:
|
|
case PILOT_SKIRMISH:
|
|
|
|
local table = {
|
|
mapping =
|
|
[
|
|
eRankedContributionType.TDM_PILOT_KILLS // from xpTypes mapping
|
|
eRankedContributionType.TDM_PILOT_ASSISTS // from xpTypes mapping
|
|
eRankedContributionType.LOSS_PILOT_DEATH // manually credited in _ranked_gamemodes
|
|
]
|
|
|
|
xpTypes = {}
|
|
}
|
|
|
|
if ( !IsLobby() )
|
|
{
|
|
// lobby doesn't know about xp types and doesn't need to, yet
|
|
// Leagues_OnScoreEvent adds ranked points for these events
|
|
table.xpTypes[ XP_TYPE.PILOT_KILL ] <- eRankedContributionType.TDM_PILOT_KILLS
|
|
table.xpTypes[ XP_TYPE.PILOT_ASSIST ] <- eRankedContributionType.TDM_PILOT_ASSISTS
|
|
}
|
|
|
|
return table
|
|
|
|
case CAPTURE_POINT:
|
|
local table =
|
|
{
|
|
mapping =
|
|
[
|
|
eRankedContributionType.ASSAULT // from GetAssaultScore()
|
|
eRankedContributionType.DEFENSE // from GetDefenseScore()
|
|
eRankedContributionType.LOSS_PILOT_DEATH // manually credited in _ranked_gamemodes
|
|
eRankedContributionType.TDM_PILOT_KILLS // from xpTypes mapping
|
|
eRankedContributionType.TDM_PILOT_ASSISTS // from xpTypes mapping
|
|
]
|
|
}
|
|
|
|
if ( !IsLobby() )
|
|
{
|
|
// lobby doesn't know about xp types and doesn't need to, yet
|
|
table.xpTypes <- {}
|
|
|
|
// Leagues_OnScoreEvent adds ranked points for these events
|
|
table.xpTypes[ XP_TYPE.PILOT_KILL ] <- eRankedContributionType.TDM_PILOT_KILLS
|
|
table.xpTypes[ XP_TYPE.PILOT_ASSIST ] <- eRankedContributionType.TDM_PILOT_ASSISTS
|
|
}
|
|
|
|
return table
|
|
|
|
case CAPTURE_THE_FLAG:
|
|
local table = {
|
|
mapping =
|
|
[
|
|
eRankedContributionType.CTF_FLAG_CAPTURES // from score name mapping
|
|
eRankedContributionType.CTF_FLAG_ASSISTS // from score name mapping
|
|
eRankedContributionType.CTF_FLAG_CARRIER_KILLS // from score name mapping
|
|
eRankedContributionType.CTF_FLAG_RETURNS // from score name mapping
|
|
|
|
eRankedContributionType.TDM_PILOT_KILLS // from xpTypes mapping
|
|
eRankedContributionType.TDM_PILOT_ASSISTS // from xpTypes mapping
|
|
eRankedContributionType.LOSS_PILOT_DEATH // manually credited in _ranked_gamemodes
|
|
]
|
|
|
|
// Leagues_OnScoreEvent adds ranked points for these events
|
|
scoreNames =
|
|
{
|
|
FlagCapture = eRankedContributionType.CTF_FLAG_CAPTURES
|
|
FlagReturn = eRankedContributionType.CTF_FLAG_RETURNS
|
|
FlagCarrierKill = eRankedContributionType.CTF_FLAG_CARRIER_KILLS
|
|
FlagCaptureAssist = eRankedContributionType.CTF_FLAG_ASSISTS
|
|
}
|
|
}
|
|
|
|
if ( !IsLobby() )
|
|
{
|
|
// lobby doesn't know about xp types and doesn't need to, yet
|
|
table.xpTypes <- {}
|
|
|
|
// Leagues_OnScoreEvent adds ranked points for these events
|
|
table.xpTypes[ XP_TYPE.PILOT_KILL ] <- eRankedContributionType.TDM_PILOT_KILLS
|
|
table.xpTypes[ XP_TYPE.PILOT_ASSIST ] <- eRankedContributionType.TDM_PILOT_ASSISTS
|
|
}
|
|
|
|
return table
|
|
|
|
|
|
case MARKED_FOR_DEATH_PRO:
|
|
case MARKED_FOR_DEATH:
|
|
|
|
local table = {
|
|
mapping =
|
|
[
|
|
//eRankedContributionType.MarkedSurvival // from score name mapping
|
|
eRankedContributionType.MarkedKilledMarked // from score name mapping
|
|
eRankedContributionType.MarkedOutlastedEnemyMarked // from score name mapping
|
|
eRankedContributionType.MarkedTargetKilled // from score name mapping
|
|
eRankedContributionType.MarkedEscort // from score name mapping
|
|
|
|
eRankedContributionType.TDM_PILOT_KILLS // from xpTypes mapping
|
|
eRankedContributionType.TDM_PILOT_ASSISTS // from xpTypes mapping
|
|
eRankedContributionType.LOSS_PILOT_DEATH // manually credited in _ranked_gamemodes
|
|
]
|
|
|
|
// Leagues_OnScoreEvent adds ranked points for these events
|
|
scoreNames =
|
|
{
|
|
//MarkedSurvival = eRankedContributionType.MarkedSurvival
|
|
MarkedKilledMarked = eRankedContributionType.MarkedKilledMarked
|
|
MarkedOutlastedEnemyMarked = eRankedContributionType.MarkedOutlastedEnemyMarked
|
|
MarkedTargetKilled = eRankedContributionType.MarkedTargetKilled
|
|
MarkedEscort = eRankedContributionType.MarkedEscort
|
|
}
|
|
}
|
|
|
|
if ( !IsLobby() )
|
|
{
|
|
// lobby doesn't know about xp types and doesn't need to, yet
|
|
table.xpTypes <- {}
|
|
|
|
// Leagues_OnScoreEvent adds ranked points for these events
|
|
table.xpTypes[ XP_TYPE.PILOT_KILL ] <- eRankedContributionType.TDM_PILOT_KILLS
|
|
table.xpTypes[ XP_TYPE.PILOT_ASSIST ] <- eRankedContributionType.TDM_PILOT_ASSISTS
|
|
}
|
|
|
|
return table
|
|
|
|
default:
|
|
Assert( 0, "Unhandled gamemode " + gamemode )
|
|
}
|
|
}
|
|
|
|
function GetPlayerRank( player = null )
|
|
{
|
|
if ( IsUI() )
|
|
return GetGemsToRank( GetPlayerTotalCompletedGems() )
|
|
|
|
return player.GetRank()
|
|
}
|
|
|
|
function GetPlayerOldRank( player = null )
|
|
{
|
|
Assert ( IsUI() || IsServer() || ( IsClient() && IsLocalClientPlayer( player ) ) )
|
|
|
|
local previousGemCount
|
|
if ( IsUI() )
|
|
{
|
|
if ( !IsFullyConnected() )
|
|
return 0
|
|
|
|
previousGemCount = GetPersistentVar( "ranked.previousGemCount" )
|
|
}
|
|
else
|
|
previousGemCount = player.GetPersistentVar( "ranked.previousGemCount" )
|
|
|
|
return GetGemsToRank( previousGemCount )
|
|
}
|
|
|
|
function GetPlayerDivision( player= null )
|
|
{
|
|
local rank = GetPlayerRank()
|
|
return (rank / 5).tointeger()
|
|
}
|
|
|
|
function GetPlayerTier( player= null )
|
|
{
|
|
local rank = GetPlayerRank()
|
|
return (rank % 5).tointeger()
|
|
}
|
|
|
|
function GetNextRank( currentRank )
|
|
{
|
|
return currentRank == MAX_RANK ? MAX_RANK : currentRank + 1
|
|
}
|
|
|
|
function GetPreviousRank( currentRank )
|
|
{
|
|
return currentRank == 0 ? 0 : currentRank - 1
|
|
}
|
|
|
|
function GetRankImage( rank )
|
|
{
|
|
rank = clamp( rank, 0, MAX_RANK )
|
|
|
|
local rankColor = 1
|
|
local rankTier = ( rank % 5 ) + 1
|
|
|
|
if ( rank < 5 )
|
|
rankColor = 1
|
|
else if ( rank < 10 )
|
|
rankColor = 2
|
|
else if ( rank < 15 )
|
|
rankColor = 3
|
|
else if ( rank < 20 )
|
|
rankColor = 4
|
|
else
|
|
rankColor = 5
|
|
|
|
return "../ui/menu/rank_icons/tier_" + rankColor + "_" + rankTier
|
|
}
|
|
|
|
if ( IsUI() )
|
|
{
|
|
function PlaylistSupportsRankedPlay()
|
|
{
|
|
if ( GetLobbyTypeScript() == eLobbyType.SOLO )
|
|
return true
|
|
|
|
return GetCurrentPlaylistVarInt( "ranking_supported", 0 )
|
|
}
|
|
|
|
function GameModeSupportsRankedPlay()
|
|
{
|
|
if ( GetLobbyTypeScript() == eLobbyType.SOLO )
|
|
return true
|
|
|
|
if ( level.ui.nextMapModeComboIndex == null )
|
|
return true
|
|
|
|
local modeName = GetCurrentPlaylistGamemodeByIndex( level.ui.nextMapModeComboIndex )
|
|
if ( !PersistenceEnumValueIsValid( "gameModes", modeName ) )
|
|
return false
|
|
|
|
return modeName in level.rankedInitFuncs
|
|
}
|
|
}
|
|
else
|
|
{
|
|
function PlaylistSupportsRankedPlay()
|
|
{
|
|
if ( IsMenuLevel() )
|
|
return false
|
|
|
|
if ( IsPrivateMatch() && !IsDelta() )
|
|
return false
|
|
|
|
if ( !GetCurrentPlaylistVarInt( "ranking_supported", 0 ) )
|
|
return false
|
|
|
|
return true
|
|
}
|
|
|
|
function GameModeSupportsRankedPlay()
|
|
{
|
|
// if ( !PersistenceEnumValueIsValid( "gameModes", GAMETYPE ) )
|
|
// return false
|
|
|
|
return GAMETYPE in level.rankedInitFuncs
|
|
}
|
|
}
|
|
|
|
function GetPlayerGemState( player, index, usePreviousData = false )
|
|
{
|
|
if ( IsUI() )
|
|
{
|
|
if ( !IsFullyConnected() )
|
|
return "gem_undefeated"
|
|
}
|
|
|
|
if ( usePreviousData )
|
|
{
|
|
local previousSize = PersistenceGetArrayCount( "ranked.previousGems" )
|
|
local previousGemCount = IsUI() ? GetPersistentVar( "ranked.previousGemCount" ) : player.GetPersistentVar( "ranked.previousGemCount" )
|
|
if ( index >= previousGemCount - 1 && index < previousGemCount + previousSize - 1 )
|
|
{
|
|
local previousGemsIndex = index - previousGemCount + 1
|
|
local var = "ranked.previousGems[" + previousGemsIndex + "].gemState"
|
|
|
|
if ( IsUI() )
|
|
return GetPersistentVar( var )
|
|
else
|
|
return player.GetPersistentVar( var )
|
|
}
|
|
|
|
// return "gem_captured"
|
|
}
|
|
|
|
if ( IsUI() )
|
|
return GetPersistentVar( "ranked.gems" + "[" + index + "].gemState" )
|
|
return player.GetPersistentVar( "ranked.gems" + "[" + index + "].gemState" )
|
|
}
|
|
|
|
function GetPlayerGemScore( player, index, usePreviousData = false )
|
|
{
|
|
if ( IsUI() )
|
|
{
|
|
if ( !IsFullyConnected() )
|
|
return 0.0
|
|
}
|
|
|
|
if ( usePreviousData )
|
|
{
|
|
local previousSize = PersistenceGetArrayCount( "ranked.previousGems" )
|
|
local previousGemCount = IsUI() ? GetPersistentVar( "ranked.previousGemCount" ) : player.GetPersistentVar( "ranked.previousGemCount" )
|
|
if ( index >= previousGemCount - 1 && index < previousGemCount + previousSize - 1 )
|
|
{
|
|
local previousGemsIndex = index - previousGemCount + 1
|
|
local var = "ranked.previousGems[" + previousGemsIndex + "].gemScore"
|
|
if ( IsUI() )
|
|
return GetPersistentVar( var )
|
|
else
|
|
return player.GetPersistentVar( var )
|
|
}
|
|
}
|
|
|
|
if ( IsUI() )
|
|
return GetPersistentVar( "ranked.gems" + "[" + index + "].gemScore" )
|
|
|
|
return player.GetPersistentVar( "ranked.gems" + "[" + index + "].gemScore" )
|
|
}
|
|
|
|
function GetPlayerTotalCompletedGems( player = null )
|
|
{
|
|
local count = 0
|
|
local max = GetMaxGems()
|
|
for ( local i = 0 ; i < max ; i++ )
|
|
{
|
|
local gemState = GetPlayerGemState( player, i )
|
|
|
|
switch ( gemState )
|
|
{
|
|
case "gem_captured":
|
|
case "gem_damaged":
|
|
count++
|
|
break
|
|
}
|
|
}
|
|
|
|
return count
|
|
}
|
|
|
|
function GetPreviousPlayerTotalCompletedGems( player = null )
|
|
{
|
|
local count = 0
|
|
local max = GetMaxGems()
|
|
for ( local i = 0 ; i < max ; i++ )
|
|
{
|
|
local gemState = GetPlayerGemState( player, i, true )
|
|
|
|
switch ( gemState )
|
|
{
|
|
case "gem_captured":
|
|
case "gem_damaged":
|
|
count++
|
|
break
|
|
}
|
|
}
|
|
|
|
return count
|
|
}
|
|
|
|
|
|
|
|
function GetPlayerSponsorshipsRemaining( player = null )
|
|
{
|
|
if ( IsUI() )
|
|
{
|
|
if ( !IsFullyConnected() )
|
|
return 0
|
|
|
|
return GetPersistentVar( "ranked.sponsorshipsRemaining" )
|
|
}
|
|
|
|
return player.GetPersistentVar( "ranked.sponsorshipsRemaining" )
|
|
}
|
|
|
|
function PlayerAcceptedRankInvite( player = null )
|
|
{
|
|
if ( IsUI() )
|
|
{
|
|
if ( !IsFullyConnected() )
|
|
return false
|
|
|
|
return GetPersistentVar( "ranked.joinedRankedPlay" )
|
|
}
|
|
else
|
|
{
|
|
return player.GetPersistentVar( "ranked.joinedRankedPlay" )
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
function PlayerQualifiedForRanked( player = null )
|
|
{
|
|
// return true
|
|
|
|
if ( IsUI() )
|
|
{
|
|
// gen 10 players get one invite
|
|
if ( GetGen() >= MAX_GEN )
|
|
return true
|
|
|
|
if ( GetRankInviteMode() == "none" )
|
|
return GetGen() > 0 || GetLevel() >= 32
|
|
|
|
if ( !IsFullyConnected() )
|
|
return false
|
|
|
|
if ( GetPersistentVar( "ranked.joinedRankedPlay" ) )
|
|
return true
|
|
return GetPersistentVar( "ranked.mySponsorName" ) != ""
|
|
}
|
|
|
|
// gen 10 players get one invite
|
|
if ( player.GetGen() >= MAX_GEN )
|
|
return true
|
|
|
|
if ( GetRankInviteMode() == "none" )
|
|
return player.GetGen() > 0 || GetLevel( player ) >= 32
|
|
|
|
if ( player.GetPersistentVar( "ranked.joinedRankedPlay" ) )
|
|
return true
|
|
return player.GetPersistentVar( "ranked.mySponsorName" ) != ""
|
|
}
|
|
|
|
function GetPlayerTimeTillNextGemDecay( player = null, currentTime = null )
|
|
{
|
|
local nextGemDecayTime = GetPlayerGemDecayTime( player )
|
|
if ( currentTime == null )
|
|
currentTime = Daily_GetCurrentTime()
|
|
return nextGemDecayTime - currentTime
|
|
}
|
|
|
|
function GetRankedDecayRate()
|
|
{
|
|
// amount of time before gem decays
|
|
return GetCurrentPlaylistVarFloat( "ranked_decay_days", 1.0 ) * SECONDS_PER_DAY
|
|
}
|
|
|
|
function GetPlayerGemDecayTime( player = null )
|
|
{
|
|
// amount of time until this player gets gem decay
|
|
if ( IsUI() && !IsFullyConnected() )
|
|
return 0
|
|
|
|
local savedTime = IsUI() ? GetPersistentVar( "ranked.nextGemDecayTime" ) : player.GetPersistentVar( "ranked.nextGemDecayTime" )
|
|
local currentTime = Daily_GetCurrentTime()
|
|
if ( savedTime == 0 )
|
|
savedTime = currentTime + (GetRankedDecayRate())
|
|
return savedTime
|
|
}
|
|
|
|
function GetRankedSeason( unixTime = null )
|
|
{
|
|
local timeParts = GetUnixTimeParts( unixTime )
|
|
local yearsElapsed = timeParts["year"] - 1970
|
|
local monthsElapsed = ( yearsElapsed * 12 ) + timeParts["month"] - RANKED_SEASON_OFFSET
|
|
local numDaysPerSeason = ( 28 / RANKED_SEASONS_PER_MONTH ).tointeger()
|
|
local numSeasonsElapsedThisMonth = min( timeParts["day"] / numDaysPerSeason, RANKED_SEASONS_PER_MONTH - 1 )
|
|
local seasonsElapsed = (monthsElapsed * RANKED_SEASONS_PER_MONTH) + numSeasonsElapsedThisMonth
|
|
|
|
return seasonsElapsed
|
|
}
|
|
|
|
function GetCurrentSeasonEndTime()
|
|
{
|
|
local unixTimeNow = Daily_GetCurrentTime()
|
|
local timePartsNow = GetUnixTimeParts( unixTimeNow )
|
|
local currentSeason = GetRankedSeason( unixTimeNow )
|
|
|
|
// Add days until we roll over to the next month
|
|
local unixTimeNextSeason = unixTimeNow
|
|
local nextSeason = currentSeason
|
|
while( nextSeason == currentSeason )
|
|
{
|
|
unixTimeNextSeason += SECONDS_PER_DAY
|
|
nextSeason = GetRankedSeason( unixTimeNextSeason )
|
|
}
|
|
|
|
// Subtract time we went over to the next month
|
|
unixTimeNextSeason -= (timePartsNow["hour"] * SECONDS_PER_HOUR) + (timePartsNow["minute"] * SECONDS_PER_MINUTE) + timePartsNow["second"]
|
|
|
|
return unixTimeNextSeason
|
|
}
|
|
|
|
function GetCurrentSeasonStartTime()
|
|
{
|
|
local unixTimeNow = Daily_GetCurrentTime()
|
|
local timePartsNow = GetUnixTimeParts( unixTimeNow )
|
|
local currentSeason = GetRankedSeason( unixTimeNow )
|
|
|
|
// Go back days until we find the previous season
|
|
local unixTimePreviousSeason = unixTimeNow
|
|
local previousSeason = currentSeason
|
|
while( previousSeason == currentSeason )
|
|
{
|
|
unixTimePreviousSeason -= SECONDS_PER_DAY
|
|
previousSeason = GetRankedSeason( unixTimePreviousSeason )
|
|
}
|
|
|
|
// Subtract time left in the day, then add 1 day for when the season first started
|
|
unixTimePreviousSeason -= (timePartsNow["hour"] * SECONDS_PER_HOUR) + (timePartsNow["minute"] * SECONDS_PER_MINUTE) + timePartsNow["second"]
|
|
unixTimePreviousSeason += SECONDS_PER_DAY
|
|
|
|
return unixTimePreviousSeason
|
|
}
|
|
|
|
|
|
|
|
|
|
function ContributionLossForPilotDeath()
|
|
{
|
|
return eRankedContributionType.LOSS_PILOT_DEATH in GetContributionContTypes()
|
|
}
|
|
|
|
|
|
function InitRankedPanelElems( elemGroup, rankedPanel, hudGroup = null )
|
|
{
|
|
elemGroup.paused <- false
|
|
elemGroup.RankedGoals <- []
|
|
|
|
if ( IsClient() )
|
|
{
|
|
elemGroup.RankedBG <- hudGroup.CreateElement( "RankedBG", rankedPanel )
|
|
elemGroup.RankedLogo <- hudGroup.CreateElement( "RankedLogo", rankedPanel )
|
|
elemGroup.RankedGoal_NoNumbersProgressBar <- hudGroup.CreateElement( "RankedGoal_NoNumbersProgressBar", rankedPanel )
|
|
|
|
for ( local i = 0; i < RATING_GOALS; i++ )
|
|
{
|
|
elemGroup.RankedGoals.append( hudGroup.CreateElement( "RankedGoal_Gem" + i, rankedPanel ) )
|
|
}
|
|
}
|
|
else
|
|
{
|
|
elemGroup.RankedBG <- rankedPanel.GetChild( "RankedBG" )
|
|
elemGroup.RankedLogo <- rankedPanel.GetChild( "RankedLogo" )
|
|
elemGroup.RankedGoal_NoNumbersProgressBar <- rankedPanel.GetChild( "RankedGoal_NoNumbersProgressBar" )
|
|
|
|
for ( local i = 0; i < RATING_GOALS; i++ )
|
|
{
|
|
elemGroup.RankedGoals.append( rankedPanel.GetChild( "RankedGoal_Gem" + i ) )
|
|
}
|
|
}
|
|
|
|
elemGroup.RankedBG.SetAlpha( 0 )
|
|
elemGroup.RankedBG.ClearPulsate()
|
|
|
|
if ( !( "GameInfo_Icon" in elemGroup ) )
|
|
elemGroup.GameInfo_Icon <- null
|
|
|
|
elemGroup.outElem <- elemGroup.RankedLogo
|
|
elemGroup.inElem <- elemGroup.GameInfo_Icon
|
|
|
|
elemGroup.RankedGoal_NoNumbersProgressBar.SetColor( RANKED_SPLASH_COLORS_MAIN )
|
|
}
|
|
Globalize( InitRankedPanelElems )
|
|
|
|
function UpdateProgressBarsOverTime( elemGroup, menuOrCockpit = null, forceJumpToCurrentState = false )
|
|
{
|
|
local jumpToCurrentState
|
|
|
|
if ( IsUI() )
|
|
{
|
|
EndSignal( menuOrCockpit, "StopMenuAnimation" )
|
|
jumpToCurrentState = forceJumpToCurrentState
|
|
|
|
OnThreadEnd(
|
|
function() : ( )
|
|
{
|
|
StopUISound( "UI_RankedSummary_BattleMark_Blinking" )
|
|
StopUISound( "UI_RankedSummary_CircleFill" )
|
|
}
|
|
)
|
|
}
|
|
else
|
|
{
|
|
jumpToCurrentState = true
|
|
|
|
if ( menuOrCockpit )
|
|
menuOrCockpit.EndSignal( "OnDestroy" )
|
|
}
|
|
|
|
elemGroup.RankedGoal_NoNumbersProgressBar.SetBarProgressRemap( 0, 1.0, 0.0, 1.0 )
|
|
//if ( level.performanceGoals.top() < 100.0 )
|
|
// goals.append( 100.0 )
|
|
|
|
local e = {}
|
|
e.lastFrame <- { perf = 0.01, goalIndex = 0 }
|
|
e.nextFrame <- { perf = 0, goalIndex = 0 }
|
|
|
|
local width = elemGroup.RankedBG.GetWidth()
|
|
|
|
if ( jumpToCurrentState )
|
|
{
|
|
local goalIndex = GetGoalIndexFromScore( level.currentPerformance )
|
|
local nextPerf = GetGoalPerf( level.currentPerformance, goalIndex )
|
|
e.lastFrame <- { perf = nextPerf, goalIndex = goalIndex }
|
|
e.nextFrame <- { perf = nextPerf, goalIndex = goalIndex }
|
|
elemGroup.RankedGoal_NoNumbersProgressBar.SetBarProgress( nextPerf )
|
|
if ( nextPerf == 1.0 )
|
|
goalIndex++
|
|
GemTransition( elemGroup, goalIndex, 0 )
|
|
if ( IsUI() )
|
|
GemWonText( goalIndex - 1 )
|
|
}
|
|
else
|
|
{
|
|
e.lastFrame <- { perf = 0.01, goalIndex = 0 }
|
|
e.nextFrame <- { perf = 0, goalIndex = 0 }
|
|
GemTransition( elemGroup, 0, 0 )
|
|
}
|
|
|
|
for ( ;; )
|
|
{
|
|
if ( !TransitionProgressBar( e, elemGroup, width ) )
|
|
{
|
|
if ( IsUI() && !elemGroup.paused )
|
|
{
|
|
Signal( level, "CompletedProgressTally" )
|
|
return
|
|
}
|
|
|
|
WaitSignal( level, "NewPerformanceUpdate" )
|
|
}
|
|
}
|
|
}
|
|
Globalize( UpdateProgressBarsOverTime )
|
|
|
|
function TransitionProgressBar( e, elemGroup, width )
|
|
{
|
|
if ( elemGroup.paused )
|
|
return false
|
|
|
|
if ( FillNextFrame( e ) )
|
|
{
|
|
TransitionFrames( e, elemGroup, width )
|
|
//printt( " " )
|
|
//printt( "From " + e.lastFrame.goalIndex + ": " + e.lastFrame.perf + " to " + e.nextFrame.goalIndex + ": " + e.nextFrame.perf )
|
|
e.lastFrame = clone e.nextFrame
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
function GetLowerGoal( goalIndex )
|
|
{
|
|
local lastGoal
|
|
if ( goalIndex > 0 )
|
|
return level.performanceGoals[ goalIndex - 1 ]
|
|
return 0
|
|
}
|
|
|
|
function GetGoalPerf( performance, nextGoalIndex )
|
|
{
|
|
return GraphCapped( performance, GetLowerGoal( nextGoalIndex ), level.performanceGoals[ nextGoalIndex ], 0, 1.0 )
|
|
}
|
|
|
|
function FillNextFrame( e )
|
|
{
|
|
local prevPerf = e.lastFrame.perf
|
|
local prevGoalIndex = e.lastFrame.goalIndex
|
|
|
|
local performance = level.currentPerformance
|
|
local nextGoalIndex = GetGoalIndexFromScore( performance )
|
|
|
|
// moving within one goal
|
|
if ( nextGoalIndex == prevGoalIndex )
|
|
{
|
|
local nextPerf = GetGoalPerf( performance, nextGoalIndex )
|
|
|
|
// hasn't changed, need new destination
|
|
if ( nextPerf == e.lastFrame.perf )
|
|
return false
|
|
|
|
e.nextFrame.perf = nextPerf
|
|
e.nextFrame.goalIndex = nextGoalIndex
|
|
return true
|
|
}
|
|
|
|
// rising to a higher goal
|
|
if ( nextGoalIndex > prevGoalIndex )
|
|
{
|
|
// can't go up more than one goal per transition
|
|
nextGoalIndex = min( nextGoalIndex, prevGoalIndex + 1 )
|
|
|
|
if ( e.lastFrame.perf == 1.0 )
|
|
{
|
|
// already full? then move to next goal
|
|
local goal = level.performanceGoals[ nextGoalIndex ]
|
|
e.lastFrame.goalIndex = nextGoalIndex
|
|
e.lastFrame.perf = 0.0
|
|
e.nextFrame.goalIndex = nextGoalIndex
|
|
e.nextFrame.perf = GetGoalPerf( level.performanceGoals[ prevGoalIndex ], nextGoalIndex )
|
|
}
|
|
else
|
|
{
|
|
// fill it up
|
|
e.nextFrame.perf = 1.0
|
|
e.nextFrame.goalIndex = prevGoalIndex
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// falling to a lower goal
|
|
|
|
// can't fall more than one goal per transition
|
|
nextGoalIndex = max( nextGoalIndex, prevGoalIndex - 1 )
|
|
|
|
local lowerGoal = level.performanceGoals[ nextGoalIndex ]
|
|
local higherGoal = level.performanceGoals[ prevGoalIndex ]
|
|
local lowerPerf = GetGoalPerf( lowerGoal, prevGoalIndex )
|
|
|
|
if ( prevPerf > lowerPerf )
|
|
{
|
|
// we're within a goal and falling to the next lower, so first, drop to the lower goal line
|
|
e.nextFrame.goalIndex = prevGoalIndex
|
|
e.nextFrame.perf = lowerPerf
|
|
return true
|
|
}
|
|
|
|
// fall from 1.0
|
|
e.lastFrame.goalIndex = nextGoalIndex
|
|
e.lastFrame.perf = 1.0
|
|
|
|
performance = GetGoalPerf( performance, nextGoalIndex )
|
|
e.nextFrame.goalIndex = nextGoalIndex
|
|
e.nextFrame.perf = max( performance, lowerPerf )
|
|
|
|
return true
|
|
}
|
|
|
|
|
|
function TransitionFrames( e, elemGroup, width )
|
|
{
|
|
//return
|
|
local perfDif = fabs( e.nextFrame.perf - e.lastFrame.perf )
|
|
if ( perfDif == 0.0 )
|
|
return
|
|
|
|
local time
|
|
if ( IsUI() )
|
|
{
|
|
EmitUISound( "UI_RankedSummary_CircleFill" )
|
|
time = GraphCapped( perfDif, 0, 1.0, 0.25, 0.8 )
|
|
}
|
|
else
|
|
{
|
|
// transition slowly if the player hasn't done anything lately
|
|
if ( e.nextFrame.perf != 1.0 && e.lastFrame.perf != 1.0 && Time() - level.lastRankScoreSplash > RANKED_RECALC_TIMESLICE )
|
|
time = RANKED_RECALC_TIMESLICE
|
|
else
|
|
time = GraphCapped( perfDif, 0, 1.0, 0.2, 0.7 )
|
|
}
|
|
|
|
if ( e.lastFrame.perf == 1.0 )
|
|
{
|
|
// coming from 1.0
|
|
GemTransition( elemGroup, e.nextFrame.goalIndex, 0 )
|
|
// lost a gem
|
|
EmitSoundOnEntity( GetLocalClientPlayer(), "UI_InGame_League_BelowGoal" )
|
|
}
|
|
|
|
// transition the bar
|
|
Assert( e.lastFrame.perf >= 0 && e.lastFrame.perf <= 1.0 )
|
|
Assert( e.nextFrame.perf >= 0 && e.nextFrame.perf <= 1.0 )
|
|
elemGroup.RankedGoal_NoNumbersProgressBar.SetBarProgressOverTime( e.lastFrame.perf, e.nextFrame.perf, time )
|
|
wait time
|
|
|
|
if ( IsUI() )
|
|
StopUISound( "UI_RankedSummary_CircleFill" )
|
|
|
|
if ( e.nextFrame.perf == 1.0 )
|
|
{
|
|
// gained a gem
|
|
if ( IsUI() )
|
|
{
|
|
EmitUISound( "UI_RankedSummary_CircleTick_Reached" )
|
|
EmitUISound( "UI_RankedSummary_BattleMark_Blinking" )
|
|
}
|
|
else
|
|
{
|
|
EmitSoundOnEntity( GetLocalClientPlayer(), "UI_InGame_League_AboveGoal" )
|
|
}
|
|
|
|
if ( IsUI() )
|
|
Signal( level, "CapturedGem" )
|
|
|
|
GemTransition( elemGroup, e.nextFrame.goalIndex + 1 )
|
|
|
|
elemGroup.RankedBG.SetPulsate( 0.25, 1.0, 25 )
|
|
elemGroup.RankedBG.SetColor( 255, 255, 255, 150 )
|
|
|
|
wait 0.3
|
|
|
|
if ( IsUI() )
|
|
{
|
|
EmitUISound( "UI_RankedSummary_BattleMark_Blinking" )
|
|
EmitUISound( "UI_RankedSummary_BattleMark_Locked" )
|
|
|
|
wait 0.3
|
|
}
|
|
|
|
elemGroup.RankedBG.ClearPulsate()
|
|
FadeBGToBlack( elemGroup )
|
|
}
|
|
}
|
|
|
|
function BlendInCurrentLogo( elemGroup )
|
|
{
|
|
if ( !elemGroup.GameInfo_Icon )
|
|
return
|
|
elemGroup.inElem.FadeOverTime( SECRET_SOCIETY_ICON_ALPHA, 0.4 )
|
|
elemGroup.outElem.FadeOverTime( 0, 0.4 )
|
|
}
|
|
Globalize( BlendInCurrentLogo )
|
|
|
|
function GemTransition( elemGroup, completedCount, time = 0.3 )
|
|
{
|
|
local count = level.performanceGoals.len()
|
|
BlendInCurrentLogo( elemGroup )
|
|
|
|
local dist = elemGroup.RankedBG.GetWidth() * GEM_DIST
|
|
local range = 30
|
|
local offset = count * 0.5 - 0.5
|
|
|
|
for ( local index = 0; index < count; index++ )
|
|
{
|
|
local elem = elemGroup.RankedGoals[ index ]
|
|
local x, y
|
|
local degree = offset * -range + index * range
|
|
degree -= 90
|
|
|
|
x = deg_cos( degree ) * dist
|
|
y = deg_sin( degree ) * dist
|
|
|
|
degree = 270 - degree
|
|
|
|
elem.SetRotation( degree )
|
|
elem.Show()
|
|
elem.SetAlpha( 255 )
|
|
|
|
if ( index < completedCount )
|
|
{
|
|
elem.SetImage( "hud/ranked_goal_tiny_filled" )
|
|
elem.SetColor( 255, 255, 255, 255 )
|
|
}
|
|
else
|
|
{
|
|
elem.SetImage( "hud/ranked_goal_tiny_empty" )
|
|
elem.SetColor( 50, 76, 82, 255 )
|
|
}
|
|
|
|
if ( index == completedCount - 1 && time > 0 )
|
|
{
|
|
elem.SetScale( 6.5, 6.5 )
|
|
elem.ScaleOverTime( 1.0, 1.0, time )
|
|
elem.SetAlpha( 0 )
|
|
elem.FadeOverTime( 255, time )
|
|
elem.SetPos( 0, 0 )
|
|
elem.MoveOverTime( x, y, time )
|
|
}
|
|
else
|
|
{
|
|
elem.SetPos( x, y )
|
|
}
|
|
}
|
|
|
|
for ( local i = count; i < RATING_GOALS; i++ )
|
|
{
|
|
elemGroup.RankedGoals[ i ].Hide()
|
|
}
|
|
}
|
|
Globalize( GemTransition )
|
|
|
|
function FadeBGToBlack( elemGroup )
|
|
{
|
|
elemGroup.RankedBG.FadeOverTime( 0, 0.5 )
|
|
}
|
|
Globalize( FadeBGToBlack )
|
|
|
|
|
|
function GetGoalIndexFromScore( score )
|
|
{
|
|
foreach ( index, goal in level.performanceGoals )
|
|
{
|
|
if ( goal > score )
|
|
return index
|
|
}
|
|
return level.performanceGoals.len() - 1
|
|
}
|
|
Globalize( GetGoalIndexFromScore )
|
|
|
|
|
|
function MatchSupportsRankedPlay( player = null )
|
|
{
|
|
if( IsPrivateMatch() && !IsDelta() )
|
|
return false
|
|
|
|
if ( !PlaylistSupportsRankedPlay() )
|
|
return false
|
|
|
|
if ( !GameModeSupportsRankedPlay() )
|
|
return false
|
|
|
|
return true
|
|
}
|
|
|
|
|
|
function TooLateForRanked()
|
|
{
|
|
if ( level.nv.matchProgress >= 90 ) // Over 90%? Don't let ranks be late enabled
|
|
return true
|
|
|
|
if ( IsRoundBased() ) // Last round?
|
|
{
|
|
local lastPlayableRound = GetRoundScoreLimit_FromPlaylist() - 1 // -1 because the round being played for the win is the one before the limit
|
|
if ( level.nv.roundsPlayed >= lastPlayableRound )
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
function GetRankInviteMode()
|
|
{
|
|
local var = GetCurrentPlaylistVar( "RankInviteMode" )
|
|
if ( var == "" )
|
|
return "gen10"
|
|
return var
|
|
}
|
|
|
|
function RankedAlwaysLoseGem()
|
|
{
|
|
if ( IsUI() && !IsFullyConnected() )
|
|
return true
|
|
|
|
local var = GetCurrentPlaylistVar( "ranked_lose_gem" )
|
|
if ( var == "" )
|
|
var = "on"
|
|
return var == "on"
|
|
}
|