1443 lines
42 KiB
Plaintext
1443 lines
42 KiB
Plaintext
#using scripts\shared\flag_shared;
|
|
#using scripts\shared\array_shared;
|
|
#using scripts\shared\callbacks_shared;
|
|
#using scripts\shared\gameobjects_shared;
|
|
#using scripts\shared\hostmigration_shared;
|
|
#using scripts\shared\hud_util_shared;
|
|
#using scripts\shared\math_shared;
|
|
#using scripts\shared\scoreevents_shared;
|
|
#using scripts\shared\sound_shared;
|
|
#using scripts\shared\util_shared;
|
|
#using scripts\shared\abilities\_ability_util;
|
|
|
|
|
|
|
|
#using scripts\mp\gametypes\_globallogic;
|
|
#using scripts\mp\gametypes\_globallogic_audio;
|
|
#using scripts\mp\gametypes\_globallogic_score;
|
|
#using scripts\mp\gametypes\_globallogic_spawn;
|
|
#using scripts\mp\gametypes\_globallogic_ui;
|
|
#using scripts\mp\gametypes\_loadout;
|
|
#using scripts\mp\gametypes\_spawning;
|
|
#using scripts\mp\gametypes\_spawnlogic;
|
|
#using scripts\mp\gametypes\_spectating;
|
|
#using scripts\mp\gametypes\_wager;
|
|
|
|
#using scripts\mp\bots\_bot;
|
|
|
|
#using scripts\mp\_teamops;
|
|
#using scripts\mp\_util;
|
|
#using scripts\mp\teams\_teams;
|
|
|
|
/*
|
|
Infect - Infected
|
|
Attackers objective: Infect all Defenders
|
|
Defenders objective: Kill / Avoid Attackers and survive until time limit is reached
|
|
Respawning: No wait / Near teammates for Attackers, Defenders immediately respawned as Attackers when killed
|
|
*/
|
|
|
|
#precache( "string", "OBJECTIVES_INFECT" );
|
|
#precache( "string", "OBJECTIVES_INFECT_HINT" );
|
|
#precache( "string", "MP_DRAFT_STARTS_IN" );
|
|
#precache( "string", "MP_GOT_INFECTED" );
|
|
#precache( "string", "MPUI_INFECTED" );
|
|
#precache( "string", "MPUI_SURVIVORS" );
|
|
#precache( "string", "MP_SURVIVORS_ELIMINATED" );
|
|
#precache( "string", "MP_INFECTED_ELIMINATED" );
|
|
#precache( "string", "MP_INFECTED_TIME_EXTENDED" );
|
|
|
|
function main()
|
|
{
|
|
globallogic::init();
|
|
|
|
level.isInfectMode = true;
|
|
|
|
level.weapon_FIRST_INFECTED_PRIMARY_WEAPON = GetWeapon( "pistol_standard" );
|
|
level.weapon_INFECTED_PRIMARY_WEAPON = GetWeapon( "melee_boneglass" );
|
|
level.weapon_INFECTED_PRIMARY_GRENADE_WEAPON = GetWeapon( "hatchet" );
|
|
|
|
util::registerRoundSwitch( 0, 9 );
|
|
util::registerTimeLimit( 0, 1440 );
|
|
util::registerScoreLimit( 0, 50000 );
|
|
util::registerRoundLimit( 0, 10 );
|
|
util::registerRoundWinLimit( 0, 10 );
|
|
util::registerNumLives( 0, 100 );
|
|
|
|
globallogic::registerFriendlyFireDelay( level.gameType, 15, 0, 1440 );
|
|
|
|
level.scoreRoundWinBased = ( GetGametypeSetting( "cumulativeRoundScores" ) == false );
|
|
level.teamScorePerKill = GetGametypeSetting( "teamScorePerKill" );
|
|
level.teamScorePerDeath = GetGametypeSetting( "teamScorePerDeath" );
|
|
level.teamScorePerHeadshot = GetGametypeSetting( "teamScorePerHeadshot" );
|
|
level.teamBased = true;
|
|
level.overrideTeamScore = true;
|
|
level.onStartGameType =&onStartGameType;
|
|
level.onEndGame = &onEndGame;
|
|
level.onSpawnPlayer =&onSpawnPlayer;
|
|
level.onRoundEndGame =&onRoundEndGame;
|
|
level.onRoundSwitch =&onRoundSwitch;
|
|
level.onPlayerKilled =&onPlayerKilled;
|
|
level.playerGetWeaponScavengeAmmo = &playerGetWeaponScavengeAmmo;
|
|
level.getTimeLimit = &getTimeLimit;
|
|
level.gameModeWeaponDropped = &weaponDropped;
|
|
// level.gametypeRoundEndScoreHud =&gametypeRoundEndScoreHud;
|
|
// level.onCloneSelectWeapon = &onCloneSelectWeapon;
|
|
|
|
callback::on_connect( &onPlayerConnect );
|
|
callback::on_disconnect( &onPlayerDisconnect );
|
|
callback::on_joined_team( &onPlayerJoinedTeam );
|
|
callback::on_joined_spectate( &onPlayerJoinedSpectate );
|
|
|
|
gameobjects::register_allowed_gameobject( level.gameType );
|
|
|
|
// globallogic_audio::set_leader_gametype_dialog ( "startTeamDeathmatch", "hcStartTeamDeathmatch", "gameBoost", "gameBoost" );
|
|
|
|
// Sets the scoreboard columns and determines with data is sent across the network
|
|
if ( !SessionModeIsSystemlink() && !SessionModeIsOnlineGame() && IsSplitScreen() )
|
|
// local matches only show the first three columns
|
|
globallogic::setvisiblescoreboardcolumns( "score", "kills", "infects", "deaths", "assists" );
|
|
else
|
|
globallogic::setvisiblescoreboardcolumns( "score", "kills", "deaths", "infects", "assists" );
|
|
|
|
level.giveCustomLoadout =&giveCustomLoadout;
|
|
level.getAutoAssignTeamName = &getAutoAssignTeamName;
|
|
level.onTimeLimit =&onTimeLimit;
|
|
level.mayDropWeapon = &mayDropWeapon;
|
|
|
|
infect_perks = [];
|
|
if ( !isdefined( infect_perks ) ) infect_perks = []; else if ( !IsArray( infect_perks ) ) infect_perks = array( infect_perks ); infect_perks[infect_perks.size]="specialty_longersprint";;
|
|
if ( !isdefined( infect_perks ) ) infect_perks = []; else if ( !IsArray( infect_perks ) ) infect_perks = array( infect_perks ); infect_perks[infect_perks.size]="specialty_quieter";;
|
|
if ( !isdefined( infect_perks ) ) infect_perks = []; else if ( !IsArray( infect_perks ) ) infect_perks = array( infect_perks ); infect_perks[infect_perks.size]="specialty_loudenemies";;
|
|
if ( !isdefined( infect_perks ) ) infect_perks = []; else if ( !IsArray( infect_perks ) ) infect_perks = array( infect_perks ); infect_perks[infect_perks.size]="specialty_movefaster";;
|
|
if ( !isdefined( infect_perks ) ) infect_perks = []; else if ( !IsArray( infect_perks ) ) infect_perks = array( infect_perks ); infect_perks[infect_perks.size]="specialty_jetnoradar";;
|
|
if ( !isdefined( infect_perks ) ) infect_perks = []; else if ( !IsArray( infect_perks ) ) infect_perks = array( infect_perks ); infect_perks[infect_perks.size]="specialty_jetquiet";;
|
|
if ( !isdefined( infect_perks ) ) infect_perks = []; else if ( !IsArray( infect_perks ) ) infect_perks = array( infect_perks ); infect_perks[infect_perks.size]="specialty_fallheight";;
|
|
if ( !isdefined( infect_perks ) ) infect_perks = []; else if ( !IsArray( infect_perks ) ) infect_perks = array( infect_perks ); infect_perks[infect_perks.size]="specialty_fastladderclimb";;
|
|
if ( !isdefined( infect_perks ) ) infect_perks = []; else if ( !IsArray( infect_perks ) ) infect_perks = array( infect_perks ); infect_perks[infect_perks.size]="specialty_fastmantle";;
|
|
if ( !isdefined( infect_perks ) ) infect_perks = []; else if ( !IsArray( infect_perks ) ) infect_perks = array( infect_perks ); infect_perks[infect_perks.size]="specialty_fastreload";;
|
|
if ( !isdefined( infect_perks ) ) infect_perks = []; else if ( !IsArray( infect_perks ) ) infect_perks = array( infect_perks ); infect_perks[infect_perks.size]="specialty_detectexplosive";;
|
|
if ( !isdefined( infect_perks ) ) infect_perks = []; else if ( !IsArray( infect_perks ) ) infect_perks = array( infect_perks ); infect_perks[infect_perks.size]="specialty_bulletaccuracy";;
|
|
if ( !isdefined( infect_perks ) ) infect_perks = []; else if ( !IsArray( infect_perks ) ) infect_perks = array( infect_perks ); infect_perks[infect_perks.size]="specialty_stalker";;
|
|
if ( !isdefined( infect_perks ) ) infect_perks = []; else if ( !IsArray( infect_perks ) ) infect_perks = array( infect_perks ); infect_perks[infect_perks.size]="specialty_jetcharger";;
|
|
if ( !isdefined( infect_perks ) ) infect_perks = []; else if ( !IsArray( infect_perks ) ) infect_perks = array( infect_perks ); infect_perks[infect_perks.size]="specialty_overcharge";;
|
|
level.infect_perks = infect_perks;
|
|
|
|
infect_gadgets = [];
|
|
if ( !isdefined( infect_gadgets ) ) infect_gadgets = []; else if ( !IsArray( infect_gadgets ) ) infect_gadgets = array( infect_gadgets ); infect_gadgets[infect_gadgets.size]="gadget_camo";;
|
|
if ( !isdefined( infect_gadgets ) ) infect_gadgets = []; else if ( !IsArray( infect_gadgets ) ) infect_gadgets = array( infect_gadgets ); infect_gadgets[infect_gadgets.size]="gadget_clone";;
|
|
if ( !isdefined( infect_gadgets ) ) infect_gadgets = []; else if ( !IsArray( infect_gadgets ) ) infect_gadgets = array( infect_gadgets ); infect_gadgets[infect_gadgets.size]="gadget_armor";;
|
|
level.infect_gadgets = infect_gadgets;
|
|
}
|
|
|
|
function onStartGameType()
|
|
{
|
|
setClientNameMode("auto_change");
|
|
|
|
game["defenders"] = "allies";
|
|
game["attackers"] = "axis";
|
|
|
|
if ( !IsDefined( game["switchedsides"] ) )
|
|
game["switchedsides"] = false;
|
|
|
|
if ( game["switchedsides"] )
|
|
{
|
|
oldAttackers = game["attackers"];
|
|
oldDefenders = game["defenders"];
|
|
game["attackers"] = oldDefenders;
|
|
game["defenders"] = oldAttackers;
|
|
}
|
|
|
|
// setCustomTeamNames();
|
|
|
|
level.displayRoundEndText = false;
|
|
|
|
// now that the game objects have been deleted place the influencers
|
|
spawning::create_map_placed_influencers();
|
|
|
|
level.spawnMins = ( 0, 0, 0 );
|
|
level.spawnMaxs = ( 0, 0, 0 );
|
|
|
|
foreach ( team in level.teams )
|
|
{
|
|
util::setObjectiveText( team, &"OBJECTIVES_INFECT" );
|
|
util::setObjectiveHintText( team, &"OBJECTIVES_INFECT_HINT" );
|
|
util::setObjectiveScoreText( team, &"OBJECTIVES_INFECT" );
|
|
|
|
spawnlogic::add_spawn_points( team, "mp_tdm_spawn" );
|
|
spawnlogic::place_spawn_points( spawning::getTDMStartSpawnName(team) );
|
|
}
|
|
|
|
spawning::updateAllSpawnPoints();
|
|
|
|
level.spawn_start = [];
|
|
|
|
foreach ( team in level.teams )
|
|
{
|
|
level.spawn_start[ team ] = spawnlogic::get_spawnpoint_array( spawning::getTDMStartSpawnName(team) );
|
|
}
|
|
|
|
level.mapCenter = math::find_box_center( level.spawnMins, level.spawnMaxs );
|
|
setMapCenter( level.mapCenter );
|
|
|
|
spawnpoint = spawnlogic::get_random_intermission_point();
|
|
setDemoIntermissionPoint( spawnpoint.origin, spawnpoint.angles );
|
|
|
|
if ( !util::isOneRound() )
|
|
{
|
|
level.displayRoundEndText = true;
|
|
if( level.scoreRoundWinBased )
|
|
{
|
|
globallogic_score::resetTeamScores();
|
|
}
|
|
}
|
|
|
|
level.infect_choseFirstInfected = false;
|
|
level.infect_choosingFirstInfected = false;
|
|
level.infect_allowSuicide = false;
|
|
level.infect_awardedFinalSurvivor = false;
|
|
|
|
level.infect_players = [];
|
|
|
|
initHud();
|
|
|
|
/# level thread devgui_infect(); #/
|
|
|
|
// gametype is user-facing as FFA so we need to use FFA bot-population logic
|
|
maxFree = GetDvarInt( "bot_maxFree", 0 );
|
|
level thread bot::monitor_bot_population( maxFree );
|
|
|
|
level thread abortedCountdownCleanup();
|
|
level thread timeExtendedCleanup();
|
|
}
|
|
|
|
function setCustomTeamNames()
|
|
{
|
|
setTeamCustomName( game["attackers"], "MPUI_INFECTED" );
|
|
setTeamCustomName( game["defenders"], "MPUI_SURVIVORS" );
|
|
}
|
|
|
|
function setTeamCustomName( team, name )
|
|
{
|
|
customTeamDvar = "g_customTeamName_" + team;
|
|
if ( GetDvarString( customTeamDvar ) == "" )
|
|
{
|
|
SetDvar( customTeamDvar, name );
|
|
}
|
|
}
|
|
|
|
function onEndGame( winningTeam )
|
|
{
|
|
if ( !util::isOneRound() && !util::isLastRound() )
|
|
{
|
|
// give a win/loss for each round played
|
|
infectUpdateWinLossStats( winningTeam );
|
|
}
|
|
}
|
|
|
|
function infectUpdateWinLossStats( winningTeam )
|
|
{
|
|
players = level.players;
|
|
|
|
for ( i = 0; i < players.size; i++ )
|
|
{
|
|
if ( !isdefined( players[i].pers["team"] ) )
|
|
continue;
|
|
|
|
if ( level.hostForcedEnd && players[i] IsHost() )
|
|
continue;
|
|
|
|
if ( winningTeam == "tie" )
|
|
globallogic_score::updateTieStats( players[i] );
|
|
else if ( players[i].pers["team"] == winningTeam )
|
|
globallogic_score::updateWinStats( players[i] );
|
|
else
|
|
{
|
|
// need to add condition for arena late join loss prevention
|
|
if ( level.rankedMatch && !level.leagueMatch && ( players[i].pers["lateJoin"] === true ) )
|
|
{
|
|
globallogic_score::updateLossLateJoinStats( players[i] );
|
|
}
|
|
|
|
if ( !level.disableStatTracking )
|
|
{
|
|
players[i] SetDStat( "playerstatslist", "cur_win_streak", "StatValue", 0 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function initHud()
|
|
{
|
|
level.infect_timerDisplay = hud::createServerTimer( "objective", 1.5 );
|
|
level.infect_timerDisplay hud::setPoint( "CENTER", undefined, 0, 50 );
|
|
level.infect_timerDisplay.label = &"MP_DRAFT_STARTS_IN";
|
|
level.infect_timerDisplay.alpha = 0;
|
|
level.infect_timerDisplay.archived = false;
|
|
level.infect_timerDisplay.hideWhenInMenu = true;
|
|
|
|
level.infect_timeExtendedDisplay = hud::createServerFontString( "objective", 1.5 );
|
|
level.infect_timeExtendedDisplay hud::setPoint( "CENTER", undefined, 0, 50 );
|
|
level.infect_timeExtendedDisplay.label = &"MP_INFECTED_TIME_EXTENDED";
|
|
level.infect_timeExtendedDisplay.alpha = 0;
|
|
level.infect_timeExtendedDisplay.archived = false;
|
|
level.infect_timeExtendedDisplay.hideWhenInMenu = true;
|
|
}
|
|
|
|
function onPlayerConnect()
|
|
{
|
|
self.infect_firstSpawn = true;
|
|
self.infect_joinedAtStart = level.inPrematchPeriod;
|
|
|
|
if ( self.sessionteam != "spectator" )
|
|
{
|
|
self.pers["needteam"] = 1;
|
|
}
|
|
|
|
playerXuid = self GetXUID();
|
|
if ( IsDefined( level.infect_players[playerXuid] ) )
|
|
{
|
|
self.infect_rejoined = true;
|
|
}
|
|
|
|
self.noDrowning = true;
|
|
}
|
|
|
|
function onPlayerJoinedTeam()
|
|
{
|
|
if ( self.team == game["attackers"] )
|
|
{
|
|
self.disableClassSelection = true;
|
|
}
|
|
else
|
|
{
|
|
self.disableClassSelection = undefined;
|
|
}
|
|
}
|
|
|
|
function getAutoAssignTeamName( player, comingFromMenu )
|
|
{
|
|
if ( !comingFromMenu && player.sessionteam == "spectator" )
|
|
{
|
|
teamName = "spectator";
|
|
}
|
|
else if ( ( isdefined( level.infect_forceAssignDefender ) && level.infect_forceAssignDefender ) )
|
|
{
|
|
level.infect_forceAssignDefender = undefined;
|
|
teamName = game["defenders"];
|
|
level thread delayedForceSpawnDefenders();
|
|
}
|
|
else if ( ( isdefined( player.infect_rejoined ) && player.infect_rejoined ) || ( isdefined( level.infect_choseFirstInfected ) && level.infect_choseFirstInfected ) )
|
|
{
|
|
teamName = game["attackers"];
|
|
}
|
|
else
|
|
{
|
|
teamName = game["defenders"];
|
|
}
|
|
|
|
return teamName;
|
|
}
|
|
|
|
function playerWaitForStreamer()
|
|
{
|
|
started_waiting = GetTime();
|
|
|
|
// try to let them finish loading the level
|
|
while ( ( !self isStreamerReady( -1, true ) ) && started_waiting + 90000 > GetTime() )
|
|
{
|
|
{wait(.05);};
|
|
}
|
|
}
|
|
|
|
function onSpawnPlayer(predictedSpawn)
|
|
{
|
|
if ( level.useStartSpawns && !level.inGracePeriod && !level.playerQueuedRespawn )
|
|
{
|
|
level.useStartSpawns = false;
|
|
}
|
|
|
|
updateTeamScores();
|
|
|
|
if ( self.team == game["attackers"] )
|
|
{
|
|
sanitizeInfectedLoadouts();
|
|
}
|
|
|
|
// let the first spawned player kick this off
|
|
if ( !level.infect_choosingFirstInfected )
|
|
{
|
|
level.infect_choosingFirstInfected = true;
|
|
level thread chooseFirstInfected();
|
|
}
|
|
|
|
spawning::onSpawnPlayer(predictedSpawn);
|
|
}
|
|
|
|
function onRoundSwitch()
|
|
{
|
|
game["switchedsides"] = !game["switchedsides"];
|
|
}
|
|
|
|
function onRoundEndGame( roundWinner )
|
|
{
|
|
if ( level.scoreRoundWinBased )
|
|
{
|
|
foreach( team in level.teams )
|
|
{
|
|
[[level._setTeamScore]]( team, game["roundswon"][team] );
|
|
}
|
|
}
|
|
|
|
return [[level.determineWinner]]();
|
|
}
|
|
|
|
function playerHasParticipated()
|
|
{
|
|
return ( self.pers["time_played_moving"] > 0 );
|
|
}
|
|
|
|
function teamCallout( team, calloutMessage, calloutPlayer )
|
|
{
|
|
players = getPlayersOnTeam( team );
|
|
foreach ( player in players )
|
|
{
|
|
player LUINotifyEvent( &"player_callout", 2, calloutMessage, calloutPlayer );
|
|
}
|
|
}
|
|
|
|
function onPlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
|
|
{
|
|
processKill = false;
|
|
wasSuicide = false;
|
|
|
|
if ( self.team == game["defenders"] && IsDefined( attacker ) )
|
|
{
|
|
if ( level.friendlyfire > 0 && isdefined( attacker.team ) && attacker.team == self.team )
|
|
{
|
|
processkill = false;
|
|
}
|
|
else if ( IsPlayer( attacker ) && attacker != self )
|
|
{
|
|
processKill = true;
|
|
}
|
|
else if ( level.infect_allowSuicide && ( attacker == self || !isPlayer( attacker ) ) )
|
|
{
|
|
processKill = true;
|
|
wasSuicide = true;
|
|
}
|
|
}
|
|
|
|
if ( !processKill )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( !wasSuicide )
|
|
{
|
|
// regular attacker reward
|
|
scoreevents::processScoreEvent( "infected_survivor", attacker, self, weapon );
|
|
|
|
if ( isdefined( attacker.pers["infects"] ) )
|
|
{
|
|
attacker.pers["infects"] = attacker.pers["infects"] + 1;
|
|
attacker.infects = attacker.pers["infects"];
|
|
}
|
|
attacker AddPlayerStatWithGameType( "INFECTS", 1 );
|
|
}
|
|
|
|
level thread handlePlayerDeath( self, wasSuicide );
|
|
}
|
|
|
|
function handlePlayerDeath( victim, wasSuicide )
|
|
{
|
|
level endon( "game_ended" );
|
|
|
|
waittillframeend; // give laststand a chance to kick in
|
|
|
|
if ( isdefined( victim.laststand ) )
|
|
{
|
|
result = victim playerWaitForLastStand();
|
|
if ( result === "player_input_revive" )
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
{wait(.05);}; // allows obituary to have expected team colors (i.e. Infected as enemy, Survivor as friendly)
|
|
|
|
if ( IsDefined( victim ) )
|
|
{
|
|
level thread displayTimeExtended();
|
|
switchPlayerToInfectedTeam( victim );
|
|
sanitizeInfectedLoadouts();
|
|
}
|
|
|
|
// generic messages/sounds, and reward survivors
|
|
totalDefenders = [[level._getTeamScore]]( game["defenders"] );
|
|
if ( totalDefenders > 1 && IsDefined( victim ) )
|
|
{
|
|
sound::play_on_players( "mpl_flagget_sting_enemy", game["defenders"] );
|
|
sound::play_on_players( "mpl_flagget_sting_friend", game["attackers"] );
|
|
|
|
teamCallout( game["defenders"], &"MP_GOT_INFECTED", victim.entnum );
|
|
|
|
if ( !wasSuicide )
|
|
{
|
|
teamCallout( game["attackers"], &"SCORE_INFECTED_SURVIVOR", victim.entnum );
|
|
|
|
survivors = getPlayersOnTeam( game["defenders"] );
|
|
foreach ( survivor in survivors )
|
|
{
|
|
if ( survivor != victim && survivor playerHasParticipated() )
|
|
{
|
|
survivor scoreevents::processScoreEvent( "survivor_still_alive", survivor );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// inform/reward last
|
|
else if ( totalDefenders == 1 )
|
|
{
|
|
onFinalSurvivor();
|
|
}
|
|
// infected win
|
|
else if ( totalDefenders == 0 )
|
|
{
|
|
onSurvivorsEliminated();
|
|
}
|
|
}
|
|
|
|
function playerWaitForLastStand()
|
|
{
|
|
level endon( "game_ended" );
|
|
self endon( "disconnect" );
|
|
|
|
return self util::waittill_any_return( "player_input_revive", "death" );
|
|
}
|
|
|
|
function onFinalSurvivor()
|
|
{
|
|
if ( ( isdefined( level.infect_announcedFinalSurvivor ) && level.infect_announcedFinalSurvivor ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
sound::play_on_players( "mpl_ballreturn_sting" );
|
|
|
|
finalSurvivor = getPlayersOnTeam( game["defenders"] )[0];
|
|
|
|
if ( !level.infect_awardedFinalSurvivor )
|
|
{
|
|
finalSurvivor playerFullyChargeHeroWeapon();
|
|
|
|
if ( finalSurvivor.infect_joinedAtStart && finalSurvivor playerHasParticipated() )
|
|
{
|
|
finalSurvivor scoreevents::processScoreEvent( "final_survivor", finalSurvivor );
|
|
}
|
|
level.infect_awardedFinalSurvivor = true;
|
|
}
|
|
|
|
LUINotifyEvent( &"player_callout", 2, &"SCORE_FINAL_SURVIVOR", finalSurvivor.entnum );
|
|
|
|
doFinalSurvivorUAV = GetDvarInt( "scr_infect_finaluav" );
|
|
if ( doFinalSurvivorUAV )
|
|
{
|
|
level thread finalSurvivorUAV( finalSurvivor );
|
|
}
|
|
|
|
level.infect_announcedFinalSurvivor = true;
|
|
}
|
|
|
|
function playerFullyChargeHeroWeapon()
|
|
{
|
|
if ( !IsDefined( self.heroWeapon ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
heroWeaponSlot = self GadgetGetSlot( self.heroWeapon );
|
|
if ( self GadgetIsReady( heroWeaponSlot ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
self GadgetPowerSet( heroWeaponSlot, 100.0 );
|
|
}
|
|
|
|
function finalSurvivorUAV( finalSurvivor )
|
|
{
|
|
level endon( "game_ended" );
|
|
finalSurvivor endon( "disconnect" );
|
|
finalSurvivor endon( "death" );
|
|
level endon( "infect_lateJoiner" );
|
|
level thread endUAVonLateJoiner( finalSurvivor );
|
|
|
|
SetTeamSpyplane( game["attackers"], 1 );
|
|
util::set_team_radar( game["attackers"], 1 );
|
|
removeUAV = false;
|
|
|
|
while ( true )
|
|
{
|
|
prevPos = finalSurvivor.origin;
|
|
|
|
wait( 4.0 );
|
|
|
|
if ( removeUAV )
|
|
{
|
|
SetTeamSpyplane( game["attackers"], 0 );
|
|
util::set_team_radar( game["attackers"], 0 );
|
|
removeUAV = false;
|
|
}
|
|
|
|
wait( 6.0 );
|
|
|
|
if ( DistanceSquared( prevPos, finalSurvivor.origin ) < ( (200) * (200) ) )
|
|
{
|
|
SetTeamSpyplane( game["attackers"], 1 );
|
|
util::set_team_radar( game["attackers"], 1 );
|
|
removeUAV = true;
|
|
|
|
foreach ( player in level.players )
|
|
{
|
|
sound::play_on_players( "fly_hunter_raise_plr" );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function endUAVonLateJoiner( finalSurvivor )
|
|
{
|
|
level endon( "game_ended" );
|
|
finalSurvivor endon( "disconnect" );
|
|
finalSurvivor endon( "death" );
|
|
|
|
while( true )
|
|
{
|
|
totalDefenders = [[level._getTeamScore]]( game["defenders"] );
|
|
if ( totalDefenders > 1 )
|
|
{
|
|
level notify( "infect_lateJoiner" );
|
|
{wait(.05);};
|
|
SetTeamSpyplane( game["attackers"], 1 );
|
|
util::set_team_radar( game["attackers"], 1 );
|
|
break;
|
|
}
|
|
{wait(.05);};
|
|
}
|
|
}
|
|
|
|
function onTimeLimit()
|
|
{
|
|
winner = game["defenders"];
|
|
level thread endGame( winner, game["strings"]["time_limit_reached"] );
|
|
}
|
|
|
|
function onSurvivorsEliminated()
|
|
{
|
|
updateTeamScores();
|
|
|
|
winner = game["attackers"];
|
|
loser = util::getOtherTeam( winner );
|
|
level thread endGame( winner, game["strings"][loser + "_eliminated"] );
|
|
}
|
|
|
|
function endGame( winner, endReasonText )
|
|
{
|
|
if ( ( isdefined( level.infect_gameEnded ) && level.infect_gameEnded ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
level.infect_gameEnded = true;
|
|
|
|
util::wait_network_frame(); // give final player a chance to switch teams in native
|
|
|
|
globallogic::endGame( winner, endReasonText );
|
|
}
|
|
|
|
function onPlayerJoinedSpectate()
|
|
{
|
|
checkTeamStates();
|
|
}
|
|
|
|
function onPlayerDisconnect()
|
|
{
|
|
checkTeamStates();
|
|
}
|
|
|
|
function checkTeamStates()
|
|
{
|
|
if ( ( isdefined( level.gameEnded ) && level.gameEnded ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
updateTeamScores();
|
|
|
|
totalAttackers = [[level._getTeamScore]]( game["attackers"] );
|
|
totalDefenders = [[level._getTeamScore]]( game["defenders"] );
|
|
|
|
// team actions or win condition necessary?
|
|
if ( isDefined( self.infect_isBeingChosen ) || level.infect_choseFirstInfected )
|
|
{
|
|
if ( totalAttackers > 0 && totalDefenders > 0 )
|
|
{
|
|
if ( totalDefenders == 1 )
|
|
{
|
|
// final survivor was abandoned: inform, reward, call uav
|
|
onFinalSurvivor();
|
|
}
|
|
}
|
|
else if ( totalDefenders == 0 )
|
|
{
|
|
// no more survivors, infected win
|
|
onSurvivorsEliminated();
|
|
}
|
|
else if ( totalAttackers == 0 )
|
|
{
|
|
if ( totalDefenders == 1 )
|
|
{
|
|
// last survivor wins
|
|
winner = game["defenders"];
|
|
loser = util::getOtherTeam( winner );
|
|
level thread endGame( winner, game["strings"][loser + "_eliminated"] );
|
|
}
|
|
else if ( totalDefenders > 1 )
|
|
{
|
|
// pick a new infected and keep the game going
|
|
level.infect_choseFirstInfected = false;
|
|
level thread chooseFirstInfected();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
activeDefenders = getActivePlayersOnTeam( game["defenders"] );
|
|
if ( activeDefenders.size < 1 )
|
|
{
|
|
level notify( "infect_stopCountdown" );
|
|
}
|
|
}
|
|
}
|
|
|
|
function giveCustomLoadout( takeAllWeapons, alreadySpawned )
|
|
{
|
|
if ( self.team == game["attackers"] )
|
|
{
|
|
self giveInfectedLoadout();
|
|
self.movementSpeedModifier = 1.2;
|
|
}
|
|
else if ( self.team == game["defenders"] )
|
|
{
|
|
self giveWeaponClassLoadout();
|
|
self.movementSpeedModifier = undefined;
|
|
}
|
|
|
|
return self.spawnWeapon;
|
|
}
|
|
|
|
// direct copy of non-giveCustomLoadout block from loadout::giveLoadout to avoid invasive changes to _loadout.gsc
|
|
function giveWeaponClassLoadout()
|
|
{
|
|
loadout::giveLoadout_init( true );
|
|
|
|
loadout::setClassNum( self.curClass );
|
|
|
|
self SetActionSlot( 3, "altMode" );
|
|
self SetActionSlot( 4, "" );
|
|
|
|
allocationSpent = self GetLoadoutAllocation( self.class_num );
|
|
overAllocation = ( allocationSpent > level.maxAllocation );
|
|
|
|
if ( !overAllocation )
|
|
{
|
|
//Perks must come first in case other give-functions check for perks
|
|
givePerks();
|
|
|
|
loadout::giveWeapons();
|
|
loadout::givePrimaryOffhand();
|
|
}
|
|
else
|
|
{
|
|
loadout::giveBaseWeapon();
|
|
}
|
|
|
|
loadout::giveSecondaryOffhand();
|
|
|
|
if ( GetDvarint( "tu11_enableClassicMode") == 0 )
|
|
{
|
|
loadout::giveSpecialOffhand();
|
|
loadout::giveHeroWeapon();
|
|
}
|
|
|
|
loadout::giveKillStreaks();
|
|
}
|
|
|
|
function givePerks()
|
|
{
|
|
self.specialty = self GetLoadoutPerks( self.class_num );
|
|
|
|
if ( level.leagueMatch )
|
|
{
|
|
for ( i = 0; i < self.specialty.size; i++ )
|
|
{
|
|
if ( loadout::isLeagueItemRestricted( self.specialty[i] ) )
|
|
{
|
|
ArrayRemoveIndex( self.specialty, i );
|
|
i--;
|
|
}
|
|
}
|
|
}
|
|
|
|
// re-registering perks to code since perks are cleared after respawn in case if players switch classes
|
|
self loadout::register_perks();
|
|
|
|
// now that perks are re-registered...
|
|
// update player momentum taking into account anteup perk; any score less than the initial value is boosted to that value
|
|
anteup_bonus = GetDvarInt( "perk_killstreakAnteUpResetValue" );
|
|
momentum_at_spawn_or_game_end = (isdefined(self.pers["momentum_at_spawn_or_game_end"])?self.pers["momentum_at_spawn_or_game_end"]:0);
|
|
hasNotDoneCombat = !( self.hasDoneCombat === true ); // fixes dev gui bot spawning in grace period
|
|
if ( ( level.inPreMatchPeriod || ( level.inGracePeriod && hasNotDoneCombat ) ) && momentum_at_spawn_or_game_end < anteup_bonus )
|
|
{
|
|
new_momentum = ( self HasPerk( "specialty_anteup" ) ? anteup_bonus : momentum_at_spawn_or_game_end );
|
|
globallogic_score::_setPlayerMomentum( self, new_momentum, false );
|
|
}
|
|
}
|
|
|
|
|
|
function giveInfectedLoadout()
|
|
{
|
|
self loadout::giveLoadout_init( true );
|
|
|
|
loadout::setClassNum( self.curClass );
|
|
|
|
self ClearPerks();
|
|
foreach ( perkName in level.infect_perks )
|
|
{
|
|
if ( !self HasPerk( perkName ) )
|
|
{
|
|
self SetPerk( perkName );
|
|
}
|
|
}
|
|
|
|
totalAttackers = [[level._getTeamScore]]( game["attackers"] );
|
|
if ( totalAttackers == 1 )
|
|
{
|
|
defaultWeapon = level.weapon_FIRST_INFECTED_PRIMARY_WEAPON;
|
|
}
|
|
else
|
|
{
|
|
defaultWeapon = level.weapon_INFECTED_PRIMARY_WEAPON;
|
|
}
|
|
self playerInfectedGivePrimaryWeapon( defaultWeapon );
|
|
self SwitchToWeapon( defaultWeapon );
|
|
self SetSpawnWeapon( defaultWeapon );
|
|
self.spawnWeapon = defaultWeapon;
|
|
|
|
primaryOffhand = level.weapon_INFECTED_PRIMARY_GRENADE_WEAPON;
|
|
primaryOffhandCount = 1;
|
|
self GiveWeapon( primaryOffhand );
|
|
self SetWeaponAmmoStock( primaryOffhand, primaryOffhandCount );
|
|
self SwitchToOffhand( primaryOffhand );
|
|
self.grenadeTypePrimary = primaryOffhand;
|
|
self.grenadeTypePrimaryCount = primaryOffhandCount;
|
|
|
|
secondaryOffhand = GetWeapon( "null_offhand_secondary" );
|
|
secondaryOffhandCount = 0;
|
|
self GiveWeapon( secondaryOffhand );
|
|
self SetWeaponAmmoClip( secondaryOffhand, secondaryOffhandCount );
|
|
self SwitchToOffhand( secondaryOffhand );
|
|
self.grenadeTypeSecondary = secondaryOffhand;
|
|
self.grenadeTypeSecondaryCount = secondaryOffhandCount;
|
|
|
|
self GiveWeapon( level.weaponBaseMelee );
|
|
|
|
giveRandomGadget();
|
|
|
|
self.heroWeapon = undefined;
|
|
}
|
|
|
|
function giveRandomGadget()
|
|
{
|
|
specialOffhand = self.infect_randomGadget;
|
|
resetCharge = false;
|
|
|
|
if ( !isdefined( specialOffhand ) )
|
|
{
|
|
randomGadget = array::random( level.infect_gadgets );
|
|
specialOffhand = GetWeapon( randomGadget );
|
|
resetCharge = true;
|
|
}
|
|
|
|
specialOffhandCount = specialOffhand.startammo;
|
|
self GiveWeapon( specialOffhand );
|
|
|
|
self SetWeaponAmmoClip( specialOffhand, specialOffhandCount );
|
|
self SwitchToOffhand( specialOffhand );
|
|
self.grenadeTypeSpecial = specialOffhand;
|
|
self.grenadeTypeSpecialCount = specialOffhandCount;
|
|
|
|
if ( ( isdefined( resetCharge ) && resetCharge ) )
|
|
{
|
|
slot = self GadgetGetSlot( specialOffhand );
|
|
self GadgetPowerReset( slot );
|
|
}
|
|
|
|
self.infect_randomGadget = specialOffhand;
|
|
}
|
|
|
|
function chooseFirstInfected()
|
|
{
|
|
level endon( "game_ended" );
|
|
level endon( "infect_stopCountdown" );
|
|
|
|
// no suicides
|
|
level.infect_allowSuicide = false;
|
|
|
|
level.lastInfectionTime = undefined;
|
|
|
|
if ( level.inPrematchPeriod )
|
|
{
|
|
level waittill( "prematch_over" );
|
|
}
|
|
|
|
level.infect_timerDisplay.label = &"MP_DRAFT_STARTS_IN";
|
|
level.infect_timerDisplay setTimer( 8 );
|
|
level.infect_timerDisplay.alpha = 1;
|
|
|
|
hostmigration::waitLongDurationWithHostMigrationPause( 8.0 );
|
|
|
|
level.infect_timerDisplay.alpha = 0;
|
|
|
|
activeDefenders = getActivePlayersOnTeam( game["defenders"] );
|
|
if ( activeDefenders.size > 0 )
|
|
{
|
|
activeDefenders[GetArrayKeys(activeDefenders)[RandomInt(GetArrayKeys(activeDefenders).size)]] setFirstInfected();
|
|
}
|
|
else
|
|
{
|
|
level.infect_choosingFirstInfected = false;
|
|
}
|
|
}
|
|
|
|
function abortedCountdownCleanup()
|
|
{
|
|
while ( true )
|
|
{
|
|
event = level util::waittill_any_return( "game_ended", "infect_stopCountdown" );
|
|
|
|
if ( isdefined( level.infect_timerDisplay ) )
|
|
{
|
|
level.infect_timerDisplay.alpha = 0;
|
|
}
|
|
|
|
if ( event == "game_ended" )
|
|
{
|
|
return;
|
|
}
|
|
|
|
level.infect_choosingFirstInfected = false;
|
|
}
|
|
}
|
|
|
|
function displayTimeExtended()
|
|
{
|
|
level notify( "timeExtended" );
|
|
|
|
level endon( "game_ended" );
|
|
level endon( "infect_stopTimeExtended" );
|
|
level endon( "timeExtended" );
|
|
|
|
timeout = 0;
|
|
|
|
while( isDefined( level.infect_timerDisplay ) && level.infect_timerDisplay.alpha > 0 )
|
|
{
|
|
hostmigration::waitLongDurationWithHostMigrationPause( 0.5 );
|
|
timeout++;
|
|
|
|
if( timeout == 20 )
|
|
return;
|
|
}
|
|
|
|
level.infect_timeExtendedDisplay.alpha = 1;
|
|
|
|
hostmigration::waitLongDurationWithHostMigrationPause( 1.0 );
|
|
|
|
level.infect_timeExtendedDisplay FadeOverTime( 2 );
|
|
|
|
level.infect_timeExtendedDisplay.alpha = 0;
|
|
}
|
|
|
|
function timeExtendedCleanup()
|
|
{
|
|
while ( true )
|
|
{
|
|
event = level util::waittill_any_return( "game_ended", "infect_stopTimeExtended" );
|
|
|
|
if ( isdefined( level.infect_timeExtendedDisplay ) )
|
|
{
|
|
level.infect_timeExtendedDisplay.alpha = 0;
|
|
}
|
|
|
|
if ( event == "game_ended" )
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
function getActivePlayersOnTeam( team )
|
|
{
|
|
activePlayers = [];
|
|
|
|
teamPlayers = getPlayersOnTeam( team );
|
|
foreach ( player in teamPlayers )
|
|
{
|
|
if ( player.sessionstate == "spectator" )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( !isdefined( activePlayers ) ) activePlayers = []; else if ( !IsArray( activePlayers ) ) activePlayers = array( activePlayers ); activePlayers[activePlayers.size]=player;;
|
|
}
|
|
|
|
return activePlayers;
|
|
}
|
|
|
|
function setFirstInfected()
|
|
{
|
|
self endon( "disconnect" );
|
|
|
|
self.infect_isBeingChosen = true;
|
|
|
|
// wait alive
|
|
while( !IsAlive( self ) || self util::isUsingRemote() )
|
|
{wait(.05);};
|
|
|
|
// remove placement item if carrying
|
|
if ( ( isdefined( self.isCarrying ) && self.isCarrying ) )
|
|
{
|
|
self notify( "force_cancel_placement" );
|
|
{wait(.05);};
|
|
}
|
|
|
|
// not while mantling
|
|
while ( self IsMantling() )
|
|
{wait(.05);};
|
|
|
|
// not while in air
|
|
while ( !self IsOnGround() && !self IsOnLadder() )
|
|
{wait(.05);};
|
|
|
|
switchPlayerToInfectedTeam( self );
|
|
self.switching_teams = undefined; // otherwise first death will be ignored by stats system
|
|
|
|
if ( self IsUsingOffHand() )
|
|
{
|
|
self ForceOffHandEnd();
|
|
}
|
|
self DisableOffhandSpecial(); // circumvents a weapon-flag issue if drafted while cooking an offhand weapon
|
|
self thread playerEnableOffhandAfterWeaponSwitch();
|
|
|
|
loadout::giveLoadout( self.team, self.curClass );
|
|
|
|
totalDefenders = [[level._getTeamScore]]( game["defenders"] );
|
|
if ( totalDefenders < 1 )
|
|
{
|
|
level.infect_forceAssignDefender = true;
|
|
}
|
|
else
|
|
{
|
|
forceSpawnTeam( game["defenders"] );
|
|
}
|
|
|
|
// tell the world!
|
|
LUINotifyEvent( &"player_callout", 2, &"SCORE_FIRST_INFECTED", self.entnum );
|
|
scoreevents::processScoreEvent( "first_infected", self );
|
|
sound::play_on_players( "mpl_flagget_sting_enemy" );
|
|
|
|
level.infect_allowSuicide = true;
|
|
level.infect_choseFirstInfected = true;
|
|
self.infect_isBeingChosen = undefined;
|
|
}
|
|
|
|
function forceSpawnTeam( team )
|
|
{
|
|
players = getPlayersOnTeam( team );
|
|
foreach ( player in players )
|
|
{
|
|
player thread playerForceSpawn();
|
|
}
|
|
}
|
|
|
|
function playerForceSpawn()
|
|
{
|
|
level endon( "game_ended" );
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
self endon( "spawned" );
|
|
|
|
if ( self.hasSpawned )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( self.pers["team"] == "spectator" )
|
|
{
|
|
return;
|
|
}
|
|
|
|
self playerWaitForStreamer();
|
|
|
|
self.pers["class"] = level.defaultClass;
|
|
self.curClass = level.defaultClass;
|
|
|
|
self globallogic_ui::closeMenus();
|
|
self CloseMenu( "ChooseClass_InGame" );
|
|
self thread [[level.spawnClient]]();
|
|
}
|
|
|
|
function switchPlayerToInfectedTeam( player )
|
|
{
|
|
storeInfectedPlayer( player );
|
|
destroyPlayerEquipment( player );
|
|
player changeTeam( game["attackers"] );
|
|
updateTeamScores();
|
|
resetTimeLimit();
|
|
}
|
|
|
|
function playerEnableOffhandAfterWeaponSwitch()
|
|
{
|
|
level endon( "game_ended" );
|
|
self endon( "disconnect" );
|
|
self endon( "death" );
|
|
|
|
self waittill( "weapon_change" );
|
|
|
|
self EnableOffhandSpecial();
|
|
}
|
|
|
|
function storeInfectedPlayer( player )
|
|
{
|
|
playerXuid = player GetXUID();
|
|
level.infect_players[playerXuid] = true;
|
|
}
|
|
|
|
function changeTeam( team )
|
|
{
|
|
if ( self.sessionstate != "dead" )
|
|
{
|
|
// Set a flag on the player to they aren't robbed points for dying - the callback will remove the flag
|
|
self.switching_teams = true;
|
|
self.switchedTeamsResetGadgets = true;
|
|
self.joining_team = team;
|
|
self.leaving_team = self.pers["team"];
|
|
}
|
|
|
|
self.pers["team"] = team;
|
|
self.team = team;
|
|
self.pers["weapon"] = undefined;
|
|
self.pers["spawnweapon"] = undefined;
|
|
self.pers["savedmodel"] = undefined;
|
|
self.pers["teamTime"] = undefined;
|
|
self.sessionteam = self.pers["team"];
|
|
|
|
self globallogic_ui::updateObjectiveText();
|
|
|
|
// update spectator permissions immediately on change of team
|
|
self spectating::set_permissions();
|
|
|
|
self notify("end_respawn");
|
|
}
|
|
|
|
function getPlayersOnTeam( team )
|
|
{
|
|
playersOnTeam = [];
|
|
|
|
foreach ( player in level.players )
|
|
{
|
|
if ( !isdefined( player ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
playerTeam = player.pers[ "team" ];
|
|
if ( IsDefined( playerTeam ) && IsDefined( level.teams[ playerTeam ] ) && playerTeam == team )
|
|
{
|
|
if ( !isdefined( playersOnTeam ) ) playersOnTeam = []; else if ( !IsArray( playersOnTeam ) ) playersOnTeam = array( playersOnTeam ); playersOnTeam[playersOnTeam.size]=player;;
|
|
}
|
|
}
|
|
|
|
return playersOnTeam;
|
|
}
|
|
|
|
function countPlayersOnTeam( team )
|
|
{
|
|
playersOnTeam = getPlayersOnTeam( team );
|
|
return playersOnTeam.size;
|
|
}
|
|
|
|
function updateTeamScores()
|
|
{
|
|
updateTeamScore( game["attackers"] );
|
|
updateTeamScore( game["defenders"] );
|
|
}
|
|
|
|
function updateTeamScore( team )
|
|
{
|
|
score = countPlayersOnTeam( team );
|
|
game["teamScores"][team] = score;
|
|
globallogic_score::updateTeamScores( team );
|
|
}
|
|
|
|
function mayDropWeapon( weapon )
|
|
{
|
|
if ( self.team === game["attackers"] )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function playerInfectedGivePrimaryWeapon( weapon )
|
|
{
|
|
self GiveWeapon( weapon );
|
|
self GiveStartAmmo( weapon );
|
|
self SetBlockWeaponPickup( weapon, true );
|
|
self.infect_primaryWeapon = weapon;
|
|
}
|
|
|
|
function sanitizeInfectedLoadouts()
|
|
{
|
|
attackers = getPlayersOnTeam( game["attackers"] );
|
|
if ( attackers.size < 2 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
foreach ( player in attackers )
|
|
{
|
|
if ( !IsAlive( player ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( player.infect_primaryWeapon !== level.weapon_INFECTED_PRIMARY_WEAPON )
|
|
{
|
|
if ( isdefined( player.infect_primaryWeapon ) )
|
|
{
|
|
player TakeWeapon( player.infect_primaryWeapon );
|
|
}
|
|
|
|
newWeapon = level.weapon_INFECTED_PRIMARY_WEAPON;
|
|
player playerInfectedGivePrimaryWeapon( newWeapon );
|
|
player SwitchToWeapon( newWeapon );
|
|
}
|
|
}
|
|
}
|
|
|
|
function playerGetWeaponScavengeAmmo( weapon, defaultAmmo )
|
|
{
|
|
if ( weapon == self.grenadeTypePrimary || weapon == self.grenadeTypeSecondary )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return defaultAmmo;
|
|
}
|
|
|
|
function resetTimeLimit()
|
|
{
|
|
level.lastInfectionTime = GetTime();
|
|
}
|
|
|
|
function getTimeLimit()
|
|
{
|
|
defaultTimeLimit = GetGametypeSetting( "timeLimit" );
|
|
if ( defaultTimeLimit == 0 )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if ( !isdefined( level.lastInfectionTime ) )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
minutesElapsed = ( ( level.lastInfectionTime - level.startTime + 1000 ) / 60000 );
|
|
timeLimit = minutesElapsed + defaultTimeLimit;
|
|
return timeLimit;
|
|
}
|
|
|
|
function destroyPlayerEquipment( player )
|
|
{
|
|
for ( i = 0; i < level.missileEntities.size; i++ )
|
|
{
|
|
item = level.missileEntities[i];
|
|
|
|
if ( !isdefined( item ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( !isdefined( item.weapon ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( item.owner !== player && item.originalowner !== player )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
item notify( "detonating" );
|
|
if ( isdefined( item ) )
|
|
item Delete();
|
|
}
|
|
}
|
|
|
|
function gametypeRoundEndScoreHud( winner, endType, endReasonText, outcomeText, team, winnerEnum, notifyRoundEndToUI, matchbonus )
|
|
{
|
|
if ( endType == "roundend" )
|
|
{
|
|
if ( winner == "tie" )
|
|
{
|
|
outcomeText = game["strings"]["draw"];
|
|
}
|
|
else if ( isdefined( self.pers["team"] ) && winner == team )
|
|
{
|
|
outcomeText = game["strings"]["victory"];
|
|
overrideSpectator = true;
|
|
}
|
|
else
|
|
{
|
|
outcomeText = game["strings"]["defeat"];
|
|
|
|
if ( ( level.rankedMatch || level.leagueMatch ) && ( self.pers[ "lateJoin" ] === true ) )
|
|
{
|
|
endReasonText = game["strings"]["join_in_progress_loss"];
|
|
}
|
|
|
|
overrideSpectator = true;
|
|
|
|
}
|
|
notifyRoundEndToUI = false;
|
|
|
|
// Codcaster Specific Outcome Override
|
|
if ( team == "spectator" && overrideSpectator )
|
|
{
|
|
// Special case handling of end reason text
|
|
foreach ( team in level.teams )
|
|
{
|
|
if ( endreasontext == game["strings"][team + "_eliminated"] )
|
|
{
|
|
endReasonText = game["strings"]["cod_caster_team_eliminated"];
|
|
break;
|
|
}
|
|
}
|
|
|
|
outcomeText = game["strings"]["cod_caster_team_wins"];
|
|
}
|
|
|
|
self LUINotifyEvent( &"show_outcome", 5, outcomeText, endReasonText, int( matchBonus ), winnerEnum, notifyRoundEndToUI );
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function onCloneSelectWeapon( player )
|
|
{
|
|
if ( player.team === game["attackers"] )
|
|
{
|
|
playerWeapon = player GetCurrentWeapon();
|
|
if ( isdefined( playerWeapon.worldModel ) )
|
|
{
|
|
return playerWeapon;
|
|
}
|
|
}
|
|
|
|
return undefined; // use default logic
|
|
}
|
|
|
|
function delayedForceSpawnDefenders()
|
|
{
|
|
level endon( "game_ended" );
|
|
|
|
level notify( "infect_forcespawn_defenders" );
|
|
level endon( "infect_forcespawn_defenders" );
|
|
|
|
wait( 30 );
|
|
|
|
forceSpawnTeam( game["defenders"] );
|
|
}
|
|
|
|
function weaponDropped( weaponItem )
|
|
{
|
|
weaponItem HideFromTeam( game["attackers"] );
|
|
}
|
|
|
|
/#
|
|
function runDvarHandler( dvarName, commandHandlerFunc )
|
|
{
|
|
SetDvar( dvarName, "" );
|
|
|
|
while ( true )
|
|
{
|
|
{wait(.05);};
|
|
|
|
dvarValue = GetDvarString( dvarName );
|
|
if ( dvarValue == "" )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
SetDvar( dvarName, "" );
|
|
|
|
tokens = StrTok( dvarValue, " " );
|
|
if ( !IsDefined( tokens ) || tokens.size < 1 )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
command = tokens[0];
|
|
ArrayRemoveIndex( tokens, 1 );
|
|
|
|
[[ commandHandlerFunc ]]( command, tokens );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function handleDevCommand( command, args )
|
|
{
|
|
switch ( command )
|
|
{
|
|
case "killall_bots":
|
|
foreach ( player in level.players )
|
|
{
|
|
if ( player util::is_bot() )
|
|
{
|
|
player Kill();
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
function devgui_infect()
|
|
{
|
|
level thread runDvarHandler( "scr_infect_devcmd", &handleDevCommand );
|
|
|
|
level flag::wait_till("all_players_spawned" );
|
|
|
|
devguiRoot = "devgui_cmd \"Infected/";
|
|
|
|
AddDebugCommand( devguiRoot + "Kill All Bots" + "\" \"set " + "scr_infect_devcmd" + " killall_bots\" \n");
|
|
}
|
|
#/
|