Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include maps\mp\_utility;
- #include maps\mp\gametypes\_hud_util;
- #include common_scripts\utility;
- TimeUntilWaveSpawn( minimumWait )
- {
- if ( !self.hasSpawned )
- return 0;
- // the time we'll spawn if we only wait the minimum wait.
- earliestSpawnTime = gettime() + minimumWait * 1000;
- lastWaveTime = level.lastWave[self.pers["team"]];
- waveDelay = level.waveDelay[self.pers["team"]] * 1000;
- // the number of waves that will have passed since the last wave happened, when the minimum wait is over.
- numWavesPassedEarliestSpawnTime = (earliestSpawnTime - lastWaveTime) / waveDelay;
- // rounded up
- numWaves = ceil( numWavesPassedEarliestSpawnTime );
- timeOfSpawn = lastWaveTime + numWaves * waveDelay;
- // don't push our spawn out because we watched killcam
- if ( isDefined( self.respawnTimerStartTime ) )
- {
- timeAlreadyPassed = (gettime() - self.respawnTimerStartTime) / 1000.0;
- if ( self.respawnTimerStartTime < lastWaveTime )
- return 0;
- }
- // avoid spawning everyone on the same frame
- if ( isdefined( self.waveSpawnIndex ) )
- timeOfSpawn += 50 * self.waveSpawnIndex;
- return (timeOfSpawn - gettime()) / 1000;
- }
- TeamKillDelay()
- {
- teamKills = self.pers["teamkills"];
- if ( level.maxAllowedTeamKills < 0 || teamkills <= level.maxAllowedTeamKills )
- return 0;
- exceeded = (teamkills - level.maxAllowedTeamKills);
- return maps\mp\gametypes\_tweakables::getTweakableValue( "team", "teamkillspawndelay" ) * exceeded;
- }
- TimeUntilSpawn( includeTeamkillDelay )
- {
- if ( (level.inGracePeriod && !self.hasSpawned) || level.gameended )
- return 0;
- respawnDelay = 0;
- if ( self.hasSpawned )
- {
- result = self [[level.onRespawnDelay]]();
- if ( isDefined( result ) )
- respawnDelay = result;
- else
- respawnDelay = getDvarInt( "scr_" + level.gameType + "_playerrespawndelay" );
- if ( includeTeamkillDelay && self.pers["teamKillPunish"] )
- respawnDelay += TeamKillDelay();
- if ( isDefined( self.respawnTimerStartTime ) )
- {
- timeAlreadyPassed = (gettime() - self.respawnTimerStartTime) / 1000.0;
- respawnDelay -= timeAlreadyPassed;
- if ( respawnDelay < 0 )
- respawnDelay = 0;
- }
- // Spawning with tactical insertion
- if ( isDefined( self.setSpawnPoint) )
- respawnDelay += level.tiSpawnDelay;
- }
- waveBased = (getDvarInt( "scr_" + level.gameType + "_waverespawndelay" ) > 0);
- if ( waveBased )
- return self TimeUntilWaveSpawn( respawnDelay );
- return respawnDelay;
- }
- maySpawn()
- {
- if ( getGametypeNumLives() || isDefined( level.disableSpawning ) )
- {
- if ( isDefined( level.disableSpawning ) && level.disableSpawning )
- return false;
- if ( self.pers["teamKillPunish"] )
- return false;
- if ( !self.pers["lives"] && gameHasStarted() )
- {
- return false;
- }
- else if ( gameHasStarted() )
- {
- // disallow spawning for late comers
- if ( !level.inGracePeriod && !self.hasSpawned )
- return false;
- }
- }
- return true;
- }
- spawnClient()
- {
- assert( isDefined( self.team ) );
- assert( isValidClass( self.class ) );
- if ( !self maySpawn() )
- {
- currentorigin = self.origin;
- currentangles = self.angles;
- self notify ( "attempted_spawn" );
- if ( self.pers["teamKillPunish"] )
- {
- self.pers["teamkills"] = max( self.pers["teamkills"] - 1, 0 );
- setLowerMessage( "friendly_fire", &"MP_FRIENDLY_FIRE_WILL_NOT" );
- if ( !self.hasSpawned && self.pers["teamkills"] <= level.maxAllowedTeamkills )
- self.pers["teamKillPunish"] = false;
- }
- else if ( isRoundBased() && !isLastRound() )
- {
- setLowerMessage( "spawn_info", game["strings"]["spawn_next_round"] );
- self thread removeSpawnMessageShortly( 3.0 );
- }
- self thread spawnSpectator( currentorigin + (0, 0, 60), currentangles );
- return;
- }
- if ( self.waitingToSpawn )
- return;
- self.waitingToSpawn = true;
- self waitAndSpawnClient();
- if ( isdefined( self ) )
- self.waitingToSpawn = false;
- }
- waitAndSpawnClient()
- {
- self endon ( "disconnect" );
- self endon ( "end_respawn" );
- level endon ( "game_ended" );
- self notify ( "attempted_spawn" );
- spawnedAsSpectator = false;
- if ( self.pers["teamKillPunish"] )
- {
- teamKillDelay = TeamKillDelay();
- if ( teamKillDelay > 0 )
- {
- setLowerMessage( "friendly_fire", &"MP_FRIENDLY_FIRE_WILL_NOT", teamKillDelay );
- self thread respawn_asSpectator( self.origin + (0, 0, 60), self.angles );
- spawnedAsSpectator = true;
- wait( teamKillDelay );
- clearLowerMessage( "friendly_fire" );
- self.respawnTimerStartTime = gettime();
- }
- self.pers["teamKillPunish"] = false;
- }
- else if ( TeamKillDelay() )
- {
- self.pers["teamkills"] = max( self.pers["teamkills"] - 1, 0 );
- }
- // for missiles, helicopters, ac130, etc...
- if ( self isUsingRemote() )
- {
- self waittill ( "stopped_using_remote" );
- }
- if ( !isdefined( self.waveSpawnIndex ) && isdefined( level.wavePlayerSpawnIndex[self.team] ) )
- {
- self.waveSpawnIndex = level.wavePlayerSpawnIndex[self.team];
- level.wavePlayerSpawnIndex[self.team]++;
- }
- timeUntilSpawn = TimeUntilSpawn( false );
- self thread predictAboutToSpawnPlayerOverTime( timeUntilSpawn );
- if ( timeUntilSpawn > 0 )
- {
- // spawn player into spectator on death during respawn delay, if he switches teams during this time, he will respawn next round
- setLowerMessage( "spawn_info", game["strings"]["waiting_to_spawn"], timeUntilSpawn );
- if ( !spawnedAsSpectator )
- self thread respawn_asSpectator( self.origin + (0, 0, 60), self.angles );
- spawnedAsSpectator = true;
- self waitForTimeOrNotify( timeUntilSpawn, "force_spawn" );
- self notify("stop_wait_safe_spawn_button");
- }
- waveBased = (getDvarInt( "scr_" + level.gameType + "_waverespawndelay" ) > 0);
- if ( maps\mp\gametypes\_tweakables::getTweakableValue( "player", "forcerespawn" ) == 0 && self.hasSpawned && !waveBased && !self.wantSafeSpawn )
- {
- setLowerMessage( "spawn_info", game["strings"]["press_to_spawn"] );
- if ( !spawnedAsSpectator )
- self thread respawn_asSpectator( self.origin + (0, 0, 60), self.angles );
- spawnedAsSpectator = true;
- self waitRespawnButton();
- }
- // do not wait after this point
- self.waitingToSpawn = false;
- self clearLowerMessage( "spawn_info" );
- self.waveSpawnIndex = undefined;
- self thread spawnPlayer();
- }
- waitRespawnButton()
- {
- self endon("disconnect");
- self endon("end_respawn");
- while (1)
- {
- if ( self useButtonPressed() )
- break;
- wait .05;
- }
- }
- removeSpawnMessageShortly( delay )
- {
- self endon ( "disconnect" );
- level endon ( "game_ended" );
- waittillframeend; // so we don't endon the end_respawn from spawning as a spectator
- self endon("end_respawn");
- wait delay;
- self clearLowerMessage( "spawn_info", 2.0 );
- }
- lastStandRespawnPlayer()
- {
- self LastStandRevive();
- if ( self _hasPerk( "specialty_finalstand" ) && !level.dieHardMode )
- self _unsetPerk( "specialty_finalstand" );
- if ( level.dieHardMode )
- self.headicon = "";
- self setStance( "crouch" );
- self.revived = true;
- self notify ( "revive" );
- // should only be defined if level.diehardmode
- if ( isDefined( self.standardmaxHealth ) )
- self.maxHealth = self.standardMaxHealth;
- self.health = self.maxHealth;
- self _enableUsability();
- if ( game["state"] == "postgame" )
- {
- assert( !level.intermission );
- // We're in the victory screen, but before intermission
- self maps\mp\gametypes\_gamelogic::freezePlayerForRoundEnd();
- }
- }
- getDeathSpawnPoint()
- {
- spawnpoint = spawn( "script_origin", self.origin );
- spawnpoint hide();
- spawnpoint.angles = self.angles;
- return spawnpoint;
- }
- showSpawnNotifies()
- {
- if ( isDefined( game["defcon"] ) )
- thread maps\mp\gametypes\_hud_message::defconSplashNotify( game["defcon"], false );
- if ( self isRested() )
- thread maps\mp\gametypes\_hud_message::splashNotify( "rested" );
- }
- predictAboutToSpawnPlayerOverTime( preduration )
- {
- self endon( "disconnect" );
- self endon( "spawned" );
- self endon( "used_predicted_spawnpoint" );
- self notify( "predicting_about_to_spawn_player" );
- self endon( "predicting_about_to_spawn_player" );
- if ( preduration <= 0 )
- return; // no point predicting if no time will pass. (if time until spawn is unknown, use 0.1)
- if ( preduration > 1.0 )
- wait preduration - 1.0;
- self predictAboutToSpawnPlayer();
- self PredictStreamPos( self.predictedSpawnPoint.origin + (0,0,60), self.predictedSpawnPoint.angles );
- self.predictedSpawnPointTime = gettime();
- for ( i = 0; i < 30; i++ )
- {
- wait .4; // this time is carefully selected: we want it as long as possible, but we want the loop to iterate about .1 to .3 seconds before people spawn for our final check
- prevPredictedSpawnPoint = self.predictedSpawnPoint;
- self predictAboutToSpawnPlayer();
- if ( self.predictedSpawnPoint != prevPredictedSpawnPoint )
- {
- self PredictStreamPos( self.predictedSpawnPoint.origin + (0,0,60), self.predictedSpawnPoint.angles );
- self.predictedSpawnPointTime = gettime();
- }
- }
- }
- predictAboutToSpawnPlayer()
- {
- assert( !isReallyAlive( self ) );
- // test predicting spawnpoints to see if we can eliminate streaming pops
- if ( self TimeUntilSpawn( true ) > 1.0 )
- {
- spawnpointname = "mp_global_intermission";
- spawnpoints = getentarray(spawnpointname, "classname");
- assert( spawnpoints.size );
- self.predictedSpawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(spawnpoints);
- return;
- }
- if ( isDefined( self.setSpawnPoint ) )
- {
- self.predictedSpawnPoint = self.setSpawnPoint;
- return;
- }
- spawnPoint = self [[level.getSpawnPoint]]();
- self.predictedSpawnPoint = spawnPoint;
- }
- checkPredictedSpawnpointCorrectness( spawnpointorigin )
- {
- /#
- if ( !isdefined( level.spawnpointPrediction ) )
- {
- level.spawnpointPrediction = spawnstruct();
- level.spawnpointPrediction.failures = 0;
- for ( i = 0; i < 7; i++ )
- level.spawnpointPrediction.buckets[i] = 0;
- }
- if ( !isdefined( self.predictedSpawnPoint ) )
- {
- println( "Failed to predict spawn for player " + self.name + " at " + spawnpointorigin );
- level.spawnpointPrediction.failures++;
- }
- else
- {
- dist = distance( self.predictedSpawnPoint.origin, spawnpointorigin );
- if ( dist <= 0 )
- level.spawnpointPrediction.buckets[0]++;
- else if ( dist <= 128 )
- level.spawnpointPrediction.buckets[1]++;
- else if ( dist <= 256 )
- level.spawnpointPrediction.buckets[2]++;
- else if ( dist <= 512 )
- level.spawnpointPrediction.buckets[3]++;
- else if ( dist <= 1024 )
- level.spawnpointPrediction.buckets[4]++;
- else if ( dist <= 2048 )
- level.spawnpointPrediction.buckets[5]++;
- else
- level.spawnpointPrediction.buckets[6]++;
- if ( dist > 0 )
- println( "Predicted player " + self.name + " would spawn at " + self.predictedSpawnPoint.origin + ", but spawned " + dist + " units away at " + spawnpointorigin );
- else
- println( "Predicted " + self.name + "'s spawn " + ((gettime() - self.predictedSpawnPointTime) / 1000) + " seconds ahead of time" );
- }
- #/
- self notify( "used_predicted_spawnpoint" );
- self.predictedSpawnPoint = undefined;
- }
- percentage( a, b )
- {
- return a + " (" + int(a / b * 100) + "%)";
- }
- printPredictedSpawnpointCorrectness()
- {
- /#
- if ( !isdefined( level.spawnpointPrediction ) )
- return;
- total = level.spawnpointPrediction.failures;
- for ( i = 0; i < 7; i++ )
- total += level.spawnpointPrediction.buckets[i];
- if ( total <= 0 )
- return;
- println( "****** Spawnpoint Prediction *******" );
- println( "There were " + total + " spawns. " + percentage( level.spawnpointPrediction.failures, total ) + " failed to be predicted." );
- total -= level.spawnpointPrediction.failures;
- if ( total > 0 )
- {
- println( "Out of the predicted ones..." );
- println( " " + percentage( level.spawnpointPrediction.buckets[0], total ) + " were perfect" );
- println( " " + percentage( level.spawnpointPrediction.buckets[1], total ) + " were within 128 units" );
- println( " " + percentage( level.spawnpointPrediction.buckets[2], total ) + " were within 256 units" );
- println( " " + percentage( level.spawnpointPrediction.buckets[3], total ) + " were within 512 units" );
- println( " " + percentage( level.spawnpointPrediction.buckets[4], total ) + " were within 1024 units" );
- println( " " + percentage( level.spawnpointPrediction.buckets[5], total ) + " were within 2048 units" );
- println( " " + percentage( level.spawnpointPrediction.buckets[6], total ) + " were beyond 2048 units" );
- }
- println( "*************" );
- #/
- }
- getSpawnOrigin( spawnpoint )
- {
- if ( !positionWouldTelefrag( spawnpoint.origin ) )
- return spawnpoint.origin;
- if ( !isdefined( spawnpoint.alternates ) )
- return spawnpoint.origin;
- foreach( alternate in spawnpoint.alternates )
- {
- if ( !positionWouldTelefrag( alternate ) )
- return alternate;
- }
- return spawnpoint.origin;
- }
- tiValidationCheck()
- {
- if ( !isDefined( self.setSpawnPoint ) )
- return false;
- carePackages = getEntArray( "care_package", "targetname" );
- foreach ( package in carePackages )
- {
- if ( distance( package.origin, self.setSpawnPoint.playerSpawnPos ) > 64 )
- continue;
- if ( isDefined( package.owner ) )
- self maps\mp\gametypes\_hud_message::playerCardSplashNotify( "destroyed_insertion", package.owner );
- maps\mp\perks\_perkfunctions::deleteTI( self.setSpawnpoint );
- return false;
- }
- return true;
- }
- spawnPlayer()
- {
- self endon( "disconnect" );
- self endon( "joined_spectators" );
- self notify( "spawned" );
- self notify( "end_respawn" );
- if ( isDefined( self.setSpawnPoint ) && self tiValidationCheck() )
- {
- spawnPoint = self.setSpawnPoint;
- self playLocalSound( "tactical_spawn" );
- if ( level.teamBased )
- self playSoundToTeam( "tactical_spawn", level.otherTeam[self.team] );
- else
- self playSound( "tactical_spawn" );
- assert( isDefined( spawnPoint.playerSpawnPos ) );
- assert( isDefined( spawnPoint.angles ) );
- spawnOrigin = self.setSpawnPoint.playerSpawnPos;
- spawnAngles = self.setSpawnPoint.angles;
- if ( isDefined( self.setSpawnPoint.enemyTrigger ) )
- self.setSpawnPoint.enemyTrigger Delete();
- self.setSpawnPoint delete();
- spawnPoint = undefined;
- }
- else
- {
- spawnPoint = self [[level.getSpawnPoint]]();
- assert( isDefined( spawnPoint ) );
- assert( isDefined( spawnPoint.origin ) );
- assert( isDefined( spawnPoint.angles ) );
- spawnOrigin = spawnpoint.origin;
- spawnAngles = spawnpoint.angles;
- }
- self setSpawnVariables();
- /#
- if ( !getDvarInt( "scr_forcerankedmatch" ) )
- assert( (level.teamBased && self.sessionteam == self.team) || (!level.teamBased && self.sessionteam == "none") );
- #/
- hadSpawned = self.hasSpawned;
- self.fauxDead = undefined;
- self.killsThisLife = [];
- self updateSessionState( "playing", "" );
- self ClearKillcamState();
- self.cancelkillcam = 1;
- self openMenu( "killedby_card_hide" );
- self.maxhealth = maps\mp\gametypes\_tweakables::getTweakableValue( "player", "maxhealth" );
- self.health = self.maxhealth;
- self.friendlydamage = undefined;
- self.hasSpawned = true;
- self.spawnTime = getTime();
- self.wasTI = !isDefined( spawnPoint );
- self.afk = false;
- self.lastStand = undefined;
- self.infinalStand = undefined;
- self.inC4Death = undefined;
- self.damagedPlayers = [];
- self.moveSpeedScaler = 1;
- self.killStreakScaler = 1;
- self.xpScaler = 1;
- self.objectiveScaler = 1;
- self.inLastStand = false;
- self.clampedHealth = undefined;
- self.shieldDamage = 0;
- self.shieldBulletHits = 0;
- self.recentShieldXP = 0;
- self.disabledWeapon = 0;
- self.disabledWeaponSwitch = 0;
- self.disabledOffhandWeapons = 0;
- self resetUsability();
- if ( self.pers["lives"] == getGametypeNumLives() )
- {
- maps\mp\gametypes\_playerlogic::addToLivesCount();
- }
- if ( self.pers["lives"] )
- self.pers["lives"]--;
- self maps\mp\gametypes\_playerlogic::addToAliveCount();
- if ( !hadSpawned || gameHasStarted() || (gameHasStarted() && level.inGracePeriod && self.hasDoneCombat) )
- self maps\mp\gametypes\_playerlogic::removeFromLivesCount();
- if ( !self.wasAliveAtMatchStart )
- {
- acceptablePassedTime = 20;
- if ( getTimeLimit() > 0 && acceptablePassedTime < getTimeLimit() * 60 / 4 )
- acceptablePassedTime = getTimeLimit() * 60 / 4;
- if ( level.inGracePeriod || getTimePassed() < acceptablePassedTime * 1000 )
- self.wasAliveAtMatchStart = true;
- }
- self setClientDvar( "cg_thirdPerson", "0" );
- self setDepthOfField( 0, 0, 512, 512, 4, 0 );
- self setClientDvar( "cg_fov", "65" );
- // Don't do this stuff for TI spawn points
- if ( isDefined( spawnPoint ) )
- {
- self maps\mp\gametypes\_spawnlogic::finalizeSpawnpointChoice( spawnpoint );
- spawnOrigin = getSpawnOrigin( spawnpoint );
- spawnAngles = spawnpoint.angles;
- }
- else
- {
- // the only useful part of finalizeSpawnpointChoice() when using tactical insertion
- self.lastSpawnTime = getTime();
- }
- self.spawnPos = spawnOrigin;
- self spawn( spawnOrigin, spawnAngles );
- [[level.onSpawnPlayer]]();
- // Don't do this stuff for TI spawn points
- if ( isDefined( spawnPoint ) )
- self checkPredictedSpawnpointCorrectness( spawnPoint.origin );
- self maps\mp\gametypes\_missions::playerSpawned();
- prof_begin( "spawnPlayer_postUTS" );
- assert( isValidClass( self.class ) );
- self maps\mp\gametypes\_class::setClass( self.class );
- self maps\mp\gametypes\_class::giveLoadout( self.team, self.class );
- if ( getDvarInt( "camera_thirdPerson" ) )
- self setThirdPersonDOF( true );
- if ( !gameFlag( "prematch_done" ) )
- self freezeControlsWrapper( true );
- else
- self freezeControlsWrapper( false );
- if ( !gameFlag( "prematch_done" ) || !hadSpawned && game["state"] == "playing" )
- {
- self setClientDvar( "scr_objectiveText", getObjectiveHintText( self.pers["team"] ) );
- team = self.pers["team"];
- if ( game["status"] == "overtime" )
- thread maps\mp\gametypes\_hud_message::oldNotifyMessage( game["strings"]["overtime"], game["strings"]["overtime_hint"], undefined, (1, 0, 0), "mp_last_stand" );
- else if ( getIntProperty( "useRelativeTeamColors", 0 ) )
- thread maps\mp\gametypes\_hud_message::oldNotifyMessage( game["strings"][team + "_name"], undefined, game["icons"][team] + "_blue", game["colors"]["blue"] );
- else
- thread maps\mp\gametypes\_hud_message::oldNotifyMessage( game["strings"][team + "_name"], undefined, game["icons"][team], game["colors"][team] );
- thread showSpawnNotifies();
- }
- if ( !level.splitscreen && getIntProperty( "scr_showperksonspawn", 1 ) == 1 && game["state"] != "postgame" )
- {
- self openMenu( "perk_display" );
- self thread hidePerksAfterTime( 5.0 );
- self thread hidePerksOnDeath();
- }
- prof_end( "spawnPlayer_postUTS" );
- //self logstring( "S " + self.origin[0] + " " + self.origin[1] + " " + self.origin[2] );
- // give "connected" handlers a chance to start
- // many of these start onPlayerSpawned handlers which rely on the "spawned_player"
- // notify which can happen on the same frame as the "connected" notify
- waittillframeend;
- self notify( "spawned_player" );
- level notify ( "player_spawned", self );
- if ( game["state"] == "postgame" )
- {
- assert( !level.intermission );
- // We're in the victory screen, but before intermission
- self maps\mp\gametypes\_gamelogic::freezePlayerForRoundEnd();
- }
- }
- hidePerksAfterTime( delay )
- {
- self endon("disconnect");
- self endon("perks_hidden");
- wait delay;
- self openMenu( "perk_hide" );
- self notify("perks_hidden");
- }
- hidePerksOnDeath()
- {
- self endon("disconnect");
- self endon("perks_hidden");
- self waittill("death");
- self openMenu( "perk_hide" );
- self notify("perks_hidden");
- }
- hidePerksOnKill()
- {
- self endon("disconnect");
- self endon("death");
- self endon("perks_hidden");
- self waittill( "killed_player" );
- self openMenu( "perk_hide" );
- self notify("perks_hidden");
- }
- spawnSpectator( origin, angles )
- {
- self notify("spawned");
- self notify("end_respawn");
- in_spawnSpectator( origin, angles );
- }
- // spawnSpectator clone without notifies for spawning between respawn delays
- respawn_asSpectator( origin, angles )
- {
- in_spawnSpectator( origin, angles );
- }
- // spawnSpectator helper
- in_spawnSpectator( origin, angles )
- {
- self setSpawnVariables();
- // don't clear lower message if not actually a spectator,
- // because it probably has important information like when we'll spawn
- if ( isDefined( self.pers["team"] ) && self.pers["team"] == "spectator" && !level.gameEnded )
- self clearLowerMessage( "spawn_info" );
- self.sessionstate = "spectator";
- self ClearKillcamState();
- self.friendlydamage = undefined;
- if( isDefined( self.pers["team"] ) && self.pers["team"] == "spectator" )
- self.statusicon = "";
- else
- self.statusicon = "hud_status_dead";
- maps\mp\gametypes\_spectating::setSpectatePermissions();
- onSpawnSpectator( origin, angles );
- if ( level.teamBased && !level.splitscreen )
- self setDepthOfField( 0, 128, 512, 4000, 6, 1.8 );
- }
- getPlayerFromClientNum( clientNum )
- {
- if ( clientNum < 0 )
- return undefined;
- for ( i = 0; i < level.players.size; i++ )
- {
- if ( level.players[i] getEntityNumber() == clientNum )
- return level.players[i];
- }
- return undefined;
- }
- onSpawnSpectator( origin, angles)
- {
- if( isDefined( origin ) && isDefined( angles ) )
- {
- self SetSpectateDefaults( origin, angles );
- self spawn(origin, angles);
- self checkPredictedSpawnpointCorrectness( origin );
- return;
- }
- spawnpointname = "mp_global_intermission";
- spawnpoints = getentarray(spawnpointname, "classname");
- assert( spawnpoints.size );
- spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(spawnpoints);
- self SetSpectateDefaults(spawnpoint.origin, spawnpoint.angles);
- self spawn(spawnpoint.origin, spawnpoint.angles);
- self checkPredictedSpawnpointCorrectness( spawnpoint.origin );
- }
- spawnIntermission()
- {
- self endon( "disconnect" );
- self notify( "spawned" );
- self notify( "end_respawn" );
- self setSpawnVariables();
- self closepopupMenu();
- self closeInGameMenu();
- self clearLowerMessages();
- self freezeControlsWrapper( true );
- self setClientDvar( "cg_everyoneHearsEveryone", 1 );
- if ( level.rankedMatch && ( self.postGamePromotion || self.pers["postGameChallenges"] ) )
- {
- if ( self.postGamePromotion )
- self playLocalSound( "mp_level_up" );
- else
- self playLocalSound( "mp_challenge_complete" );
- if ( self.postGamePromotion > level.postGameNotifies )
- level.postGameNotifies = 1;
- if ( self.pers["postGameChallenges"] > level.postGameNotifies )
- level.postGameNotifies = self.pers["postGameChallenges"];
- self closepopupMenu();
- self closeInGameMenu();
- self openMenu( game["menu_endgameupdate"] );
- waitTime = 4.0 + min( self.pers["postGameChallenges"], 3 );
- while ( waitTime )
- {
- wait ( 0.25 );
- waitTime -= 0.25;
- self openMenu( game["menu_endgameupdate"] );
- }
- self closeMenu( game["menu_endgameupdate"] );
- }
- self.sessionstate = "intermission";
- self ClearKillcamState();
- self.friendlydamage = undefined;
- spawnPoints = getEntArray( "mp_global_intermission", "classname" );
- assertEx( spawnPoints.size, "NO mp_global_intermission SPAWNPOINTS IN MAP" );
- spawnPoint = spawnPoints[0];
- self spawn( spawnPoint.origin, spawnPoint.angles );
- self checkPredictedSpawnpointCorrectness( spawnPoint.origin );
- self setDepthOfField( 0, 128, 512, 4000, 6, 1.8 );
- }
- spawnEndOfGame()
- {
- if ( 1 )
- {
- self freezeControlsWrapper( true );
- self spawnSpectator();
- self freezeControlsWrapper( true );
- return;
- }
- self notify("spawned");
- self notify("end_respawn");
- self setSpawnVariables();
- self closepopupMenu();
- self closeInGameMenu();
- self clearLowerMessages();
- self setClientDvar( "cg_everyoneHearsEveryone", 1 );
- self.sessionstate = "dead";
- self ClearKillcamState();
- self.friendlydamage = undefined;
- spawnPoints = getEntArray( "mp_global_intermission", "classname" );
- assertEx( spawnPoints.size, "NO mp_global_intermission SPAWNPOINTS IN MAP" );
- spawnPoint = spawnPoints[0];
- self spawn( spawnPoint.origin, spawnPoint.angles );
- self checkPredictedSpawnpointCorrectness( spawnPoint.origin );
- spawnPoint setModel( "tag_origin" );
- //self playerLinkTo( spawnPoint, "tag_origin", (0,0,0), spawnPoint.angles );
- self playerLinkTo( spawnPoint );
- self PlayerHide();
- self freezeControlsWrapper( true );
- self setDepthOfField( 0, 128, 512, 4000, 6, 1.8 );
- }
- setSpawnVariables()
- {
- // Stop shellshock and rumble
- self StopShellshock();
- self StopRumble( "damage_heavy" );
- }
- notifyConnecting()
- {
- waittillframeend;
- if( isDefined( self ) )
- level notify( "connecting", self );
- }
- Callback_PlayerDisconnect()
- {
- if ( !isDefined( self.connected ) )
- return;
- self removePlayerOnDisconnect();
- if ( !level.teamBased )
- game["roundsWon"][self.guid] = undefined;
- //if ( !level.gameEnded )
- // self logXPGains();
- if ( level.splitscreen )
- {
- players = level.players;
- if ( players.size <= 1 )
- level thread maps\mp\gametypes\_gamelogic::forceEnd();
- }
- if ( isDefined( self.score ) && isDefined( self.pers["team"] ) )
- {
- setPlayerTeamRank( self, self.clientid, self.score - 5 * self.deaths );
- }
- lpselfnum = self getEntityNumber();
- lpGuid = self.guid;
- logPrint("Q;" + lpGuid + ";" + lpselfnum + ";" + self.name + "\n");
- self thread maps\mp\_events::disconnected();
- if ( level.gameEnded )
- self maps\mp\gametypes\_gamescore::removeDisconnectedPlayerFromPlacement();
- if ( isDefined( self.team ) )
- self maps\mp\gametypes\_playerlogic::removeFromTeamCount();
- if ( self.sessionstate == "playing" )
- self maps\mp\gametypes\_playerlogic::removeFromAliveCount( true );
- else if ( self.sessionstate == "spectator" )
- level thread maps\mp\gametypes\_gamelogic::updateGameEvents();
- }
- removePlayerOnDisconnect()
- {
- found = false;
- for ( entry = 0; entry < level.players.size; entry++ )
- {
- if ( level.players[entry] == self )
- {
- found = true;
- while ( entry < level.players.size-1 )
- {
- level.players[entry] = level.players[entry + 1];
- assert( level.players[entry] != self );
- entry++;
- }
- level.players[entry] = undefined;
- break;
- }
- }
- assert( found );
- }
- initClientDvars()
- {
- makeDvarServerInfo( "cg_drawTalk", 1 );
- makeDvarServerInfo( "cg_drawCrosshair", 1 );
- makeDvarServerInfo( "cg_drawCrosshairNames", 1 );
- makeDvarServerInfo( "cg_hudGrenadeIconMaxRangeFrag", 250 );
- if ( level.hardcoreMode )
- {
- setDvar( "cg_drawTalk", 3 );
- setDvar( "cg_drawCrosshair", 0 );
- setDvar( "cg_drawCrosshairNames", 1 );
- setDvar( "cg_hudGrenadeIconMaxRangeFrag", 0 );
- }
- self setClientDvars( "cg_drawSpectatorMessages", 1,
- "g_compassShowEnemies", getDvar( "scr_game_forceuav" ),
- "cg_scoreboardPingGraph", 1 );
- if ( level.splitScreen )
- {
- self setClientDvars("cg_hudGrenadeIconHeight", "37.5",
- "cg_hudGrenadeIconWidth", "37.5",
- "cg_hudGrenadeIconOffset", "75",
- "cg_hudGrenadePointerHeight", "18",
- "cg_hudGrenadePointerWidth", "37.5",
- "cg_hudGrenadePointerPivot", "18 40.5",
- "cg_fovscale", "0.75" );
- }
- else
- {
- self setClientDvars("cg_hudGrenadeIconHeight", "25",
- "cg_hudGrenadeIconWidth", "25",
- "cg_hudGrenadeIconOffset", "50",
- "cg_hudGrenadePointerHeight", "12",
- "cg_hudGrenadePointerWidth", "25",
- "cg_hudGrenadePointerPivot", "12 27",
- "cg_fovscale", "1");
- }
- if ( getGametypeNumLives() )
- {
- self setClientDvars("cg_deadChatWithDead", 1,
- "cg_deadChatWithTeam", 0,
- "cg_deadHearTeamLiving", 0,
- "cg_deadHearAllLiving", 0);
- }
- else
- {
- self setClientDvars("cg_deadChatWithDead", 0,
- "cg_deadChatWithTeam", 1,
- "cg_deadHearTeamLiving", 1,
- "cg_deadHearAllLiving", 0);
- }
- if ( level.teamBased )
- self setClientDvars("cg_everyonehearseveryone", 0);
- self setClientDvar( "ui_altscene", 0 );
- if ( getdvarint("scr_hitloc_debug") )
- {
- for ( i = 0; i < 6; i++ )
- {
- self setClientDvar( "ui_hitloc_" + i, "" );
- }
- self.hitlocInited = true;
- }
- }
- Callback_PlayerConnect()
- {
- thread notifyConnecting();
- self.statusicon = "hud_status_connecting";
- self waittill( "begin" );
- self.statusicon = "";
- connectTime = undefined;
- /#
- connectTime = getTime();
- #/
- level notify( "connected", self );
- self.connected = true;
- if ( self isHost() )
- level.player = self;
- // only print that we connected if we haven't connected in a previous round
- if( !level.splitscreen && !isDefined( self.pers["score"] ) )
- iPrintLn(&"MP_CONNECTED", self);
- self.usingOnlineDataOffline = self isUsingOnlineDataOffline();
- self initClientDvars();
- self initPlayerStats();
- if( getdvar( "r_reflectionProbeGenerate" ) == "1" )
- level waittill( "eternity" );
- self.guid = self getGuid();
- firstConnect = false;
- if ( !isDefined( self.pers["clientid"] ) )
- {
- self.pers["clientid"] = game["clientid"];
- game["clientid"]++;
- firstConnect = true;
- }
- self.clientid = self.pers["clientid"];
- logPrint("J;" + self.guid + ";" + self getEntityNumber() + ";" + self.name + "\n");
- if ( matchMakingGame() && game["clientid"] <= 24 && game["clientid"] != getMatchData( "playerCount" ) )
- {
- setMatchData( "playerCount", game["clientid"] );
- setMatchData( "players", self.clientid, "xuid", self getXuid() );
- /#
- if ( ( getDvarInt( "scr_forcerankedmatch" ) && level.teamBased ) || ( isDefined( self.pers["isBot"] ) && level.teamBased ) )
- self.sessionteam = maps\mp\gametypes\_menus::getTeamAssignment();
- #/
- assert( getdvarint( "scr_runlevelandquit" ) == 1 || (level.teamBased && (self.sessionteam == "allies" || self.sessionteam == "axis")) || (!level.teamBased && self.sessionteam == "none" ) );
- //assert( (level.teamBased && self.sessionteam == self.team) || (!level.teamBased && self.sessionteam == "none") );
- setMatchData( "players", self.clientid, "team", self.sessionteam );
- }
- if ( !level.teamBased )
- game["roundsWon"][self.guid] = 0;
- self.leaderDialogQueue = [];
- self.leaderDialogActive = "";
- self.leaderDialogGroups = [];
- self.leaderDialogGroup = "";
- if ( !isDefined( self.pers["cur_kill_streak"] ) )
- self.pers["cur_kill_streak"] = 0;
- if ( !isDefined( self.pers["cur_death_streak"] ) )
- self.pers["cur_death_streak"] = 0;
- self.kill_streak = self maps\mp\gametypes\_persistence::statGet( "killStreak" );
- self.lastGrenadeSuicideTime = -1;
- self.teamkillsThisRound = 0;
- self.hasSpawned = false;
- self.waitingToSpawn = false;
- self.wantSafeSpawn = false;
- self.wasAliveAtMatchStart = false;
- self.moveSpeedScaler = 1;
- self.killStreakScaler = 1;
- self.xpScaler = 1;
- self.objectiveScaler = 1;
- self.isSniper = false;
- self.saved_actionSlotData = [];
- self setRestXPGoal();
- for( slotID = 1; slotID <= 4; slotID++ )
- {
- self.saved_actionSlotData[slotID] = spawnStruct();
- self.saved_actionSlotData[slotID].type = "";
- self.saved_actionSlotData[slotID].item = undefined;
- }
- self thread maps\mp\_flashgrenades::monitorFlash();
- // give any threads waiting on the "connected" notify a chance to process before we are added to level.players
- // this should ensure that all . variables on the player are correctly initialized by this point
- waittillframeend;
- /#
- foreach ( player in level.players )
- assert( player != self );
- #/
- level.players[level.players.size] = self;
- if ( level.teambased )
- self updateScores();
- // When joining a game in progress, if the game is at the post game state (scoreboard) the connecting player should spawn into intermission
- if ( game["state"] == "postgame" )
- {
- self.connectedPostGame = true;
- if ( matchMakingGame() )
- self maps\mp\gametypes\_menus::addToTeam( maps\mp\gametypes\_menus::getTeamAssignment(), true );
- else
- self maps\mp\gametypes\_menus::addToTeam( "spectator", true );
- self setClientDvars( "cg_drawSpectatorMessages", 0 );
- spawnIntermission();
- return;
- }
- /#
- if ( getDvarInt( "scr_debug_postgameconnect" ) )
- {
- self.pers["class"] = "";
- self.class = "";
- if ( self.sessionteam != "spectator" )
- self.pers["team"] = self.sessionteam;
- self.team = undefined;
- }
- #/
- // only give a loss on the first connect
- if ( firstConnect )
- maps\mp\gametypes\_gamelogic::updateLossStats( self );
- level endon( "game_ended" );
- if ( isDefined( level.hostMigrationTimer ) )
- self thread maps\mp\gametypes\_hostmigration::hostMigrationTimerThink();
- // first connect only
- if ( !isDefined( self.pers["team"] ) )
- {
- if ( matchMakingGame() )
- {
- self thread spawnSpectator();
- self [[level.autoassign]]();
- self thread kickIfDontSpawn();
- return;
- }
- self [[level.spectator]]();
- self maps\mp\gametypes\_menus::beginTeamChoice();
- }
- else
- {
- self maps\mp\gametypes\_menus::addToTeam( self.pers["team"], true );
- if ( isValidClass( self.pers["class"] ) )
- {
- self thread spawnClient();
- return;
- }
- self thread spawnSpectator();
- if ( self.pers["team"] == "spectator" )
- self maps\mp\gametypes\_menus::beginTeamChoice();
- else
- self maps\mp\gametypes\_menus::beginClassChoice();
- }
- /#
- assert( connectTime == getTime() );
- #/
- }
- Callback_PlayerMigrated()
- {
- println( "Player " + self.name + " finished migrating at time " + gettime() );
- if ( isDefined( self.connected ) && self.connected )
- {
- self updateObjectiveText();
- self updateMainMenu();
- if ( level.teambased )
- self updateScores();
- }
- level.hostMigrationReturnedPlayerCount++;
- if ( level.hostMigrationReturnedPlayerCount >= level.players.size * 2 / 3 )
- {
- println( "2/3 of players have finished migrating" );
- level notify( "hostmigration_enoughplayers" );
- }
- }
- AddLevelsToExperience( experience, levels ) // lets you add "1500 experience + 1.5 levels" and returns the result in experience
- {
- rank = maps\mp\gametypes\_rank::getRankForXp( experience );
- minXP = maps\mp\gametypes\_rank::getRankInfoMinXp( rank );
- maxXP = maps\mp\gametypes\_rank::getRankInfoMaxXp( rank );
- rank += (experience - minXP) / (maxXP - minXP);
- rank += levels;
- if ( rank < 0 )
- {
- rank = 0;
- fractionalPart = 0.0;
- }
- else if ( rank >= level.maxRank + 1.0 )
- {
- rank = level.maxRank;
- fractionalPart = 1.0;
- }
- else
- {
- fractionalPart = rank - floor( rank );
- rank = int(floor( rank ));
- }
- minXP = maps\mp\gametypes\_rank::getRankInfoMinXp( rank );
- maxXP = maps\mp\gametypes\_rank::getRankInfoMaxXp( rank );
- return int( fractionalPart * (maxXP - minXP) ) + minXP;
- }
- GetRestXPCap( experience )
- {
- levelsToCap = getDvarFloat( "scr_restxp_cap" );
- return AddLevelsToExperience( experience, levelsToCap );
- }
- setRestXPGoal()
- {
- if ( !getdvarint( "scr_restxp_enable" ) )
- {
- self setPlayerData( "restXPGoal", 0 );
- return;
- }
- secondsSinceLastGame = self getRestedTime();
- hoursSinceLastGame = secondsSinceLastGame / 3600;
- /#
- hoursSinceLastGame *= getDvarFloat( "scr_restxp_timescale" );
- #/
- experience = self getPlayerData( "experience" );
- minRestXPTime = getDvarFloat( "scr_restxp_minRestTime" ); // hours
- restXPGainRate = getDvarFloat( "scr_restxp_levelsPerDay" ) / 24.0;
- restXPCap = GetRestXPCap( experience );
- restXPGoal = self getPlayerData( "restXPGoal" );
- if ( restXPGoal < experience )
- restXPGoal = experience;
- oldRestXPGoal = restXPGoal;
- restLevels = 0;
- if ( hoursSinceLastGame > minRestXPTime )
- {
- restLevels = restXPGainRate * hoursSinceLastGame;
- restXPGoal = AddLevelsToExperience( restXPGoal, restLevels );
- }
- cappedString = "";
- if ( restXPGoal >= restXPCap )
- {
- restXPGoal = restXPCap;
- cappedString = " (hit cap)";
- }
- println( "Player " + self.name + " has rested for " + hoursSinceLastGame + " hours; gained " + restLevels + " levels of rest XP" + cappedString + ". Now has " + (restXPGoal - experience) + " rest XP; was " + (oldRestXPGoal - experience) );
- self setPlayerData( "restXPGoal", restXPGoal );
- }
- forceSpawn()
- {
- self endon ( "death" );
- self endon ( "disconnect" );
- self endon ( "spawned" );
- wait ( 60.0 );
- if ( self.hasSpawned )
- return;
- if ( self.pers["team"] == "spectator" )
- return;
- if ( !isValidClass( self.pers["class"] ) )
- {
- self.pers["class"] = "CLASS_CUSTOM1";
- self.class = self.pers["class"];
- }
- self closeMenus();
- self thread spawnClient();
- }
- kickIfDontSpawn()
- {
- self endon ( "death" );
- self endon ( "disconnect" );
- self endon ( "spawned" );
- self endon ( "attempted_spawn" );
- waittime = getdvarfloat("scr_kick_time", 90 );
- mintime = getdvarfloat("scr_kick_mintime", 45 );
- starttime = gettime();
- if ( self isHost() )
- kickWait( 120 );
- else
- kickWait( waittime );
- timePassed = (gettime() - starttime)/1000;
- if ( timePassed < waittime - .1 && timePassed < mintime )
- return;
- if ( self.hasSpawned )
- return;
- if ( self.pers["team"] == "spectator" )
- return;
- kick( self getEntityNumber(), "EXE_PLAYERKICKED_INACTIVE" );
- level thread maps\mp\gametypes\_gamelogic::updateGameEvents();
- }
- kickWait( waittime )
- {
- level endon("game_ended");
- maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( waittime );
- }
- updateSessionState( sessionState, statusIcon )
- {
- assert( sessionState == "playing" || sessionState == "dead" || sessionState == "spectator" || sessionState == "intermission" );
- self.sessionstate = sessionState;
- self.statusicon = statusIcon;
- }
- initPlayerStats()
- {
- self maps\mp\gametypes\_persistence::initBufferedStats();
- self initPersStat( "score" );
- self.score = self.pers["score"];
- self initPersStat( "deaths" );
- self.deaths = self getPersStat( "deaths" );
- self initPersStat( "suicides" );
- self.suicides = self getPersStat( "suicides" );
- self initPersStat( "kills" );
- self.kills = self getPersStat( "kills" );
- self initPersStat( "headshots" );
- self.headshots = self getPersStat( "headshots" );
- self initPersStat( "assists" );
- self.assists = self getPersStat( "assists" );
- self initPersStat( "teamkills" );
- if ( !isDefined( self.pers["teamKillPunish"] ) )
- self.pers["teamKillPunish"] = false;
- self initPersStat( "longestStreak" );
- self.pers["lives"] = getGametypeNumLives();
- self maps\mp\gametypes\_persistence::statSetChild( "round", "kills", 0 );
- self maps\mp\gametypes\_persistence::statSetChild( "round", "killStreak", 0 );
- self maps\mp\gametypes\_persistence::statSetChild( "round", "deaths", 0 );
- self maps\mp\gametypes\_persistence::statSetChild( "round", "score", 0 );
- self maps\mp\gametypes\_persistence::statSetChild( "round", "loss", false );
- self maps\mp\gametypes\_persistence::statSetChild( "round", "win", false );
- self maps\mp\gametypes\_persistence::statSetChild( "round", "scoreboardType", "none" );
- self maps\mp\gametypes\_persistence::statSetChildBuffered( "round", "timePlayed", 0 );
- }
- addToTeamCount()
- {
- assert( isPlayer( self ) );
- assert( isDefined( self.team ) );
- assert( isDefined( self.pers["team"] ) );
- assert( self.team == self.pers["team"] );
- level.teamCount[self.team]++;
- maps\mp\gametypes\_gamelogic::updateGameEvents();
- }
- removeFromTeamCount()
- {
- assert( isPlayer( self ) );
- assert( isDefined( self.team ) );
- assert( isDefined( self.pers["team"] ) );
- assert( self.team == self.pers["team"] );
- level.teamCount[self.team]--;
- }
- addToAliveCount()
- {
- assert( isPlayer( self ) );
- level.aliveCount[self.team]++;
- level.hasSpawned[self.team]++;
- if ( level.aliveCount["allies"] + level.aliveCount["axis"] > level.maxPlayerCount )
- level.maxPlayerCount = level.aliveCount["allies"] + level.aliveCount["axis"];
- }
- removeFromAliveCount( disconnected )
- {
- assert( isPlayer( self ) );
- if ( isDefined( self.switching_teams ) || isDefined( disconnected ) )
- {
- self maps\mp\gametypes\_playerlogic::removeAllFromLivesCount();
- if ( isDefined( self.switching_teams ) )
- self.pers["lives"] = 0;
- }
- level.aliveCount[self.team]--;
- return maps\mp\gametypes\_gamelogic::updateGameEvents();
- }
- addToLivesCount()
- {
- assert( isPlayer( self ) );
- level.livesCount[self.team] += self.pers["lives"];
- }
- removeFromLivesCount()
- {
- assert( isPlayer( self ) );
- level.livesCount[self.team]--;
- // defensive, but we need to allow players to die/respawn when they're the only player in an offline game
- level.livesCount[self.team] = int( max( 0, level.livesCount[self.team] ) );
- }
- removeAllFromLivesCount()
- {
- assert( isPlayer( self ) );
- level.livesCount[self.team] -= self.pers["lives"];
- // defensive, but we need to allow players to die/respawn when they're the only player in an offline game
- level.livesCount[self.team] = int( max( 0, level.livesCount[self.team] ) );
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement