#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"); } #/