s1-scripts-dev/raw/maps/mp/_reinforcements.gsc
2025-05-21 16:23:17 +02:00

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();
}