264 lines
6.7 KiB
Plaintext
264 lines
6.7 KiB
Plaintext
#include maps\mp\_utility;
|
|
#include common_scripts\utility;
|
|
|
|
REINFORCEMENT_TYPE_NONE = 0;
|
|
REINFORCEMENT_TYPE_COMMON = 1;
|
|
REINFORCEMENT_TYPE_UNCOMMON = 2;
|
|
REINFORCEMENT_TYPE_RARE = 3;
|
|
REINFORCEMENT_TYPE_PRACTICE = 4;
|
|
|
|
init()
|
|
{
|
|
/#
|
|
SetDvarIfUninitialized( "scr_force_reinforcements", 0 );
|
|
|
|
if( GetDvarInt( "scr_isGamescom" ) == 1 )
|
|
SetDvarIfUninitialized( "scr_force_reinforcements_randomly", 0 );
|
|
else
|
|
SetDvarIfUninitialized( "scr_force_reinforcements_randomly", 1 );
|
|
|
|
#/
|
|
|
|
if ( level.rankedMatch )
|
|
level thread onPlayerConnect();
|
|
}
|
|
|
|
onPlayerConnect()
|
|
{
|
|
level endon ( "game_ended" );
|
|
|
|
level waittill ( "prematch_over" );
|
|
waitframe();
|
|
|
|
foreach ( player in level.players )
|
|
{
|
|
if ( IsBot( player ) )
|
|
continue;
|
|
|
|
player resetReinforcements();
|
|
player thread checkForReinforcements();
|
|
}
|
|
|
|
while( true )
|
|
{
|
|
level waittill( "connected", player );
|
|
if ( IsBot( player ) )
|
|
continue;
|
|
|
|
player resetReinforcements();
|
|
player thread checkForReinforcements();
|
|
}
|
|
}
|
|
|
|
resetReinforcements() // self == player
|
|
{
|
|
self SetClientOmnvar( "ui_reinforcement_timer_type", 0 );
|
|
self SetClientOmnvar( "ui_reinforcement_timer", 0 );
|
|
}
|
|
|
|
storePendingReinforcement( type ) // self == player
|
|
{
|
|
self.pers["reinforcements"] = SpawnStruct();
|
|
self.pers["reinforcements"].type = type;
|
|
self.pers["reinforcements"].startTimePassed = getGameTimePassedMS();
|
|
}
|
|
|
|
cancelPendingReinforcement() // self == player
|
|
{
|
|
self.pers["reinforcements"].type = 0;
|
|
}
|
|
|
|
pendingReinforcementAvailable() // self == player
|
|
{
|
|
return IsDefined( self.pers["reinforcements"] );
|
|
}
|
|
|
|
checkForReinforcements() // self == player
|
|
{
|
|
self endon( "disconnect" );
|
|
level endon( "game_ended" );
|
|
|
|
if( !allowClassChoice() )
|
|
return;
|
|
|
|
// Wait until the player has joined a team
|
|
if ( self.health <= 0 )
|
|
self waittill( "spawned_player" );
|
|
|
|
// Handle round-switching
|
|
if ( self pendingReinforcementAvailable() )
|
|
{
|
|
self thread continueReinforcements();
|
|
return;
|
|
}
|
|
|
|
typeAvailable = REINFORCEMENT_TYPE_NONE;
|
|
|
|
if ( practiceRoundGame() )
|
|
{
|
|
typeAvailable = REINFORCEMENT_TYPE_PRACTICE;
|
|
}
|
|
else
|
|
{
|
|
typeAvailable = self ConsumeReinforcement();
|
|
|
|
|
|
/#
|
|
//giving every player a chance of a reinforcement on connect. ONLY FOR TESTING.
|
|
if ( GetDvarInt( "scr_force_reinforcements_randomly", 0 ) > 0 )
|
|
{
|
|
i = RandomInt( 100 );
|
|
|
|
if ( i < 75 )
|
|
typeAvailable = 0;
|
|
else if ( i < 90 )
|
|
typeAvailable = 1;
|
|
else if ( i < 98 )
|
|
typeAvailable = 2;
|
|
else if ( i < 100 )
|
|
typeAvailable = 3;
|
|
|
|
}
|
|
|
|
if ( GetDvarInt( "scr_force_reinforcements", 0 ) > 0 )
|
|
typeAvailable = GetDvarInt( "scr_force_reinforcements", 0 );
|
|
|
|
SetDvar( "scr_force_reinforcements_randomly", 0 );
|
|
SetDvar( "src_force_reinforcements", 0 );
|
|
#/
|
|
}
|
|
|
|
// Record data about reinforcements available
|
|
storePendingReinforcement( typeAvailable );
|
|
|
|
if ( typeAvailable == REINFORCEMENT_TYPE_NONE )
|
|
return;
|
|
|
|
timeToReinforcementMS = getTimeToReinforcementForTypeMS( typeAvailable );
|
|
matchTimeRemainingMS = getTimeRemainingIncludingRounds();
|
|
|
|
if ( matchTimeRemainingMS < timeToReinforcementMS )
|
|
{
|
|
// Cancel as there isn't enough time left in the match
|
|
cancelPendingReinforcement();
|
|
return;
|
|
}
|
|
|
|
self thread waitForReinforcementOfType( typeAvailable, timeToReinforcementMS );
|
|
}
|
|
|
|
continueReinforcements() // self == player
|
|
{
|
|
typeAvailable = self.pers["reinforcements"].type;
|
|
if ( typeAvailable == REINFORCEMENT_TYPE_NONE )
|
|
return;
|
|
|
|
timeToReinforcementMS = getTimeToReinforcementForTypeMS( typeAvailable );
|
|
matchTimeElapsedMS = getGameTimePassedMS();
|
|
startTimeElapsedMS = self.pers["reinforcements"].startTimePassed;
|
|
|
|
timeToReinforcementMS -= matchTimeElapsedMS;
|
|
timeToReinforcementMS += startTimeElapsedMS;
|
|
|
|
self thread waitForReinforcementOfType( typeAvailable, timeToReinforcementMS );
|
|
}
|
|
|
|
getTimeRemainingIncludingRounds()
|
|
{
|
|
if ( isRoundBased() )
|
|
{
|
|
numRoundsToWin = getScoreLimit();
|
|
minRoundsRemaining = min( numRoundsToWin - getRoundsWon( "allies" ), numRoundsToWin - getRoundsWon( "axis" ) );
|
|
timeLimitMin = getTimeLimit() * minRoundsRemaining;
|
|
return ( timeLimitMin * 60 * 1000 ) - getTimePassed();
|
|
}
|
|
else
|
|
{
|
|
return maps\mp\gametypes\_gamelogic::getTimeRemaining();
|
|
}
|
|
}
|
|
|
|
|
|
getTimeToReinforcementForTypeMS( type ) // self == player
|
|
{
|
|
switch( type )
|
|
{
|
|
case REINFORCEMENT_TYPE_COMMON: return 2 * 60 * 1000; // 2 minutes
|
|
case REINFORCEMENT_TYPE_UNCOMMON: return 4 * 60 * 1000; // 4 minutes
|
|
case REINFORCEMENT_TYPE_RARE: return 6 * 60 * 1000; // 6 minutes
|
|
case REINFORCEMENT_TYPE_PRACTICE: return 1 * 60 * 1000; // 1 minute
|
|
default:
|
|
AssertMsg( "getTimeToReinforcementForType(): Unhandled reinforcement type: " + type );
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
getIconTypeForReinforcementOfType( type ) // self == player
|
|
{
|
|
switch( type )
|
|
{
|
|
case REINFORCEMENT_TYPE_COMMON: return 1; // Common
|
|
case REINFORCEMENT_TYPE_UNCOMMON: return 2; // Uncommon
|
|
case REINFORCEMENT_TYPE_RARE: return 3; // Rare
|
|
case REINFORCEMENT_TYPE_PRACTICE: return 1; // Common
|
|
default:
|
|
AssertMsg( "getIconTypeForReinforcementOfType(): Unhandled reinforcement type: " + type );
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
getCarePackageStreakForReinforcementOfType( type ) // self == player
|
|
{
|
|
switch( type )
|
|
{
|
|
case REINFORCEMENT_TYPE_COMMON: return "airdrop_reinforcement_common";
|
|
case REINFORCEMENT_TYPE_UNCOMMON: return "airdrop_reinforcement_uncommon";
|
|
case REINFORCEMENT_TYPE_RARE: return "airdrop_reinforcement_rare";
|
|
case REINFORCEMENT_TYPE_PRACTICE: return "airdrop_reinforcement_practice";
|
|
default:
|
|
AssertMsg( "getCarePackageStreakForReinforcementOfType(): Unhandled reinforcement type: " + type );
|
|
break;
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
waitForReinforcementOfType( type, timeMS ) // self == player
|
|
{
|
|
self endon( "disconnect" );
|
|
level endon( "game_ended" );
|
|
|
|
Assert( type != REINFORCEMENT_TYPE_NONE );
|
|
|
|
iconType = getIconTypeForReinforcementOfType( type );
|
|
|
|
self SetClientOmnvar( "ui_reinforcement_timer_type", iconType );
|
|
self SetClientOmnvar( "ui_reinforcement_timer", ( GetTime() + timeMS ) );
|
|
|
|
maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( timeMS / 1000.0 );
|
|
|
|
self SetClientOmnvar( "ui_reinforcement_timer_type", 0 );
|
|
self SetClientOmnvar( "ui_reinforcement_timer", 0 );
|
|
|
|
// Give the package of type
|
|
giveReinforcementOfType( type );
|
|
}
|
|
|
|
giveReinforcementOfType( type ) // self == player
|
|
{
|
|
if ( !IsPlayer( self ) )
|
|
return;
|
|
|
|
streakName = getCarePackageStreakForReinforcementOfType( type );
|
|
streakVal = 500;
|
|
|
|
slotIndex = self maps\mp\killstreaks\_killstreaks::getNextKillstreakSlotIndex( streakName );
|
|
self thread maps\mp\gametypes\_hud_message::killstreakSplashNotify( streakName, streakVal, undefined, undefined, slotIndex );
|
|
self maps\mp\killstreaks\_killstreaks::giveKillstreak( streakName );
|
|
|
|
cancelPendingReinforcement();
|
|
} |