This commit is contained in:
reaaLx
2024-09-04 23:46:54 +10:00
parent 5f950a3356
commit 1ea2370337
471 changed files with 108331 additions and 0 deletions

View File

@ -0,0 +1,211 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
init()
{
if( level._multiTeamBased == true )
{
for( i = 0; i < level._teamNameList.size; i++ )
{
level._isTeamSpeaking[level._teamNameList[i]] = false;
level._speakers[level._teamNameList[i]] = [];
}
}
level._isTeamSpeaking["allies"] = false;
level._isTeamSpeaking["axis"] = false;
level._speakers["allies"] = [];
level._speakers["axis"] = [];
level._bcSounds = [];
level._bcSounds["reload"] = "inform_reloading_generic";
level._bcSounds["frag_out"] = "inform_attack_grenade";
level._bcSounds["flash_out"] = "inform_attack_flashbang";
level._bcSounds["smoke_out"] = "inform_attack_smoke";
level._bcSounds["conc_out"] = "inform_attack_stun";
level._bcSounds["c4_plant"] = "inform_attack_thwc4";
level._bcSounds["claymore_plant"] = "inform_plant_claymore";
level._bcSounds["kill"] = "inform_killfirm_infantry";
level._bcSounds["casualty"] = "inform_casualty_generic";
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill ( "connected", player );
player thread onPlayerSpawned();
}
}
onPlayerSpawned()
{
self endon( "disconnect" );
for(;;)
{
self waittill( "spawned_player" );
// help players be stealthy in splitscreen by not announcing their intentions
if ( level._splitscreen )
continue;
self thread claymoreTracking();
self thread reloadTracking();
self thread grenadeTracking();
}
}
claymoreTracking()
{
self endon ( "death" );
self endon ( "disconnect" );
while(1)
{
self waittill( "begin_firing" );
weaponName = self getCurrentWeapon();
if ( weaponName == "claymore_mp" )
level thread sayLocalSound( self, "claymore_plant" );
}
}
reloadTracking()
{
self endon ( "death" );
self endon ( "disconnect" );
for( ;; )
{
self waittill ( "reload_start" );
level thread sayLocalSound( self, "reload" );
}
}
grenadeTracking()
{
self endon ( "death" );
self endon ( "disconnect" );
for( ;; )
{
self waittill ( "grenade_fire", grenade, weaponName );
if ( weaponName == "frag_grenade_mp" )
level thread sayLocalSound( self, "frag_out" );
else if ( weaponName == "flash_grenade_mp" )
level thread sayLocalSound( self, "flash_out" );
else if ( weaponName == "concussion_grenade_mp" )
level thread sayLocalSound( self, "conc_out" );
else if ( weaponName == "smoke_grenade_mp" )
level thread sayLocalSound( self, "smoke_out" );
else if ( weaponName == "c4_mp" )
level thread sayLocalSound( self, "c4_plant" );
}
}
sayLocalSoundDelayed( player, soundType, delay )
{
player endon ( "death" );
player endon ( "disconnect" );
wait ( delay );
sayLocalSound( player, soundType );
}
sayLocalSound( player, soundType )
{
player endon ( "death" );
player endon ( "disconnect" );
if ( isSpeakerInRange( player ) )
return;
if( player.team != "spectator" )
{
prefix = maps\mp\gametypes\_teams::getTeamVoicePrefix( player.team ) + "1_";
soundAlias = prefix + level._bcSounds[soundType];
player thread doSound( soundAlias );
}
}
doSound( soundAlias )
{
team = self.pers["team"];
level addSpeaker( self, team );
self playSoundToTeam( soundAlias, team, self );
self thread timeHack( soundAlias ); // workaround because soundalias notify isn't happening
self waittill_any( soundAlias, "death", "disconnect" );
level removeSpeaker( self, team );
}
timeHack( soundAlias )
{
self endon ( "death" );
self endon ( "disconnect" );
wait ( 2.0 );
self notify ( soundAlias );
}
isSpeakerInRange( player )
{
player endon ( "death" );
player endon ( "disconnect" );
distSq = 1000 * 1000;
// to prevent player switch to spectator after throwing a granade causing damage to someone and result in attacker.pers["team"] = "spectator"
if( isdefined( player ) && isdefined( player.pers["team"] ) && player.pers["team"] != "spectator" )
{
for ( index = 0; index < level._speakers[player.pers["team"]].size; index++ )
{
teammate = level._speakers[player.pers["team"]][index];
if ( teammate == player )
return true;
if ( distancesquared( teammate.origin, player.origin ) < distSq )
return true;
}
}
return false;
}
addSpeaker( player, team )
{
level._speakers[team][level._speakers[team].size] = player;
}
// this is lazy... fix up later by tracking ID's and doing array slot swapping
removeSpeaker( player, team )
{
newSpeakers = [];
for ( index = 0; index < level._speakers[team].size; index++ )
{
if ( level._speakers[team][index] == player )
continue;
newSpeakers[newSpeakers.size] = level._speakers[team][index];
}
level._speakers[team] = newSpeakers;
}

View File

@ -0,0 +1,274 @@
// Callback Setup
// This script provides the hooks from code into script for the gametype callback functions.
//=============================================================================
// Code Callback functions
/*================
Called by code after the level's main script function has run.
================*/
CodeCallback_StartGameType()
{
if( getDvar( "r_reflectionProbeGenerate" ) == "1" )
level waittill( "eternity" );
// If the gametype has not beed started, run the startup
if(!isDefined(level._gametypestarted) || !level._gametypestarted)
{
[[level._callbackStartGameType]]();
level._gametypestarted = true; // so we know that the gametype has been started up
}
}
/*================
Called when a player begins connecting to the server.
Called again for every map change or tournement restart.
Return undefined if the client should be allowed, otherwise return
a string with the reason for denial.
Otherwise, the client will be sent the current gamestate
and will eventually get to ClientBegin.
firstTime will be qtrue the very first time a client connects
to the server machine, but qfalse on map changes and tournement
restarts.
================*/
CodeCallback_PlayerConnect()
{
if( getDvar( "r_reflectionProbeGenerate" ) == "1" )
level waittill( "eternity" );
self endon("disconnect");
[[level._callbackPlayerConnect]]();
// tagGHS< BB adds >
lpselfnum = self getEntityNumber();
bbPrint( "mpjoins: name %s client %s", self.name, lpselfnum );
}
/*================
Called when a player drops from the server.
Will not be called between levels.
self is the player that is disconnecting.
================*/
CodeCallback_PlayerDisconnect()
{
self maps\mp\gametypes\_gamelogic::dump_score_board_to_black_box_for_player_bailed_early();
self notify("disconnect");
[[level._callbackPlayerDisconnect]]();
lpselfnum = self getEntityNumber();
bbPrint( "mpquits: name %s client %d", self.name, lpselfnum );
}
/*================
Called when a player has taken damage.
self is the player that took damage.
================*/
CodeCallback_PlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset)
{
self endon("disconnect");
[[level._callbackPlayerDamage]](eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset);
}
/*================
Called when a player has been killed.
self is the player that was killed.
================*/
CodeCallback_PlayerKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration)
{
self endon("disconnect");
//println( "mpattacks: victimxuid='" + self GetXUID() + "', victimweapon='" + self GetCurrentWeapon() + "'\n" );
//bbPrint( "breakpoint:" );
if(self.sessionstate != "dead")
{
attackerweaponiskillstreak = 0;
if ( maps\mp\_utility::isKillstreakWeapon( sWeapon ) )
{
attackerweaponiskillstreak = 1;
}
attackerweaponisequipment = 0;
if( maps\mp\gametypes\_weapons::isEquipment( sWeapon ) )
{
attackerweaponisequipment = 1;
}
attackerweaponisnormal = 1; // assume weapon is normal unless it's a killstreak or equipment weapon.
if( ( attackerweaponiskillstreak != 0 ) || ( attackerweaponisequipment != 0 ) )
{
attackerweaponisnormal = 0;
}
lpattackerorigin = ( 0, 0, 0 );
if(isPlayer(eAttacker))
{
lpattacknum = eAttacker getEntityNumber();
lpattackGuid = eAttacker getGuid();
lpattackname = eAttacker.name;
lpattackerteam = eAttacker.pers["team"];
lpattackerorigin = eAttacker.origin;
//println( "mpattacks: victimxuid='" + self GetXUID() + "', attackerxuid='" + eAttacker GetXUID() + "'\n" );
//bbPrint( "breakpoint:" );
bbPrint( "mpattacks: gametime %d attackerspawnid %d attackerxuid %llu attackerweapon %s attackerx %f attackery %f attackerz %f victimspawnid %d victimxuid %llu victimweapon %s victimx %f victimy %f victimz %f damage %d damagetype %s damagelocation %s death 0 attackerweaponisnormal %d attackerweaponiskillstreak %d attackerweaponisequipment %d attackersuit %s victimsuit %s",
gettime(), eAttacker getplayerspawnid(), eAttacker GetXUID(), sWeapon, lpattackerorigin, self getplayerspawnid(), self GetXUID(), self GetCurrentWeapon(), self.origin, iDamage, sMeansOfDeath, sHitLoc, attackerweaponisnormal, attackerweaponiskillstreak, attackerweaponisequipment, eAttacker.currentSuit, self.currentSuit );
}
else
{
//println( "mpattacks: victimxuid='" + self GetXUID() + "'\n" );
lpattacknum = -1;
lpattackGuid = "";
lpattackname = "";
lpattackerteam = "world";
bbPrint( "mpattacks: gametime %d attackerweapon %s victimspawnid %d victimxuid %llu victimweapon %s victimx %f victimy %f victimz %f damage %d damagetype %s damagelocation %s death 0 attackerweaponisnormal %d attackerweaponiskillstreak %d attackerweaponisequipment %d",
gettime(), sWeapon, self getplayerspawnid(), self GetXUID(), self GetCurrentWeapon(), self.origin, iDamage, sMeansOfDeath, sHitLoc, attackerweaponisnormal, attackerweaponiskillstreak, attackerweaponisequipment );
}
//bbPrint( "breakpoint:" );
}
// We need to do the bbprint before here since the level callbacks will respawn the player by the time this next line returns
[[level._callbackPlayerKilled]](eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration);
}
/*================
Called when a vehicle has taken damage.
self is the vehicle that took damage.
================*/
CodeCallback_VehicleDamage( inflictor, attacker, damage, dFlags, meansOfDeath, weapon, point, dir, hitLoc, timeOffset, modelIndex, partName )
{
if ( isDefined( self.damageCallback ) )
self [[self.damageCallback]]( inflictor, attacker, damage, dFlags, meansOfDeath, weapon, point, dir, hitLoc, timeOffset, modelIndex, partName );
else
self Vehicle_FinishDamage( inflictor, attacker, damage, dFlags, meansOfDeath, weapon, point, dir, hitLoc, timeOffset, modelIndex, partName );
}
/*================
Called when code is forcibly ending the game.
e.g. we suck as host.
================*/
CodeCallback_CodeEndGame()
{
self endon("disconnect");
[[level._callbackCodeEndGame]]();
}
/*================
Called when a player has been killed, but has last stand perk.
self is the player that was killed.
================*/
CodeCallback_PlayerLastStand(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration )
{
self endon("disconnect");
[[level._callbackPlayerLastStand]](eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration );
}
/*================
Called when a player reconnects to the server
following a host migration.
================*/
CodeCallback_PlayerMigrated()
{
self endon("disconnect");
[[level._callbackPlayerMigrated]]();
}
/*================
Called once when a host migration has occured.
================*/
CodeCallback_HostMigration()
{
[[level._callbackHostMigration]]();
}
//=============================================================================
// Damage flags used in the playerDamage callback
SetupDamageFlags()
{
// code-defined:
level._iDFLAGS_RADIUS = 1; // damage was indirect
level._iDFLAGS_NO_ARMOR = 2; // armor does not protect from this damage
level._iDFLAGS_NO_KNOCKBACK = 4; // do not affect velocity, just view angles
level._iDFLAGS_PENETRATION = 8; // damage occurred after one or more penetrations
level._iDFLAGS_STUN = 16; // non-lethal
level._iDFLAGS_SHIELD_EXPLOSIVE_IMPACT = 32; // missile impacted on the front of the victim's shield
level._iDFLAGS_SHIELD_EXPLOSIVE_IMPACT_HUGE = 64; // ...and was from a projectile with "Big Explosion" checked on.
level._iDFLAGS_SHIELD_EXPLOSIVE_SPLASH = 128; // explosive splash, somewhat deflected by the victim's shield
// script-defined:
level._iDFLAGS_NO_TEAM_PROTECTION = 256;
level._iDFLAGS_NO_PROTECTION = 512;
level._iDFLAGS_PASSTHRU = 1024;
}
/*================
Setup any misc callbacks stuff like defines and default callbacks
================*/
SetupCallbacks()
{
SetDefaultCallbacks();
SetupDamageFlags();
}
/*================
Called from the gametype script to store off the default callback functions.
This allows the callbacks to be overridden by level script, but not lost.
================*/
SetDefaultCallbacks()
{
level._callbackStartGameType = maps\mp\gametypes\_gamelogic::Callback_StartGameType;
level._callbackPlayerConnect = maps\mp\gametypes\_playerlogic::Callback_PlayerConnect;
level._callbackPlayerDisconnect = maps\mp\gametypes\_playerlogic::Callback_PlayerDisconnect;
level._callbackPlayerDamage = maps\mp\gametypes\_damage::Callback_PlayerDamage;
level._callbackPlayerKilled = maps\mp\gametypes\_damage::Callback_PlayerKilled;
level._callbackCodeEndGame = maps\mp\gametypes\_gamelogic::Callback_CodeEndGame;
level._callbackPlayerLastStand = maps\mp\gametypes\_damage::Callback_PlayerLastStand;
level._callbackPlayerMigrated = maps\mp\gametypes\_playerlogic::Callback_PlayerMigrated;
level._callbackHostMigration = maps\mp\gametypes\_hostmigration::Callback_HostMigration;
}
/*================
Called when a gametype is not supported.
================*/
AbortLevel()
{
println("Aborting level - gametype is not supported");
level._callbackStartGameType = ::callbackVoid;
level._callbackPlayerConnect = ::callbackVoid;
level._callbackPlayerDisconnect = ::callbackVoid;
level._callbackPlayerDamage = ::callbackVoid;
level._callbackPlayerKilled = ::callbackVoid;
level._callbackCodeEndGame = ::callbackVoid;
level._callbackPlayerLastStand = ::callbackVoid;
level._callbackPlayerMigrated = ::callbackVoid;
level._callbackHostMigration = ::callbackVoid;
setdvar("g_gametype", "dm");
exitLevel(false);
}
/*================
================*/
callbackVoid()
{
}

2896
maps/mp/gametypes/_class.gsc Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,94 @@
init()
{
precacheShader("damage_feedback");
precacheShader("damage_feedback_j");
precacheShader("damage_feedback_trophy");
precacheShader("damage_feedback_endgame");
precacheShader("scavenger_pickup");
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player.hud_damagefeedback = newClientHudElem(player);
player.hud_damagefeedback.horzAlign = "center";
player.hud_damagefeedback.vertAlign = "middle";
player.hud_damagefeedback.x = -12;
player.hud_damagefeedback.y = -12;
player.hud_damagefeedback.alpha = 0;
player.hud_damagefeedback.archived = true;
player.hud_damagefeedback setShader("damage_feedback", 24, 48);
}
}
updateDamageFeedback( typeHit )
{
if ( !isPlayer( self ) )
return;
x = -12;
y = -12;
if ( getDvarInt( "camera_thirdPerson" ) )
yOffset = self GetThirdPersonCrosshairOffset() * 240;
else
yOffset = getdvarfloat( "cg_crosshairVerticalOffset" ) * 240;
if ( level._splitscreen )
yOffset *= 0.5;
feedbackDurationOverride = 0;
startAlpha = 1;
if ( typeHit == "hitBodyArmor" )
{
self.hud_damagefeedback setShader("damage_feedback_trophy", 24, 48);
self playlocalsound("MP_hit_alert"); // TODO: change sound?
}
else if ( typeHit == "hitEndGame" )
{
self.hud_damagefeedback setShader("damage_feedback_endgame", 24, 48);
self playlocalsound("MP_hit_alert");
}
else if ( typeHit == "stun" )
{
return;
}
else if ( typeHit == "none" )
{
return;
}
else if ( typeHit == "scavenger" && !level._hardcoreMode )
{
x = -36;
y = 32;
self.hud_damagefeedback setShader("scavenger_pickup", 64, 32);
feedbackDurationOverride = 2.5;
}
else
{
self.hud_damagefeedback setShader("damage_feedback", 24, 48);
self playlocalsound("MP_hit_alert");
}
self.hud_damagefeedback.alpha = startAlpha;
if ( feedBackDurationOverride != 0 )
self.hud_damagefeedback fadeOverTime(feedbackDurationOverride);
else
self.hud_damagefeedback fadeOverTime(1);
self.hud_damagefeedback.alpha = 0;
// only update hudelem positioning when necessary
if ( self.hud_damagefeedback.x != x )
self.hud_damagefeedback.x = x;
y = y - int( yOffset );
if ( self.hud_damagefeedback.y != y )
self.hud_damagefeedback.y = y;
}

View File

@ -0,0 +1,87 @@
#include maps\mp\_utility;
init()
{
if (!level._teambased)
return;
precacheShader("headicon_dead");
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player.selfDeathIcons = []; // icons that other people see which point to this player when he's dead
}
}
updateDeathIconsEnabled()
{
//if (!self.enableDeathIcons)
// self removeOtherDeathIcons();
}
addDeathIcon( entity, dyingplayer, team, timeout )
{
if ( !level._teambased )
return;
//tagZP<TODO> fix death icons in MTDM
if( level._multiTeamBased )
{
println( "tagZP<TODO> Fix death icons in MTMD" );
return;
}
iconOrg = entity.origin;
dyingplayer endon("spawned_player");
dyingplayer endon("disconnect");
wait .05;
WaitTillSlowProcessAllowed();
assert(team == "allies" || team == "axis");
if ( getDvar( "ui_hud_showdeathicons" ) == "0" )
return;
if ( level._hardcoreMode )
return;
if ( isdefined( self.lastDeathIcon ) )
self.lastDeathIcon destroy();
newdeathicon = newTeamHudElem( team );
newdeathicon.x = iconOrg[0];
newdeathicon.y = iconOrg[1];
newdeathicon.z = iconOrg[2] + 54;
newdeathicon.alpha = .61;
newdeathicon.archived = true;
if ( level._splitscreen )
newdeathicon setShader("headicon_dead", 14, 14);
else
newdeathicon setShader("headicon_dead", 7, 7);
newdeathicon setwaypoint( true, false );
self.lastDeathIcon = newdeathicon;
newdeathicon thread destroySlowly ( timeout );
}
destroySlowly( timeout )
{
self endon("death");
wait timeout;
self fadeOverTime(1.0);
self.alpha = 0;
wait 1.0;
self destroy();
}

1661
maps/mp/gametypes/_dev.gsc Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,120 @@
init()
{
// Draws a team icon over teammates
level._drawfriend = 0;
game["headicon_allies"] = maps\mp\gametypes\_teams::getTeamHeadIcon( "allies" );
game["headicon_axis"] = maps\mp\gametypes\_teams::getTeamHeadIcon( "axis" );
precacheHeadIcon( game["headicon_allies"] );
precacheHeadIcon( game["headicon_axis"] );
precacheShader( "waypoint_revive" );
level thread onPlayerConnect();
for(;;)
{
updateFriendIconSettings();
wait 5;
}
}
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player thread onPlayerSpawned();
player thread onPlayerKilled();
}
}
onPlayerSpawned()
{
self endon("disconnect");
for(;;)
{
self waittill("spawned_player");
self thread showFriendIcon();
}
}
onPlayerKilled()
{
self endon("disconnect");
for(;;)
{
self waittill("killed_player");
self.headicon = "";
}
}
showFriendIcon()
{
if(level._drawfriend)
{
if(self.pers["team"] == "allies")
{
self.headicon = game["headicon_allies"];
self.headiconteam = "allies";
}
else
{
self.headicon = game["headicon_axis"];
self.headiconteam = "axis";
}
}
}
updateFriendIconSettings()
{
drawfriend = maps\mp\_utility::getIntProperty("scr_drawfriend", level._drawfriend);
if(level._drawfriend != drawfriend)
{
level._drawfriend = drawfriend;
updateFriendIcons();
}
}
updateFriendIcons()
{
// for all living players, show the appropriate headicon
players = level._players;
for(i = 0; i < players.size; i++)
{
player = players[i];
if(isDefined(player.pers["team"]) && player.pers["team"] != "spectator" && player.sessionstate == "playing")
{
if(level._drawfriend)
{
if(player.pers["team"] == "allies")
{
player.headicon = game["headicon_allies"];
player.headiconteam = "allies";
}
else
{
player.headicon = game["headicon_axis"];
player.headiconteam = "axis";
}
}
else
{
players = level._players;
for(i = 0; i < players.size; i++)
{
player = players[i];
if(isDefined(player.pers["team"]) && player.pers["team"] != "spectator" && player.sessionstate == "playing")
player.headicon = "";
}
}
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,529 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
getHighestScoringPlayer()
{
updatePlacement();
if ( !level._placement["all"].size )
return ( undefined );
else
return ( level._placement["all"][0] );
}
getLosingPlayers()
{
updatePlacement();
players = level._placement["all"];
losingPlayers = [];
foreach ( player in players )
{
if ( player == level._placement["all"][0] )
continue;
losingPlayers[losingPlayers.size] = player;
}
return losingPlayers;
}
givePlayerScore( event, player, victim, overrideCheckPlayerScoreLimitSoon )
{
if ( isDefined( level._nukeIncoming ) )
return;
score = player.pers["score"];
onPlayerScore( event, player, victim );
if ( score == player.pers["score"] )
return;
if ( !player rankingEnabled() && !level._hardcoreMode )
player thread maps\mp\gametypes\_rank::scorePopup( (player.pers["score"] - score), false, (0.85,0.85,0.85), 0 );
player maps\mp\gametypes\_persistence::statAdd( "score", (player.pers["score"] - score) );
if( getDvarInt( "prototype_adrenaline_enabled" ) == 1 )
{
player maps\mp\_adrenaline::adrenalineAddScore( (player.pers["score"] - score) );
}
player.score = player.pers["score"];
player maps\mp\gametypes\_persistence::statSetChild( "round", "score", player.score );
if ( !level._teambased )
thread sendUpdatedDMScores();
// tagJC<NOTE>: In game mode where winning is not dependent on players' or team's score, it is unnecessary to check whether
// the score limit will be reached soon.
if ( !isDefined( overrideCheckPlayerScoreLimitSoon ) || !overrideCheckPlayerScoreLimitSoon )
player maps\mp\gametypes\_gamelogic::checkPlayerScoreLimitSoon();
scoreEndedMatch = player maps\mp\gametypes\_gamelogic::checkScoreLimit();
if ( scoreEndedMatch && event == "kill" )
player.finalKill = true;
}
onPlayerScore( event, player, victim )
{
score = maps\mp\gametypes\_rank::getScoreInfoValue( event );
assert( isDefined( score ) );
player.pers["score"] += score * level._objectivePointsMod;
}
// Seems to only be used for reducing a player's score due to suicide
_setPlayerScore( player, score )
{
if ( score == player.pers["score"] )
return;
player.pers["score"] = score;
player.score = player.pers["score"];
player thread maps\mp\gametypes\_gamelogic::checkScoreLimit();
}
_getPlayerScore( player )
{
return player.pers["score"];
}
giveTeamScoreForObjective( team, score )
{
if ( isDefined( level._nukeIncoming ) )
return;
score *= level._objectivePointsMod;
teamScore = game["teamScores"][team];
/*
otherTeam = level._otherTeam[team];
if ( game["teamScores"][team] > game["teamScores"][otherTeam] )
level._wasWinning = team;
else if ( game["teamScores"][otherTeam] > game["teamScores"][team] )
level._wasWinning = otherTeam;
*/
level._wasWinning = getWinningTeam();
_setTeamScore( team, _getTeamScore( team ) + score );
isWinning = getWinningTeam();
/*
isWinning = "none";
if ( game["teamScores"][team] > game["teamScores"][otherTeam] )
isWinning = team;
else if ( game["teamScores"][otherTeam] > game["teamScores"][team] )
isWinning = otherTeam;
*/
if ( !level._splitScreen && isWinning != "none" && isWinning != level._wasWinning && getTime() - level._lastStatusTime > 5000 && getScoreLimit() != 1 )
{
level._lastStatusTime = getTime();
leaderDialog( "lead_taken", isWinning, "status" );
if ( level._wasWinning != "none")
leaderDialog( "lead_lost", level._wasWinning, "status" );
}
if ( isWinning != "none" )
level._wasWinning = isWinning;
}
getWinningTeam()
{
//if( level._multiTeamBased == true )
//{
winning_team = level._teamNameList[0];
winning_score = game["teamScores"][level._teamNameList[0]];
num_teams_tied_for_winning = 1;
for( i = 1; i < level._teamNameList.size; i++ )
{
if( game["teamScores"][level._teamNameList[i]] > winning_score )
{
//new winning team found
winning_team = level._teamNameList[i];
winning_score = game["teamScores"][level._teamNameList[i]];
num_teams_tied_for_winning = 1;
}
else if( game["teamScores"][level._teamNameList[i]] == winning_score )
{
num_teams_tied_for_winning = num_teams_tied_for_winning + 1;
winning_team = "none";
}
}
return( winning_team );
//}
/*
if ( game["teamScores"]["allies"] > game["teamScores"]["axis"] )
return ( "allies" );
else if ( game["teamScores"]["allies"] < game["teamScores"]["axis"] )
return ( "axis" );
*/
return ( "none" );
}
_setTeamScore( team, teamScore )
{
if ( teamScore == game["teamScores"][team] )
return;
if ( isDefined( level._nukeIncoming ) )
return;
game["teamScores"][team] = teamScore;
updateTeamScore( team );
if ( game["status"] == "overtime" )
thread [[level._onScoreLimit]]();
else
{
thread maps\mp\gametypes\_gamelogic::checkTeamScoreLimitSoon( team );
thread maps\mp\gametypes\_gamelogic::checkScoreLimit();
}
}
updateTeamScore( team )
{
assert( level._teamBased );
teamScore = 0;
if ( !isRoundBased() || !isObjectiveBased() )
teamScore = _getTeamScore( team );
else
teamScore = game["roundsWon"][team];
setTeamScore( team, teamScore );
//thread sendUpdatedTeamScores();
}
_getTeamScore( team )
{
return game["teamScores"][team];
}
sendUpdatedTeamScores()
{
level notify("updating_scores");
level endon("updating_scores");
wait .05;
WaitTillSlowProcessAllowed();
foreach ( player in level._players )
player updateScores();
}
sendUpdatedDMScores()
{
level notify("updating_dm_scores");
level endon("updating_dm_scores");
wait .05;
WaitTillSlowProcessAllowed();
for ( i = 0; i < level._players.size; i++ )
{
level._players[i] updateDMScores();
level._players[i].updatedDMScores = true;
}
}
removeDisconnectedPlayerFromPlacement()
{
offset = 0;
numPlayers = level._placement["all"].size;
found = false;
for ( i = 0; i < numPlayers; i++ )
{
if ( level._placement["all"][i] == self )
found = true;
if ( found )
level._placement["all"][i] = level._placement["all"][ i + 1 ];
}
if ( !found )
return;
level._placement["all"][ numPlayers - 1 ] = undefined;
assert( level._placement["all"].size == numPlayers - 1 );
if( level._multiTeamBased )
{
MTDM_updateTeamPlacement();
}
else if ( level._teamBased )
{
updateTeamPlacement();
return;
}
numPlayers = level._placement["all"].size;
for ( i = 0; i < numPlayers; i++ )
{
player = level._placement["all"][i];
player notify( "update_outcome" );
}
}
updatePlacement()
{
prof_begin("updatePlacement");
placementAll = [];
foreach ( player in level._players )
{
if ( isDefined( player.connectedPostGame ))
{
continue;
}
if( player.pers["team"] == "spectator" )
{
continue;
}
if( player.pers["team"] == "none" )
{
continue;
}
placementAll[placementAll.size] = player;
}
for ( i = 1; i < placementAll.size; i++ )
{
player = placementAll[i];
playerScore = player.score;
// for ( j = i - 1; j >= 0 && (player.score > placementAll[j].score || (player.score == placementAll[j].score && player.deaths < placementAll[j].deaths)); j-- )
for ( j = i - 1; j >= 0 && getBetterPlayer( player, placementAll[j] ) == player; j-- )
placementAll[j + 1] = placementAll[j];
placementAll[j + 1] = player;
}
level._placement["all"] = placementAll;
if( level._multiTeamBased )
{
MTDM_updateTeamPlacement();
}
else if ( level._teamBased )
{
updateTeamPlacement();
}
prof_end("updatePlacement");
}
getBetterPlayer( playerA, playerB )
{
if ( playerA.score > playerB.score )
return playerA;
if ( playerB.score > playerA.score )
return playerB;
if ( playerA.deaths < playerB.deaths )
return playerA;
if ( playerB.deaths < playerA.deaths )
return playerB;
// TODO: more metrics for getting the better player
if ( cointoss() )
return playerA;
else
return playerB;
}
updateTeamPlacement()
{
placement["allies"] = [];
placement["axis"] = [];
placement["spectator"] = [];
assert( level._teamBased );
placementAll = level._placement["all"];
placementAllSize = placementAll.size;
for ( i = 0; i < placementAllSize; i++ )
{
player = placementAll[i];
team = player.pers["team"];
placement[team][ placement[team].size ] = player;
}
level._placement["allies"] = placement["allies"];
level._placement["axis"] = placement["axis"];
}
//TagZP<TODO> consolidate with updateTeamPlacement()
MTDM_updateTeamPlacement()
{
placement["spectator"] = [];
foreach( teamname in level._teamNameList )
{
placement[teamname] = [];
}
assert( level._multiTeamBased );
placementAll = level._placement["all"];
placementAllSize = placementAll.size;
for ( i = 0; i < placementAllSize; i++ )
{
player = placementAll[i];
team = player.pers["team"];
placement[team][ placement[team].size ] = player;
}
foreach( teamname in level._teamNameList )
{
level._placement[teamname] = placement[teamname];
}
}
initialDMScoreUpdate()
{
// the first time we call updateDMScores on a player, we have to send them the whole scoreboard.
// by calling updateDMScores on each player one at a time,
// we can avoid having to send the entire scoreboard to every single player
// the first time someone kills someone else.
wait .2;
numSent = 0;
while(1)
{
didAny = false;
players = level._players;
for ( i = 0; i < players.size; i++ )
{
player = players[i];
if ( !isdefined( player ) )
continue;
if ( isdefined( player.updatedDMScores ) )
continue;
player.updatedDMScores = true;
player updateDMScores();
didAny = true;
wait .5;
}
if ( !didAny )
wait 3; // let more players connect
}
}
processAssist( killedplayer )
{
self endon("disconnect");
killedplayer endon("disconnect");
wait .05; // don't ever run on the same frame as the playerkilled callback.
WaitTillSlowProcessAllowed();
if( !level._multiteambased )
{
if ( self.pers["team"] != "axis" && self.pers["team"] != "allies" )
{
return;
}
}
if ( self.pers["team"] == killedplayer.pers["team"] )
return;
damagedone = killedplayer.attackerData[self.guid].damage;
// If the attacker has conducted some damages using any grenades with lasting effect, the player should receive a minimum reward that is not porpotional to the damages done
playerMaxHealth = getDvarInt ( "scr_player_maxhealth" );
//Assuming there are four levels for assist rewards, divide player's max health by 4 to get the amount of damage per assist level
damagePerAssistLevel = playerMaxHealth / 4;
if ( isDefined ( killedplayer.attackerData[self.guid].isGrenadeWithLastingEffect ) && killedplayer.attackerData[self.guid].isGrenadeWithLastingEffect == true )
{
if ( damagedone <= 50 )
{
assist_event = "assist_grenade";
}
else
{
assist_event = "assist_level_" + int( ceil( damagedone / damagePerAssistLevel ) );
}
}
else
{
assist_event = "assist_level_" + int( ceil( damagedone / damagePerAssistLevel ) );
}
self thread [[level._onXPEvent]]( assist_event );
self incPersStat( "assists", 1 );
self.assists = self getPersStat( "assists" );
self incPlayerStat( "assists", 1 );
givePlayerScore( assist_event, self, killedplayer );
self thread giveAdrenaline( "assist" );
self thread maps\mp\gametypes\_missions::playerAssist();
}
processShieldAssist( killedPlayer )
{
self endon( "disconnect" );
killedPlayer endon( "disconnect" );
wait .05; // don't ever run on the same frame as the playerkilled callback.
WaitTillSlowProcessAllowed();
if ( self.pers["team"] != "axis" && self.pers["team"] != "allies" )
return;
if ( self.pers["team"] == killedplayer.pers["team"] )
return;
self thread [[level._onXPEvent]]( "assist" );
self thread [[level._onXPEvent]]( "assist" );
self incPersStat( "assists", 1 );
self.assists = self getPersStat( "assists" );
self incPlayerStat( "assists", 1 );
givePlayerScore( "assist", self, killedplayer );
self thread maps\mp\gametypes\_hud_message::SplashNotifyDelayed( "shield_assist" );
self thread maps\mp\gametypes\_missions::playerAssist();
}

View File

@ -0,0 +1,279 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
init()
{
level._splitscreen = isSplitScreen();
level._ps3 = (getDvar( "ps3Game" ) == "true");
level._xenon = (getDvar( "xenonGame" ) == "true");
level._console = (level._ps3 || level._xenon);
level._onlineGame = getDvarInt( "onlinegame" );
level._rankedMatch = ( !level._onlineGame || !getDvarInt( "xblive_privatematch" ) );
if ( !level._console )
{
if ( !getDvarInt( "sv_pure" ) )
{
oldvalue = level._rankedMatch;
level._rankedMatch = false;
/#
level._rankedMatch = oldvalue;
#/
}
}
/#
if ( getdvarint( "scr_forcerankedmatch" ) == 1 )
{
level._onlineGame = true;
level._rankedMatch = true;
}
#/
level._script = toLower( getDvar( "mapname" ) );
level._gametype = toLower( getDvar( "g_gametype" ) );
//TagZP<NOTE>blocking this out in MTDM will force crashes/asserts where these are used. So nothing slips by.
if( level._gametype != "mtdm" )
{
level._otherTeam["allies"] = "axis";
level._otherTeam["axis"] = "allies";
}
level._maxNumTeams = 2;
level._teamNameList = ["allies", "axis"];
level._teamBased = false;
level._multiTeamBased = false;
level._objectiveBased = false;
level._endGameOnTimeLimit = true;
level._showingFinalKillcam = false;
level._tiSpawnDelay = getDvarInt( "scr_tispawndelay" );
// hack to allow maps with no scripts to run correctly
if ( !isDefined( level._tweakablesInitialized ) )
maps\mp\gametypes\_tweakables::init();
precacheString( &"MP_HALFTIME" );
precacheString( &"MP_OVERTIME" );
precacheString( &"MP_ROUNDEND" );
precacheString( &"MP_INTERMISSION" );
precacheString( &"MP_SWITCHING_SIDES" );
precacheString( &"MP_FRIENDLY_FIRE_WILL_NOT" );
precacheString( &"PLATFORM_REVIVE" );
precacheString( &"MP_OBITUARY_NEUTRAL" );
precacheString( &"MP_OBITUARY_FRIENDLY" );
precacheString( &"MP_OBITUARY_ENEMY" );
if ( level._splitScreen )
precacheString( &"MP_ENDED_GAME" );
else
precacheString( &"MP_HOST_ENDED_GAME" );
level._halftimeType = "halftime";
level._halftimeSubCaption = &"MP_SWITCHING_SIDES";
level._lastStatusTime = 0;
level._wasWinning = "none";
level._lastSlowProcessFrame = 0;
for( i = 0; i < level._teamNameList.size; i++ )
{
level._placement[level._teamNameList[i]] = [];
}
level._placement["all"] = [];
/*
level._placement["allies"] = [];
level._placement["axis"] = [];
level._placement["all"] = [];
*/
level._postRoundTime = 5.0;
level._playersLookingForSafeSpawn = [];
registerDvars();
precacheModel( "vehicle_mig29_desert" );
precacheModel( "projectile_cbu97_clusterbomb" );
precacheModel( "tag_origin" );
level._fx_airstrike_afterburner = loadfx ("fire/jet_afterburner");
level._fx_airstrike_contrail = loadfx ("smoke/jet_contrail");
if ( level._console )
precacheLeaderboards( "LB_KILLS LB_WINS LB_TOTALXP LB_ACCURACY" );
for( i = 0; i < level._teamNameList.size; i++ )
{
level._teamCount[level._teamNameList[i]] = 0;
level._aliveCount[level._teamNameList[i]] = 0;
level._livesCount[level._teamNameList[i]] = 0;
level._hasSpawned[level._teamNameList[i]] = 0;
}
level._teamCount["spectator"] = 0;
level._aliveCount["spectator"] = 0;
level._oneLeftTime = [];
/#
if ( getdvarint( "scr_runlevelandquit" ) == 1 )
{
thread runLevelAndQuit();
}
#/
}
/#
runLevelAndQuit()
{
wait 1;
while ( level._players.size < 1 )
{
wait 0.5;
}
wait 0.5;
level notify( "game_ended" );
exitLevel();
}
#/
registerDvars()
{
makeDvarServerInfo( "ui_bomb_timer", 0 );
makeDvarServerInfo( "ui_danger_team", "" );
}
SetupCallbacks()
{
level._onXPEvent = ::onXPEvent;
level._getSpawnPoint = ::blank;
level._onSpawnPlayer = ::blank;
level._onRespawnDelay = ::blank;
level._onTimeLimit = maps\mp\gametypes\_gamelogic::default_onTimeLimit;
level._onScoreLimit = maps\mp\gametypes\_gamelogic::default_onScoreLimit;
level._onHalfTime = maps\mp\gametypes\_gamelogic::default_onHalfTime;
level._onDeadEvent = maps\mp\gametypes\_gamelogic::default_onDeadEvent;
level._onOneLeftEvent = maps\mp\gametypes\_gamelogic::default_onOneLeftEvent;
level._onPrecacheGametype = ::blank;
level._onStartGameType = ::blank;
level._onPlayerKilled = ::blank;
level._autoassign = maps\mp\gametypes\_menus::menuAutoAssign;
level._spectator = maps\mp\gametypes\_menus::menuSpectator;
level._class = maps\mp\gametypes\_menus::menuClass;
level._onTeamSelection = maps\mp\gametypes\_menus::onMenuTeamSelect;
}
blank( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 )
{
}
/#
xpRateThread()
{
self endon ( "death" );
self endon ( "disconnect" );
level endon ( "game_ended" );
gameFlagWait( "prematch_done" );
for ( ;; )
{
wait ( 5.0 );
if ( level._players[0].pers["team"] == "allies" || level._players[0].pers["team"] == "axis" )
self maps\mp\gametypes\_rank::giveRankXP( "kill", int(min( getDvarInt( "scr_xprate" ), 50 )) );
}
}
#/
testMenu()
{
self endon ( "death" );
self endon ( "disconnect" );
for ( ;; )
{
wait ( 10.0 );
notifyData = spawnStruct();
notifyData.titleText = &"MP_CHALLENGE_COMPLETED";
notifyData.notifyText = "wheee";
notifyData.sound = "mp_challenge_complete";
self thread maps\mp\gametypes\_hud_message::notifyMessage( notifyData );
}
}
testShock()
{
self endon ( "death" );
self endon ( "disconnect" );
for ( ;; )
{
wait ( 3.0 );
numShots = randomInt( 6 );
for ( i = 0; i < numShots; i++ )
{
iPrintLnBold( numShots );
self shellShock( "frag_grenade_mp", 0.2 );
wait ( 0.1 );
}
}
}
onXPEvent( event )
{
//self thread maps\mp\_loot::giveMoney( event, 10 );
self thread maps\mp\gametypes\_rank::giveRankXP( event );
}
fakeLag()
{
self endon ( "disconnect" );
self.fakeLag = randomIntRange( 50, 150 );
for ( ;; )
{
self setClientDvar( "fakelag_target", self.fakeLag );
wait ( randomFloatRange( 5.0, 15.0 ) );
}
}
debugLine( start, end )
{
for ( i = 0; i < 50; i++ )
{
line( start, end );
wait .05;
}
}

View File

@ -0,0 +1,235 @@
#include maps\mp\_utility;
init()
{
level._healthOverlayCutoff = 0.55;
regenTime = 5;
regenTime = maps\mp\gametypes\_tweakables::getTweakableValue( "player", "healthregentime" );
regenRatePercent = 10;
regenRatePercent = maps\mp\gametypes\_tweakables::getTweakableValue( "player", "healthregenratepercent" );
level._playerHealth_RegularRegenDelay = regenTime * 1000;
level._playerHealth_RegenRate = 1.0 / regenRatePercent;
level._healthRegenDisabled = (level._playerHealth_RegularRegenDelay <= 0);
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player thread onPlayerSpawned();
}
}
onPlayerSpawned()
{
self endon("disconnect");
self.healthRegenDelay = level._playerHealth_RegularRegenDelay;
self.healthRegenRate = level._playerHealth_RegenRate;
for(;;)
{
self waittill("spawned_player");
self thread playerHealthRegen();
self thread showTempDamage();
}
}
showTempDamage()
{
self endon ( "death" );
self endon ( "disconnect" );
/#
setDevDvar( "scr_damage_wait", 0 );
setDevDvar( "scr_damage_fadein", 0.25 );
setDevDvar( "scr_damage_fadeout", 0.5 );
setDevDvar( "scr_damage_holdtime", 0.5 );
setDevDvar( "scr_damage_numfades", 5 );
for ( ;; )
{
while ( getDvarFloat( "scr_damage_wait" ) <= 0 )
wait ( 1.0 );
wait ( getDvarFloat( "scr_damage_wait" ) );
for ( i = 0; i < getDvarInt( "scr_damage_numfades" ); i++ )
{
self VisionSetNakedForPlayer( "mp_crash_damage", getDvarFloat( "scr_damage_fadein" ) * (getDvarInt( "scr_damage_numfades" ) - i) );
wait ( getDvarFloat( "scr_damage_fadein" ) + getDvarFloat( "scr_damage_holdtime" ) );
self VisionSetNakedForPlayer( "mp_crash", getDvarFloat( "scr_damage_fadeout" ) * getDvarInt( "scr_damage_numfades" ) );
wait ( getDvarFloat( "scr_damage_fadeout" ) );
}
}
#/
}
playerHealthRegen()
{
self endon ( "death" );
self endon ( "disconnect" );
self endon ( "joined_team" );
self endon ( "joined_spectators" );
if ( self.health <= 0 )
{
assert( !isalive( self ) );
return;
}
oldhealth = self.maxhealth;
regenRate = 0.1;
veryHurt = false;
self.breathingStopTime = -10000;
thread playerBreathingSound( self.maxhealth * 0.35 );
lastSoundTime_Recover = 0;
hurtTime = 0;
newHealth = 0;
for (;;)
{
wait ( 0.05 );
if ( isDefined( level._hostMigrationTimer ) )
{
timePassed = maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
hurtTime += timePassed;
lastSoundTime_Recover += timePassed;
}
if ( self.health == self.maxhealth || ( level._dieHardMode && isDefined( self.healthClamped ) && self.health >= self.healthClamped ) ) // runs every frame
{
oldHealth = self.maxhealth;
veryHurt = false;
self.atBrinkOfDeath = false;
continue;
}
if ( self.health <= 0 ) // player dead
return;
curTime = getTime();
ratio = self.health / self.maxHealth;
if ( ratio <= level._healthOverlayCutoff )
{
if ( !veryHurt )
hurtTime = curTime;
veryHurt = true;
self.atBrinkOfDeath = true;
}
if ( self.health >= oldhealth )
{
if ( curTime - hurtTime < self.healthRegenDelay )
{
continue;
}
if ( level._healthRegenDisabled )
{
wait ( 3.0 );
self.maxHealth = int( max( self.health, 2 ) );
self.health = self.maxHealth;
continue;
}
if ( curTime - lastSoundTime_Recover > self.healthRegenDelay )
{
lastSoundTime_Recover = curTime;
if ( !level._gameEnded )
self playLocalSound("breathing_better");
}
if ( veryHurt )
{
newHealth = ratio;
if ( curTime > hurtTime + 3000 )
{
newHealth += self.healthRegenRate;
}
}
else
{
newHealth = 1;
}
if ( newHealth >= 1.0 )
{
if ( veryHurt )
{
self maps\mp\gametypes\_missions::healthRegenerated();
}
self maps\mp\gametypes\_damage::resetAttackerList();
newHealth = 1.0;
}
if (newHealth <= 0)
{
// Player is dead
return;
}
self setNormalHealth (newHealth);
oldHealth = self.health;
continue;
}
// first time damaged
oldHealth = self.health;
hurtTime = curTime;
self.breathingStopTime = hurtTime + 6000;
}
}
playerBreathingSound( healthcap )
{
level endon ( "game_ended" );
self endon ( "death" );
self endon ( "disconnect" );
self endon ( "joined_team" );
self endon ( "joined_spectators" );
wait ( 2 );
for (;;)
{
wait ( 0.2 );
if ( self.health <= 0 )
return;
// Player still has a lot of health so no breathing sound
if ( self.health >= healthcap )
continue;
if ( level._healthRegenDisabled && gettime() > self.breathingStopTime )
continue;
self playLocalSound( "breathing_hurt" );
wait ( .784 );
wait ( 0.1 + randomfloat (0.8) );
}
}

View File

@ -0,0 +1,167 @@
#include maps\mp\_utility;
#include common_scripts\utility;
Callback_HostMigration()
{
level._hostMigrationReturnedPlayerCount = 0;
if ( level._gameEnded )
{
println( "Migration starting at time " + gettime() + ", but game has ended, so no countdown." );
return;
}
println( "Migration starting at time " + gettime() );
level._hostMigrationTimer = true;
level notify( "host_migration_begin" );
maps\mp\gametypes\_gamelogic::UpdateTimerPausedness();
foreach ( player in level._players )
{
player thread hostMigrationTimerThink();
}
level endon( "host_migration_begin" );
hostMigrationWait();
level._hostMigrationTimer = undefined;
println( "Migration finished at time " + gettime() );
level notify( "host_migration_end" );
maps\mp\gametypes\_gamelogic::UpdateTimerPausedness();
}
hostMigrationWait()
{
level endon( "game_ended" );
level endon( "nuke_death" );
// start with a 20 second wait.
// once we get enough players, or the first 15 seconds pass, switch to a 5 second timer.
thread maps\mp\gametypes\_gamelogic::matchStartTimerConsole( "waiting_for_players", 20.0 );
hostMigrationWaitForPlayers();
thread maps\mp\gametypes\_gamelogic::matchStartTimerConsole( "match_resuming_in", 5.0 );
wait 5;
}
hostMigrationWaitForPlayers()
{
level endon( "hostmigration_enoughplayers" );
wait 15;
}
hostMigrationTimerThink_Internal()
{
level endon( "host_migration_begin" );
level endon( "host_migration_end" );
self.hostMigrationControlsFrozen = false;
while ( !isReallyAlive( self ) )
{
self waittill( "spawned" );
}
self.hostMigrationControlsFrozen = true;
self freezeControlsWrapper( true );
level waittill( "host_migration_end" );
}
hostMigrationTimerThink()
{
self endon( "disconnect" );
self setClientDvar( "cg_scoreboardPingGraph", "0" );
hostMigrationTimerThink_Internal();
if ( self.hostMigrationControlsFrozen )
self freezeControlsWrapper( false );
self setClientDvar( "cg_scoreboardPingGraph", "1" );
}
waitTillHostMigrationDone()
{
if ( !isDefined( level._hostMigrationTimer ) )
return 0;
starttime = gettime();
level waittill( "host_migration_end" );
return gettime() - starttime;
}
waitTillHostMigrationStarts( duration )
{
if ( isDefined( level._hostMigrationTimer ) )
return;
level endon( "host_migration_begin" );
wait duration;
}
waitLongDurationWithHostMigrationPause( duration )
{
if ( duration == 0 )
return;
assert( duration > 0 );
starttime = gettime();
endtime = gettime() + duration * 1000;
while ( gettime() < endtime )
{
waitTillHostMigrationStarts( (endtime - gettime()) / 1000 );
if ( isDefined( level._hostMigrationTimer ) )
{
timePassed = waitTillHostMigrationDone();
endtime += timePassed;
}
}
assert( gettime() == endtime );
waitTillHostMigrationDone();
return gettime() - starttime;
}
waitLongDurationWithGameEndTimeUpdate( duration )
{
if ( duration == 0 )
return;
assert( duration > 0 );
starttime = gettime();
endtime = gettime() + duration * 1000;
while ( gettime() < endtime )
{
waitTillHostMigrationStarts( (endtime - gettime()) / 1000 );
while ( isDefined( level._hostMigrationTimer ) )
{
endTime += 1000;
setGameEndTime( int( endTime ) );
wait 1;
}
}
assert( gettime() == endtime );
while ( isDefined( level._hostMigrationTimer ) )
{
endTime += 1000;
setGameEndTime( int( endTime ) );
wait 1;
}
return gettime() - starttime;
}

160
maps/mp/gametypes/_hud.gsc Normal file
View File

@ -0,0 +1,160 @@
// Edge relative placement values for rect->h_align and rect->v_align
#define HORIZONTAL_ALIGN_SUBLEFT 0 // left edge of a 4:3 screen (safe area not included)
#define HORIZONTAL_ALIGN_LEFT 1 // left viewable (safe area) edge
#define HORIZONTAL_ALIGN_CENTER 2 // center of the screen (reticle)
#define HORIZONTAL_ALIGN_RIGHT 3 // right viewable (safe area) edge
#define HORIZONTAL_ALIGN_FULLSCREEN 4 // disregards safe area
#define HORIZONTAL_ALIGN_NOSCALE 5 // uses exact parameters - neither adjusts for safe area nor scales for screen size
#define HORIZONTAL_ALIGN_TO640 6 // scales a real-screen resolution x down into the 0 - 640 range
#define HORIZONTAL_ALIGN_CENTER_SAFEAREA 7 // center of the safearea
#define HORIZONTAL_ALIGN_MAX HORIZONTAL_ALIGN_CENTER_SAFEAREA
#define HORIZONTAL_ALIGN_DEFAULT HORIZONTAL_ALIGN_SUBLEFT
#define VERTICAL_ALIGN_SUBTOP 0 // top edge of the 4:3 screen (safe area not included)
#define VERTICAL_ALIGN_TOP 1 // top viewable (safe area) edge
#define VERTICAL_ALIGN_CENTER 2 // center of the screen (reticle)
#define VERTICAL_ALIGN_BOTTOM 3 // bottom viewable (safe area) edge
#define VERTICAL_ALIGN_FULLSCREEN 4 // disregards safe area
#define VERTICAL_ALIGN_NOSCALE 5 // uses exact parameters - neither adjusts for safe area nor scales for screen size
#define VERTICAL_ALIGN_TO480 6 // scales a real-screen resolution y down into the 0 - 480 range
#define VERTICAL_ALIGN_CENTER_SAFEAREA 7 // center of the save area
#define VERTICAL_ALIGN_MAX VERTICAL_ALIGN_CENTER_SAFEAREA
#define VERTICAL_ALIGN_DEFAULT VERTICAL_ALIGN_SUBTOP
static const char *g_he_font[] =
{
"default", // HE_FONT_DEFAULT
"bigfixed", // HE_FONT_BIGFIXED
"smallfixed", // HE_FONT_SMALLFIXED
"objective", // HE_FONT_OBJECTIVE
};
// These values correspond to the defines in q_shared.h
static const char *g_he_alignx[] =
{
"left", // HE_ALIGN_LEFT
"center", // HE_ALIGN_CENTER
"right", // HE_ALIGN_RIGHT
};
static const char *g_he_aligny[] =
{
"top", // HE_ALIGN_TOP
"middle", // HE_ALIGN_MIDDLE
"bottom", // HE_ALIGN_BOTTOM
};
// These values correspond to the defines in menudefinition.h
static const char *g_he_horzalign[] =
{
"subleft", // HORIZONTAL_ALIGN_SUBLEFT
"left", // HORIZONTAL_ALIGN_LEFT
"center", // HORIZONTAL_ALIGN_CENTER
"right", // HORIZONTAL_ALIGN_RIGHT
"fullscreen", // HORIZONTAL_ALIGN_FULLSCREEN
"noscale", // HORIZONTAL_ALIGN_NOSCALE
"alignto640", // HORIZONTAL_ALIGN_TO640
"center_safearea", // HORIZONTAL_ALIGN_CENTER_SAFEAREA
};
cassert( ARRAY_COUNT( g_he_horzalign ) == HORIZONTAL_ALIGN_MAX + 1 );
static const char *g_he_vertalign[] =
{
"subtop", // VERTICAL_ALIGN_SUBTOP
"top", // VERTICAL_ALIGN_TOP
"middle", // VERTICAL_ALIGN_CENTER
"bottom", // VERTICAL_ALIGN_BOTTOM
"fullscreen", // VERTICAL_ALIGN_FULLSCREEN
"noscale", // VERTICAL_ALIGN_NOSCALE
"alignto480", // VERTICAL_ALIGN_TO480
"center_safearea", // VERTICAL_ALIGN_CENTER_SAFEAREA
};
cassert( ARRAY_COUNT( g_he_vertalign ) == VERTICAL_ALIGN_MAX + 1 );
*/
init()
{
precacheShader( "progress_bar_bg" );
precacheShader( "progress_bar_fg" );
precacheShader( "progress_bar_fill" );
level._uiParent = spawnstruct();
level._uiParent.horzAlign = "left";
level._uiParent.vertAlign = "top";
level._uiParent.alignX = "left";
level._uiParent.alignY = "top";
level._uiParent.x = 0;
level._uiParent.y = 0;
level._uiParent.width = 0;
level._uiParent.height = 0;
level._uiParent.children = [];
level._fontHeight = 12;
level._hud["allies"] = spawnstruct();
level._hud["axis"] = spawnstruct();
// we can, of course, separate out the following constants for splitscreen.
// primary progress bars are for things like capturing flags or planting bombs - big, important things that happen as you play a gametype
level._primaryProgressBarY = -61; // from center
level._primaryProgressBarX = 0;
level._primaryProgressBarHeight = 9; //28; // this is the height and width of the whole progress bar, including the outline. the part that actually moves is 2 pixels smaller.
level._primaryProgressBarWidth = 120;
level._primaryProgressBarTextY = -75;
level._primaryProgressBarTextX = 0;
level._primaryProgressBarFontSize = .6; // 1.4 before font change from "objective"
level._teamProgressBarY = 32; // 205;
level._teamProgressBarHeight = 14;
level._teamProgressBarWidth = 192;
level._teamProgressBarTextY = 8; // 155;
level._teamProgressBarFontSize = 1.65;
if ( level._splitscreen )
{
level._lowerTextYAlign = "BOTTOM";
level._lowerTextY = -76;
level._lowerTextFontSize = 1.14;
}
else
{
level._lowerTextYAlign = "CENTER";
level._lowerTextY = 70;
level._lowerTextFontSize = 1.6;
}
}
fontPulseInit( maxFontScale )
{
self.baseFontScale = self.fontScale;
if ( isDefined( maxFontScale ) )
self.maxFontScale = min( maxFontScale, 6.3 );
else
self.maxFontScale = min( self.fontScale * 2, 6.3 );
self.inFrames = 2;
self.outFrames = 4;
}
fontPulse(player)
{
self notify ( "fontPulse" );
self endon ( "fontPulse" );
self endon( "death" );
player endon("disconnect");
player endon("joined_team");
player endon("joined_spectators");
self ChangeFontScaleOverTime( self.inFrames * 0.05 );
self.fontScale = self.maxFontScale;
wait self.inFrames * 0.05;
self ChangeFontScaleOverTime( self.outFrames * 0.05 );
self.fontScale = self.baseFontScale;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,792 @@
#include maps\mp\_utility;
setParent( element )
{
if ( isDefined( self.parent ) && self.parent == element )
return;
if ( isDefined( self.parent ) )
self.parent removeChild( self );
self.parent = element;
self.parent addChild( self );
if ( isDefined( self.point ) )
self setPoint( self.point, self.relativePoint, self.xOffset, self.yOffset );
else
self setPoint( "TOPLEFT" );
}
getParent()
{
return self.parent;
}
addChild( element )
{
element.index = self.children.size;
self.children[self.children.size] = element;
}
removeChild( element )
{
element.parent = undefined;
if ( self.children[self.children.size-1] != element )
{
self.children[element.index] = self.children[self.children.size-1];
self.children[element.index].index = element.index;
}
self.children[self.children.size-1] = undefined;
element.index = undefined;
}
setPoint( point, relativePoint, xOffset, yOffset, moveTime )
{
if ( !isDefined( moveTime ) )
moveTime = 0;
element = self getParent();
if ( moveTime )
self moveOverTime( moveTime );
if ( !isDefined( xOffset ) )
xOffset = 0;
self.xOffset = xOffset;
if ( !isDefined( yOffset ) )
yOffset = 0;
self.yOffset = yOffset;
self.point = point;
self.alignX = "center";
self.alignY = "middle";
if ( isSubStr( point, "TOP" ) )
self.alignY = "top";
if ( isSubStr( point, "BOTTOM" ) )
self.alignY = "bottom";
if ( isSubStr( point, "LEFT" ) )
self.alignX = "left";
if ( isSubStr( point, "RIGHT" ) )
self.alignX = "right";
if ( !isDefined( relativePoint ) )
relativePoint = point;
self.relativePoint = relativePoint;
relativeX = "center_adjustable";
relativeY = "middle";
if ( isSubStr( relativePoint, "TOP" ) )
relativeY = "top_adjustable";
if ( isSubStr( relativePoint, "BOTTOM" ) )
relativeY = "bottom_adjustable";
if ( isSubStr( relativePoint, "LEFT" ) )
relativeX = "left_adjustable";
if ( isSubStr( relativePoint, "RIGHT" ) )
relativeX = "right_adjustable";
if ( element == level._uiParent )
{
self.horzAlign = relativeX;
self.vertAlign = relativeY;
}
else
{
self.horzAlign = element.horzAlign;
self.vertAlign = element.vertAlign;
}
if ( strip_suffix( relativeX, "_adjustable" ) == element.alignX )
{
offsetX = 0;
xFactor = 0;
}
else if ( relativeX == "center" || element.alignX == "center" )
{
offsetX = int(element.width / 2);
if ( relativeX == "left_adjustable" || element.alignX == "right" )
xFactor = -1;
else
xFactor = 1;
}
else
{
offsetX = element.width;
if ( relativeX == "left_adjustable" )
xFactor = -1;
else
xFactor = 1;
}
self.x = element.x + (offsetX * xFactor);
if ( strip_suffix( relativeY, "_adjustable" ) == element.alignY )
{
offsetY = 0;
yFactor = 0;
}
else if ( relativeY == "middle" || element.alignY == "middle" )
{
offsetY = int(element.height / 2);
if ( relativeY == "top_adjustable" || element.alignY == "bottom" )
yFactor = -1;
else
yFactor = 1;
}
else
{
offsetY = element.height;
if ( relativeY == "top_adjustable" )
yFactor = -1;
else
yFactor = 1;
}
self.y = element.y + (offsetY * yFactor);
self.x += self.xOffset;
self.y += self.yOffset;
switch ( self.elemType )
{
case "bar":
setPointBar( point, relativePoint, xOffset, yOffset );
break;
}
self updateChildren();
}
setPointBar( point, relativePoint, xOffset, yOffset )
{
self.bar.horzAlign = self.horzAlign;
self.bar.vertAlign = self.vertAlign;
self.bar.alignX = "left";
self.bar.alignY = self.alignY;
self.bar.y = self.y;
if ( self.alignX == "left" )
self.bar.x = self.x;
else if ( self.alignX == "right" )
self.bar.x = self.x - self.width;
else
self.bar.x = self.x - int(self.width / 2);
if ( self.alignY == "top" )
self.bar.y = self.y;
else if ( self.alignY == "bottom" )
self.bar.y = self.y;
self updateBar( self.bar.frac );
}
updateBar( barFrac, rateOfChange )
{
if ( self.elemType == "bar" )
updateBarScale( barFrac, rateOfChange );
}
updateBarScale( barFrac, rateOfChange ) // rateOfChange is optional and is in "(entire bar lengths) per second"
{
barWidth = int(self.width * barFrac + 0.5); // (+ 0.5 rounds)
if ( !barWidth )
barWidth = 1;
self.bar.frac = barFrac;
self.bar setShader( self.bar.shader, barWidth, self.height );
assertEx( barWidth <= self.width, "barWidth <= self.width: " + barWidth + " <= " + self.width + " - barFrac was " + barFrac );
//if barWidth is bigger than self.width then we are drawing more than 100%
if ( isDefined( rateOfChange ) && barWidth < self.width )
{
if ( rateOfChange > 0 )
{
//printLn( "scaling from: " + barWidth + " to " + self.width + " at " + ((1 - barFrac) / rateOfChange) );
assertex( ((1 - barFrac) / rateOfChange) > 0, "barFrac: " + barFrac + "rateOfChange: " + rateOfChange );
self.bar scaleOverTime( (1 - barFrac) / rateOfChange, self.width, self.height );
}
else if ( rateOfChange < 0 )
{
//printLn( "scaling from: " + barWidth + " to " + 0 + " at " + (barFrac / (-1 * rateOfChange)) );
assertex( (barFrac / (-1 * rateOfChange)) > 0, "barFrac: " + barFrac + "rateOfChange: " + rateOfChange );
self.bar scaleOverTime( barFrac / (-1 * rateOfChange), 1, self.height );
}
}
self.bar.rateOfChange = rateOfChange;
self.bar.lastUpdateTime = getTime();
}
createFontString( font, fontScale )
{
fontElem = newClientHudElem( self );
fontElem.elemType = "font";
fontElem.font = font;
fontElem.fontscale = fontScale;
fontElem.baseFontScale = fontScale;
fontElem.x = 0;
fontElem.y = 0;
fontElem.width = 0;
fontElem.height = int(level._fontHeight * fontScale);
fontElem.xOffset = 0;
fontElem.yOffset = 0;
fontElem.children = [];
fontElem setParent( level._uiParent );
fontElem.hidden = false;
return fontElem;
}
createServerFontString( font, fontScale, team )
{
if ( isDefined( team ) )
fontElem = newTeamHudElem( team );
else
fontElem = newHudElem();
fontElem.elemType = "font";
fontElem.font = font;
fontElem.fontscale = fontScale;
fontElem.baseFontScale = fontScale;
fontElem.x = 0;
fontElem.y = 0;
fontElem.width = 0;
fontElem.height = int(level._fontHeight * fontScale);
fontElem.xOffset = 0;
fontElem.yOffset = 0;
fontElem.children = [];
fontElem setParent( level._uiParent );
fontElem.hidden = false;
return fontElem;
}
createServerTimer( font, fontScale, team )
{
if ( isDefined( team ) )
timerElem = newTeamHudElem( team );
else
timerElem = newHudElem();
timerElem.elemType = "timer";
timerElem.font = font;
timerElem.fontScale = fontScale;
timerElem.baseFontScale = fontScale;
timerElem.x = 0;
timerElem.y = 0;
timerElem.width = 0;
timerElem.height = int(level._fontHeight * fontScale);
timerElem.xOffset = 0;
timerElem.yOffset = 0;
timerElem.children = [];
timerElem setParent( level._uiParent );
timerElem.hidden = false;
return timerElem;
}
createTimer( font, fontScale )
{
timerElem = newClientHudElem( self );
timerElem.elemType = "timer";
timerElem.font = font;
timerElem.fontScale = fontScale;
timerElem.baseFontScale = fontScale;
timerElem.x = 0;
timerElem.y = 0;
timerElem.width = 0;
timerElem.height = int(level._fontHeight * fontScale);
timerElem.xOffset = 0;
timerElem.yOffset = 0;
timerElem.children = [];
timerElem setParent( level._uiParent );
timerElem.hidden = false;
return timerElem;
}
createIcon( shader, width, height )
{
iconElem = newClientHudElem( self );
iconElem.elemType = "icon";
iconElem.x = 0;
iconElem.y = 0;
iconElem.width = width;
iconElem.height = height;
iconElem.baseWidth = iconElem.width;
iconElem.baseHeight = iconElem.height;
iconElem.xOffset = 0;
iconElem.yOffset = 0;
iconElem.children = [];
iconElem setParent( level._uiParent );
iconElem.hidden = false;
if ( isDefined( shader ) )
{
iconElem setShader( shader, width, height );
iconElem.shader = shader;
}
return iconElem;
}
createServerIcon( shader, width, height, team )
{
if ( isDefined( team ) )
iconElem = newTeamHudElem( team );
else
iconElem = newHudElem();
iconElem.elemType = "icon";
iconElem.x = 0;
iconElem.y = 0;
iconElem.width = width;
iconElem.height = height;
iconElem.baseWidth = iconElem.width;
iconElem.baseHeight = iconElem.height;
iconElem.xOffset = 0;
iconElem.yOffset = 0;
iconElem.children = [];
iconElem setParent( level._uiParent );
iconElem.hidden = false;
if ( isDefined( shader ) )
{
iconElem setShader( shader, width, height );
iconElem.shader = shader;
}
return iconElem;
}
createServerBar( color, width, height, flashFrac, team, selected )
{
if ( isDefined( team ) )
barElem = newTeamHudElem( team );
else
barElem = newHudElem();
barElem.x = 0;
barElem.y = 0;
barElem.frac = 0;
barElem.color = color;
barElem.sort = -2;
barElem.shader = "progress_bar_fill";
barElem setShader( "progress_bar_fill", width, height );
barElem.hidden = false;
if ( isDefined( flashFrac ) )
{
barElem.flashFrac = flashFrac;
// barElem thread flashThread();
}
if ( isDefined( team ) )
barElemBG = newTeamHudElem( team );
else
barElemBG = newHudElem();
barElemBG.elemType = "bar";
barElemBG.x = 0;
barElemBG.y = 0;
barElemBG.width = width;
barElemBG.height = height;
barElemBG.xOffset = 0;
barElemBG.yOffset = 0;
barElemBG.bar = barElem;
barElemBG.children = [];
barElemBG.sort = -3;
barElemBG.color = (0,0,0);
barElemBG.alpha = 0.5;
barElemBG setParent( level._uiParent );
barElemBG setShader( "progress_bar_bg", width, height );
barElemBG.hidden = false;
return barElemBG;
}
createBar( color, width, height, flashFrac )
{
barElem = newClientHudElem( self );
barElem.x = 0 ;
barElem.y = 0;
barElem.frac = 0;
barElem.color = color;
barElem.sort = -2;
barElem.shader = "progress_bar_fill";
barElem setShader( "progress_bar_fill", width, height );
barElem.hidden = false;
if ( isDefined( flashFrac ) )
{
barElem.flashFrac = flashFrac;
// barElem thread flashThread();
}
barElemBG = newClientHudElem( self );
barElemBG.elemType = "bar";
barElemBG.width = width;
barElemBG.height = height;
barElemBG.xOffset = 0;
barElemBG.yOffset = 0;
barElemBG.bar = barElem;
barElemBG.children = [];
barElemBG.sort = -3;
barElemBG.color = (0,0,0);
barElemBG.alpha = 0.5;
barElemBG setParent( level._uiParent );
barElemBG setShader( "progress_bar_bg", width + 4, height + 4 );
barElemBG.hidden = false;
return barElemBG;
}
getCurrentFraction()
{
frac = self.bar.frac;
if (isdefined(self.bar.rateOfChange))
{
frac += (getTime() - self.bar.lastUpdateTime) * self.bar.rateOfChange;
if (frac > 1) frac = 1;
if (frac < 0) frac = 0;
}
return frac;
}
createPrimaryProgressBar( yOffset )
{
if ( !isDefined( yOffset ) )
yOffset = 0;
bar = createBar( (1, 1, 1), level._primaryProgressBarWidth, level._primaryProgressBarHeight );
bar setPoint("CENTER", undefined, level._primaryProgressBarX, level._primaryProgressBarY - yOffset );
return bar;
}
createPrimaryProgressBarText( yOffset )
{
if ( !isDefined( yOffset ) )
yOffset = 0;
text = createFontString( "hudbig", level._primaryProgressBarFontSize );
text setPoint("CENTER", undefined, level._primaryProgressBarTextX, level._primaryProgressBarTextY - yOffset );
text.sort = -1;
return text;
}
createTeamProgressBar( team )
{
bar = createServerBar( (1,0,0), level._teamProgressBarWidth, level._teamProgressBarHeight, undefined, team );
bar setPoint("TOP", undefined, 0, level._teamProgressBarY);
return bar;
}
createTeamProgressBarText( team )
{
text = createServerFontString( "default", level._teamProgressBarFontSize, team );
text setPoint("TOP", undefined, 0, level._teamProgressBarTextY);
return text;
}
setFlashFrac( flashFrac )
{
self.bar.flashFrac = flashFrac;
}
hideElem()
{
if ( self.hidden )
return;
self.hidden = true;
if ( self.alpha != 0 )
self.alpha = 0;
if ( self.elemType == "bar" || self.elemType == "bar_shader" )
{
self.bar.hidden = true;
if ( self.bar.alpha != 0 )
self.bar.alpha = 0;
}
}
showElem()
{
if ( !self.hidden )
return;
self.hidden = false;
if ( self.elemType == "bar" || self.elemType == "bar_shader" )
{
if ( self.alpha != .5 )
self.alpha = .5;
self.bar.hidden = false;
if ( self.bar.alpha != 1 )
self.bar.alpha = 1;
}
else
{
if ( self.alpha != 1 )
self.alpha = 1;
}
}
flashThread()
{
self endon ( "death" );
if ( !self.hidden )
self.alpha = 1;
while(1)
{
if ( self.frac >= self.flashFrac )
{
if ( !self.hidden )
{
self fadeOverTime(0.3);
self.alpha = .2;
wait(0.35);
self fadeOverTime(0.3);
self.alpha = 1;
}
wait(0.7);
}
else
{
if ( !self.hidden && self.alpha != 1 )
self.alpha = 1;
wait ( 0.05 );
}
}
}
destroyElem()
{
tempChildren = [];
for ( index = 0; index < self.children.size; index++ )
{
if ( isDefined( self.children[index] ) )
tempChildren[tempChildren.size] = self.children[index];
}
for ( index = 0; index < tempChildren.size; index++ )
tempChildren[index] setParent( self getParent() );
if ( self.elemType == "bar" || self.elemType == "bar_shader" )
{
self.bar destroy();
}
self destroy();
}
setIconShader( shader )
{
self setShader( shader );
self.shader = shader;
}
getIconShader( shader )
{
return self.shader;
}
setIconSize( width, height )
{
assert( isDefined( self.shader ) );
self setShader( self.shader, width, height );
}
setWidth( width )
{
self.width = width;
}
setHeight( height )
{
self.height = height;
}
setSize( width, height )
{
self.width = width;
self.height = height;
}
updateChildren()
{
for ( index = 0; index < self.children.size; index++ )
{
child = self.children[index];
child setPoint( child.point, child.relativePoint, child.xOffset, child.yOffset );
}
}
transitionReset()
{
self.x = self.xOffset;
self.y = self.yOffset;
if ( self.elemType == "font" )
{
self.fontScale = self.baseFontScale;
self.label = &"";
}
else if ( self.elemType == "icon" )
{
//self scaleOverTime( 0.001, self.width, self.height );
self setShader( self.shader, self.width, self.height );
}
self.alpha = 0;
}
transitionZoomIn( duration )
{
switch ( self.elemType )
{
case "font":
case "timer":
self.fontScale = 6.3;
self changeFontScaleOverTime( duration );
self.fontScale = self.baseFontScale;
break;
case "icon":
self setShader( self.shader, self.width * 6, self.height * 6 );
self scaleOverTime( duration, self.width, self.height );
break;
}
}
transitionPulseFXIn( inTime, duration )
{
transTime = int(inTime)*1000;
showTime = int(duration)*1000;
switch ( self.elemType )
{
case "font":
case "timer":
self setPulseFX( transTime+250, showTime+transTime, transTime+250 );
break;
default:
break;
}
}
transitionSlideIn( duration, direction )
{
if ( !isDefined( direction ) )
direction = "left";
switch ( direction )
{
case "left":
self.x += 1000;
break;
case "right":
self.x -= 1000;
break;
case "up":
self.y -= 1000;
break;
case "down":
self.y += 1000;
break;
}
self moveOverTime( duration );
self.x = self.xOffset;
self.y = self.yOffset;
}
transitionSlideOut( duration, direction )
{
if ( !isDefined( direction ) )
direction = "left";
gotoX = self.xOffset;
gotoY = self.yOffset;
switch ( direction )
{
case "left":
gotoX += 1000;
break;
case "right":
gotoX -= 1000;
break;
case "up":
gotoY -= 1000;
break;
case "down":
gotoY += 1000;
break;
}
self.alpha = 1;
self moveOverTime( duration );
self.x = gotoX;
self.y = gotoY;
}
transitionZoomOut( duration )
{
switch ( self.elemType )
{
case "font":
case "timer":
self changeFontScaleOverTime( duration );
self.fontScale = 6.3;
case "icon":
self scaleOverTime( duration, self.width * 6, self.height * 6 );
break;
}
}
transitionFadeIn( duration )
{
self fadeOverTime( duration );
if ( isDefined( self.maxAlpha ) )
self.alpha = self.maxAlpha;
else
self.alpha = 1;
}
transitionFadeOut( duration )
{
self fadeOverTime( 0.15 );
self.alpha = 0;
}

View File

@ -0,0 +1,691 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
init()
{
precacheString(&"PLATFORM_PRESS_TO_SKIP");
precacheString(&"PLATFORM_PRESS_TO_RESPAWN");
precacheString(&"PLATFORM_PRESS_TO_COPYCAT");
precacheShader("specialty_copycat");
level._killcam = maps\mp\gametypes\_tweakables::getTweakableValue( "game", "allowkillcam" );
}
killcam(
attackerNum, // entity number of the attacker
killcamentityindex, // entity number of the entity to view (grenade, airstrike, etc)
killcamentitystarttime, // time at which the killcamentity came into being
sWeapon, // killing weapon
predelay, // time between player death and beginning of killcam
offsetTime, // something to do with how far back in time the killer was seeing the world when he made the kill; latency related, sorta
timeUntilRespawn, // will the player be allowed to respawn after the killcam?
maxtime, // time remaining until map ends; the killcam will never last longer than this. undefined = no limit
attacker, // entity object of attacker
victim // entity object of the victim
)
{
// monitors killcam and hides HUD elements during killcam session
//if ( !level.splitscreen )
// self thread killcam_HUD_off();
self endon("disconnect");
self endon("spawned");
level endon("game_ended");
if ( attackerNum < 0 )
return;
// length from killcam start to killcam end
if (getdvar("scr_killcam_time") == "")
{
if ( sWeapon == "artillery_mp" || sWeapon == "stealth_bomb_mp" )
camtime = (gettime() - killcamentitystarttime) / 1000 - predelay - .1;
else if ( level._showingFinalKillcam )
camtime = 4.0;
else if ( sWeapon == "javelin_mp" )
camtime = 8;
else if ( issubstr( sWeapon, "remotemissile_" ) )
camtime = 5;
else if ( !timeUntilRespawn || timeUntilRespawn > 5.0 ) // if we're not going to respawn, we can take more time to watch what happened
camtime = 5.0;
else if ( sWeapon == "frag_grenade_mp" || sWeapon == "frag_grenade_short_mp" || sWeapon == "semtex_mp" )
camtime = 4.25; // show long enough to see grenade thrown
else
camtime = 2.5;
}
else
camtime = getdvarfloat("scr_killcam_time");
if (isdefined(maxtime)) {
if (camtime > maxtime)
camtime = maxtime;
if (camtime < .05)
camtime = .05;
}
// time after player death that killcam continues for
if (getdvar("scr_killcam_posttime") == "")
postdelay = 2;
else {
postdelay = getdvarfloat("scr_killcam_posttime");
if (postdelay < 0.05)
postdelay = 0.05;
}
/* timeline:
| camtime | postdelay |
| | predelay |
^ killcam start ^ player death ^ killcam end
^ player starts watching killcam
*/
killcamlength = camtime + postdelay;
// don't let the killcam last past the end of the round.
if (isdefined(maxtime) && killcamlength > maxtime)
{
// first trim postdelay down to a minimum of 1 second.
// if that doesn't make it short enough, trim camtime down to a minimum of 1 second.
// if that's still not short enough, cancel the killcam.
if ( maxtime < 2 )
return;
if (maxtime - camtime >= 1) {
// reduce postdelay so killcam ends at end of match
postdelay = maxtime - camtime;
}
else {
// distribute remaining time over postdelay and camtime
postdelay = 1;
camtime = maxtime - 1;
}
// recalc killcamlength
killcamlength = camtime + postdelay;
}
killcamoffset = camtime + predelay;
startTime = getTime();
self notify ( "begin_killcam", startTime );
if ( getDvarInt( "upgradeEnabling" ) == 1 )
{
// To specifically wait for the button presses for Y or B
self thread maps\mp\_upgrade::waitForYButtonPress();
self thread maps\mp\_upgrade::waitForBButtonPress();
}
self.sessionstate = "spectator";
self.forcespectatorclient = attackerNum;
self.killcamentity = -1;
if ( killcamentityindex >= 0 )
self thread setKillCamEntity( killcamentityindex, killcamoffset, killcamentitystarttime );
self.archivetime = killcamoffset;
self.killcamlength = killcamlength;
self.psoffsettime = offsetTime;
// ignore spectate permissions
self allowSpectateTeam("allies", true);
self allowSpectateTeam("axis", true);
self allowSpectateTeam("freelook", true);
self allowSpectateTeam("none", true);
if( level._multiTeamBased )
{
foreach( teamname in level._teamNameList )
{
self allowSpectateTeam( teamname, true );
}
}
if ( isDefined( attacker ) && level._showingFinalKillcam ) // attacker may have disconnected
{
self openMenu( "killedby_card_display" );
self SetCardDisplaySlot( attacker, 7 );
}
self thread endedKillcamCleanup();
// wait till the next server frame to allow code a chance to update archivetime if it needs trimming
wait 0.05;
assertex( self.archivetime <= killcamoffset + 0.0001, "archivetime: " + self.archivetime + ", killcamoffset: " + killcamoffset );
if ( self.archivetime < killcamoffset )
println( "WARNING: Code trimmed killcam time by " + (killcamoffset - self.archivetime) + " seconds because it doesn't have enough game time recorded!" );
camtime = self.archivetime - .05 - predelay;
killcamlength = camtime + postdelay;
self.killcamlength = killcamlength;
if ( camtime <= 0 ) // if we're not looking back in time far enough to even see the death, cancel
{
println( "Cancelling killcam because we don't even have enough recorded to show the death." );
self.sessionstate = "dead";
self.forcespectatorclient = -1;
self.killcamentity = -1;
self.archivetime = 0;
self.psoffsettime = 0;
self notify ( "killcam_ended" );
return;
}
if ( level._showingFinalKillcam )
thread doFinalKillCamFX( camtime );
self.killcam = true;
self initKCElements();
if ( getDvarInt( "upgradeEnabling" ) == 1 )
{
self maps\mp\_upgrade::initUpgradeElements();
}
if ( !level._splitscreen )
{
self.kc_timer.alpha = 1;
self.kc_timer setTenthsTimer(camtime);
}
if ( timeUntilRespawn && !level._gameEnded )
{
if ( timeUntilRespawn > 0 )
if ( isDefined( level._showSpawnTimer ) && level._showSpawnTimer )
{
setLowerMessage( "kc_info", game["strings"]["waiting_to_spawn"], timeUntilRespawn, 1, true );
}
else
{
setLowerMessage( "kc_info", game["strings"]["waiting_to_spawn"], timeUntilRespawn );
}
else
setLowerMessage( "kc_info", &"PLATFORM_PRESS_TO_SKIP" );
}
else if ( !level._gameEnded )
{
setLowerMessage( "kc_info", &"PLATFORM_PRESS_TO_RESPAWN" );
}
if ( !level._showingFinalKillcam )
{
self.kc_skiptext.alpha = 1;
if ( getDvarInt( "upgradeEnabling" ) == 1 )
{
self maps\mp\_upgrade::showUpgradeHUDElement();
}
}
else
self.kc_skiptext.alpha = 0;
self.kc_othertext.alpha = 0;
self.kc_icon.alpha = 0;
self thread spawnedKillcamCleanup();
if ( self == victim && victim _hasPerk( "specialty_copycat" ) && isDefined( victim.pers["copyCatLoadout"] ) )
self thread waitKCCopyCatButton( attacker );
if ( !level._showingFinalKillcam )
self thread waitSkipKillcamButton( timeUntilRespawn );
else
self notify ( "showing_final_killcam" );
self thread endKillcamIfNothingToShow();
self waittillKillcamOver();
if ( level._showingFinalKillcam )
{
self thread maps\mp\gametypes\_playerlogic::spawnEndOfGame();
return;
}
self thread calculateKillCamTime( startTime );
self thread killcamCleanup( true );
}
doFinalKillCamFX( camTime )
{
if ( isDefined( level._doingFinalKillcamFx ) )
return;
level._doingFinalKillcamFx = true;
intoSlowMoTime = camTime;
if ( intoSlowMoTime > 1.0 )
{
intoSlowMoTime = 1.0;
wait( camTime - 1.0 );
}
setSlowMotion( 1.0, 0.25, intoSlowMoTime ); // start timescale, end timescale, lerp duration
wait( intoSlowMoTime + .5 );
setSlowMotion( 0.25, 1, 1.0 );
level._doingFinalKillcamFx = undefined;
}
calculateKillCamTime( startTime )
{
watchedTime = int(getTime() - startTime);
self incPlayerStat( "killcamtimewatched", watchedTime );
}
waittillKillcamOver()
{
self endon("abort_killcam");
wait(self.killcamlength - 0.05);
}
setKillCamEntity( killcamentityindex, killcamoffset, starttime )
{
self endon("disconnect");
self endon("killcam_ended");
killcamtime = (gettime() - killcamoffset * 1000);
if ( starttime > killcamtime )
{
wait .05;
// code may have trimmed archivetime after the first frame if we couldn't go back in time as far as requested.
killcamoffset = self.archivetime;
killcamtime = (gettime() - killcamoffset * 1000);
if ( starttime > killcamtime )
wait (starttime - killcamtime) / 1000;
}
self.killcamentity = killcamentityindex;
}
waitSkipKillcamButton( timeUntilRespawn )
{
self endon("disconnect");
self endon("killcam_ended");
while(self cancelKillCamUseButton())
wait .05;
while(!(self cancelKillCamUseButton()))
wait .05;
if ( !matchMakingGame() )
self incPlayerStat( "killcamskipped", 1 );
if ( timeUntilRespawn <= 0 )
clearLowerMessage( "kc_info" );
if ( getDvarInt( "upgradeEnabling" ) == 1 )
{
self maps\mp\_upgrade::processUpgradeSelections();
}
self notify("abort_killcam");
}
waitKCCopyCatButton( attacker )
{
self endon("disconnect");
self endon("killcam_ended");
self waitCopyCatButton( attacker );
self notify("abort_killcam");
}
waitDeathCopyCatButton( attacker )
{
self endon ( "disconnect" );
self initKCElements();
if ( getDvarInt( "upgradeEnabling" ) == 1 )
{
self maps\mp\_upgrade::initUpgradeElements();
}
usedCopycat = self waitCopyCatButton( attacker );
if ( !isDefined( usedCopycat ) )
{
self.kc_icon.alpha = 0;
self.kc_othertext.alpha = 0;
}
}
waitCopyCatButton( attacker )
{
self endon ( "spawned_player" );
self endon ( "death_delay_finished" );
self.kc_icon setShader( "specialty_copycat", 48, 48 );
self.kc_othertext setText( &"PLATFORM_PRESS_TO_COPYCAT" );
self.kc_othertext.alpha = 1;
self.kc_icon.alpha = 1;
self notifyOnPlayerCommand( "use_copycat", "weapnext" );
self waittill( "use_copycat" );
self.pers["copyCatLoadout"]["inUse"] = true;
self.pers["copyCatLoadout"]["owner"] = attacker;
self.kc_othertext fadeOverTime( 0.5 );
self.kc_othertext.alpha = 0;
self.kc_icon fadeOverTime( 0.25 );
self.kc_icon scaleOverTime( 0.25, 512, 512 );
self.kc_icon.alpha = 0;
if ( isDefined( attacker ) )
attacker thread maps\mp\gametypes\_hud_message::playerCardSplashNotify( "copied", self );
self playLocalSound( "copycat_steal_class" );
return true;
}
waitSkipKillcamSafeSpawnButton()
{
self endon("disconnect");
self endon("killcam_ended");
if ( !self maps\mp\gametypes\_playerlogic::maySpawn() )
return;
while(self fragButtonPressed())
wait .05;
while(!(self fragButtonPressed()))
wait .05;
self.wantSafeSpawn = true;
self notify("abort_killcam");
}
endKillcamIfNothingToShow()
{
self endon("disconnect");
self endon("killcam_ended");
while(1)
{
// code may trim our archivetime to zero if there is nothing "recorded" to show.
// this can happen when the person we're watching in our killcam goes into killcam himself.
// in this case, end the killcam.
if ( self.archivetime <= 0 )
break;
wait .05;
}
self notify("abort_killcam");
}
spawnedKillcamCleanup()
{
self endon("disconnect");
self endon("killcam_ended");
self waittill("spawned");
self thread killcamCleanup( false );
}
endedKillcamCleanup()
{
self endon("disconnect");
self endon("killcam_ended");
level waittill("game_ended");
self thread killcamCleanup( true );
}
killcamCleanup( clearState )
{
if(isDefined(self.kc_skiptext))
self.kc_skiptext.alpha = 0;
if(isDefined(self.kc_timer))
self.kc_timer.alpha = 0;
if(isDefined(self.kc_icon))
self.kc_icon.alpha = 0;
if(isDefined(self.kc_othertext))
self.kc_othertext.alpha = 0;
if ( getDvarInt( "upgradeEnabling" ) == 1 )
{
maps\mp\_upgrade::upgradeHUDCleanUp();
}
self.killcam = undefined;
if ( !level._gameEnded )
self clearLowerMessage( "kc_info" );
self thread maps\mp\gametypes\_spectating::setSpectatePermissions();
self notify("killcam_ended"); // do this last, in case this function was called from a thread ending on it
if ( !clearState )
return;
self.sessionstate = "dead";
self ClearKillcamState();
}
cancelKillCamOnUse()
{
self.cancelKillcam = false;
self thread cancelKillCamOnUse_specificButton( ::cancelKillCamUseButton, ::cancelKillCamCallback );
//self thread cancelKillCamOnUse_specificButton( ::cancelKillCamSafeSpawnButton, ::cancelKillCamSafeSpawnCallback );
}
cancelKillCamUseButton()
{
if ( getDvarInt( "upgradeEnabling" ) == 1 )
{
if ( self useButtonPressed())
{
self.killCamButtonPressed = "use";
return true;
}
else if ( self JumpButtonPressed())
{
self.killCamButtonPressed = "jump";
if (( self.earnedStrikePoints >= level._upgradeDefs[self.upgradeList["jump"]]["requiredPoints"] ) && !(maps\mp\_upgrade::hasUpgrade(self, self.upgradeList["jump"] )))
{
return true;
}
else
{
return false;
}
}
else if ( self maps\mp\_upgrade::ReloadButtonPressed())
{
self.killCamButtonPressed = "switchWeap";
if (( self.earnedStrikePoints >= level._upgradeDefs[self.upgradeList["switchWeap"]]["requiredPoints"] ) && !(maps\mp\_upgrade::hasUpgrade(self, self.upgradeList["switchWeap"] )))
{
return true;
}
else
{
return false;
}
}
else if ( self maps\mp\_upgrade::ProneButtonPressed())
{
self.killCamButtonPressed = "prone";
if (( self.earnedStrikePoints >= level._upgradeDefs[self.upgradeList["prone"]]["requiredPoints"] ) && !(maps\mp\_upgrade::hasUpgrade(self, self.upgradeList["prone"] )))
{
return true;
}
else
{
return false;
}
}
return false;
}
else
{
return self useButtonPressed();
}
}
cancelKillCamSafeSpawnButton()
{
return self fragButtonPressed();
}
cancelKillCamCallback()
{
self.cancelKillcam = true;
}
cancelKillCamSafeSpawnCallback()
{
self.cancelKillcam = true;
self.wantSafeSpawn = true;
}
cancelKillCamOnUse_specificButton( pressingButtonFunc, finishedFunc )
{
self endon ( "death_delay_finished" );
self endon ( "disconnect" );
level endon ( "game_ended" );
for ( ;; )
{
if ( !self [[pressingButtonFunc]]() )
{
wait ( 0.05 );
continue;
}
buttonTime = 0;
while( self [[pressingButtonFunc]]() )
{
buttonTime += 0.05;
wait ( 0.05 );
}
if ( buttonTime >= 0.5 )
continue;
buttonTime = 0;
while ( !self [[pressingButtonFunc]]() && buttonTime < 0.5 )
{
buttonTime += 0.05;
wait ( 0.05 );
}
if ( buttonTime >= 0.5 )
continue;
if ( getDvarInt( "upgradeEnabling" ) == 1 )
{
self maps\mp\_upgrade::processUpgradeSelections();
}
self [[finishedFunc]]();
return;
}
}
initKCElements()
{
if ( !isDefined( self.kc_skiptext ) )
{
self.kc_skiptext = newClientHudElem(self);
self.kc_skiptext.archived = false;
self.kc_skiptext.x = 0;
self.kc_skiptext.alignX = "center";
self.kc_skiptext.alignY = "top";
self.kc_skiptext.horzAlign = "center_adjustable";
self.kc_skiptext.vertAlign = "top_adjustable";
self.kc_skiptext.sort = 1; // force to draw after the bars
self.kc_skiptext.font = "default";
self.kc_skiptext.foreground = true;
self.kc_skiptext.hideWhenInMenu = true;
if ( level._splitscreen )
{
self.kc_skiptext.y = 20;
self.kc_skiptext.fontscale = 1.2; // 1.8/1.5
}
else
{
self.kc_skiptext.y = 32;
self.kc_skiptext.fontscale = 1.8;
}
}
if ( !isDefined( self.kc_othertext ) )
{
self.kc_othertext = newClientHudElem(self);
self.kc_othertext.archived = false;
self.kc_othertext.y = 48;
self.kc_othertext.alignX = "left";
self.kc_othertext.alignY = "top";
self.kc_othertext.horzAlign = "center";
self.kc_othertext.vertAlign = "middle";
self.kc_othertext.sort = 10; // force to draw after the bars
self.kc_othertext.font = "small";
self.kc_othertext.foreground = true;
self.kc_othertext.hideWhenInMenu = true;
if ( level._splitscreen )
{
self.kc_othertext.x = 16;
self.kc_othertext.fontscale = 1.2;
}
else
{
self.kc_othertext.x = 32;
self.kc_othertext.fontscale = 1.6;
}
}
if ( !isDefined( self.kc_icon ) )
{
self.kc_icon = newClientHudElem(self);
self.kc_icon.archived = false;
self.kc_icon.x = 16;
self.kc_icon.y = 16;
self.kc_icon.alignX = "left";
self.kc_icon.alignY = "top";
self.kc_icon.horzAlign = "center";
self.kc_icon.vertAlign = "middle";
self.kc_icon.sort = 1; // force to draw after the bars
self.kc_icon.foreground = true;
self.kc_icon.hideWhenInMenu = true;
}
if ( !level._splitscreen )
{
if ( !isdefined( self.kc_timer ) )
{
self.kc_timer = createFontString( "hudbig", 1.0 );
self.kc_timer.archived = false;
self.kc_timer.x = 0;
self.kc_timer.alignX = "center";
self.kc_timer.alignY = "middle";
self.kc_timer.horzAlign = "center_safearea";
self.kc_timer.vertAlign = "top_adjustable";
self.kc_timer.y = 42;
self.kc_timer.sort = 1; // force to draw after the bars
self.kc_timer.font = "hudbig";
self.kc_timer.foreground = true;
self.kc_timer.color = (0.85,0.85,0.85);
self.kc_timer.hideWhenInMenu = true;
}
}
}

View File

@ -0,0 +1,589 @@
#include maps\mp\_utility;
init()
{
if ( !isDefined( game["gamestarted"] ) )
{
game["menu_team"] = "team_marinesopfor";
if( level._multiTeamBased )
{
game["menu_team"] = "team_mtdm_options";
}
game["menu_class_allies"] = "class_marines";
game["menu_changeclass_allies"] = "changeclass_marines";
game["menu_initteam_allies"] = "initteam_marines";
game["menu_class_axis"] = "class_opfor";
game["menu_changeclass_axis"] = "changeclass_opfor";
game["menu_initteam_axis"] = "initteam_opfor";
game["menu_class"] = "class";
game["menu_changeclass"] = "changeclass";
game["menu_onemanarmy"] = "onemanarmy";
game["menu_exosuit"] = "exosuit";
if( level._multiTeamBased )
{
for( i = 0; i < level._teamNameList.size; i++ )
{
str_menu_class = "menu_class_" + level._teamNameList[i];
str_menu_changeclass = "menu_changeclass_" + level._teamNameList[i];
str_menu_initteam = "menu_initteam_" + level._teamNameList[i];
game[str_menu_class] = "class_marines";
game[str_menu_changeclass] = "changeclass_marines";
game[str_menu_initteam] = "initteam_marines";
}
}
if ( !level._console )
{
game["menu_callvote"] = "callvote";
game["menu_muteplayer"] = "muteplayer";
precacheMenu(game["menu_callvote"]);
precacheMenu(game["menu_muteplayer"]);
}
else
{
game["menu_controls"] = "ingame_controls";
//game["menu_options"] = "ingame_options";
game["menu_leavegame"] = "popup_leavegame";
if(level._splitscreen)
{
if( level._multiTeamBased )
{
for( i = 0; i < level._teamNameList.size; i++ )
{
str_menu_class = "menu_class_" + level._teamNameList[i];
str_menu_changeclass = "menu_changeclass_" + level._teamNameList[i];
game[str_menu_class] += "_splitscreen";
game[str_menu_changeclass] += "_splitscreen";
}
}
game["menu_team"] += "_splitscreen";
game["menu_class_allies"] += "_splitscreen";
game["menu_changeclass_allies"] += "_splitscreen";
game["menu_class_axis"] += "_splitscreen";
game["menu_changeclass_axis"] += "_splitscreen";
game["menu_class"] += "_splitscreen";
game["menu_controls"] += "_splitscreen";
//game["menu_options"] += "_splitscreen";
game["menu_leavegame"] += "_splitscreen";
game["menu_onemanarmy"] += "_splitscreen";
game["menu_changeclass_defaults_splitscreen"] = "changeclass_defaults_splitscreen";
game["menu_changeclass_custom_splitscreen"] = "changeclass_custom_splitscreen";
game["menu_onemanarmy_defaults_splitscreen"] = "onemanarmy_defaults_splitscreen";
game["menu_onemanarmy_custom_splitscreen"] = "onemanarmy_custom_splitscreen";
precacheMenu(game["menu_changeclass_defaults_splitscreen"]);
precacheMenu(game["menu_changeclass_custom_splitscreen"]);
precacheMenu(game["menu_onemanarmy_defaults_splitscreen"]);
precacheMenu(game["menu_onemanarmy_custom_splitscreen"]);
}
precacheMenu(game["menu_controls"]);
//precacheMenu(game["menu_options"]);
precacheMenu(game["menu_leavegame"]);
//precacheMenu("status_update");
}
precacheMenu("scoreboard");
precacheMenu(game["menu_team"]);
precacheMenu(game["menu_class_allies"]);
precacheMenu(game["menu_changeclass_allies"]);
precacheMenu(game["menu_initteam_allies"]);
precacheMenu(game["menu_class_axis"]);
precacheMenu(game["menu_changeclass_axis"]);
precacheMenu(game["menu_class"]);
precacheMenu(game["menu_changeclass"]);
precacheMenu(game["menu_initteam_axis"]);
precacheMenu(game["menu_onemanarmy"]);
precacheMenu(game["menu_exosuit"]);
precacheString( &"MP_HOST_ENDED_GAME" );
precacheString( &"MP_HOST_ENDGAME_RESPONSE" );
}
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill("connected", player);
player thread onMenuResponse();
}
}
onMenuResponse()
{
self endon("disconnect");
for(;;)
{
self waittill("menuresponse", menu, response);
if ( response == "back" )
{
self closepopupMenu();
self closeInGameMenu();
if ( level._console )
{
if ( menu == game["menu_changeclass"] ||
menu == game["menu_team"] ||
menu == game["menu_controls"] ||
( isDefined( game["menu_changeclass_defaults_splitscreen"] ) && menu == game["menu_changeclass_defaults_splitscreen"] ) ||
( isDefined( game["menu_changeclass_custom_splitscreen"] ) && menu == game["menu_changeclass_custom_splitscreen"] ) )
{
if( self.pers["team"] == "allies" )
self openpopupMenu( game["menu_class_allies"] );
if( self.pers["team"] == "axis" )
self openpopupMenu( game["menu_class_axis"] );
}
}
continue;
}
if(response == "changeteam")
{
self closepopupMenu();
self closeInGameMenu();
self openpopupMenu(game["menu_team"]);
}
if(response == "changeclass_marines" )
{
self closepopupMenu();
self closeInGameMenu();
self openpopupMenu( game["menu_changeclass_allies"] );
continue;
}
if(response == "changeclass_opfor" )
{
self closepopupMenu();
self closeInGameMenu();
self openpopupMenu( game["menu_changeclass_axis"] );
continue;
}
if(response == "changeclass_marines_splitscreen" )
self openpopupMenu( "changeclass_marines_splitscreen" );
if(response == "changeclass_opfor_splitscreen" )
self openpopupMenu( "changeclass_opfor_splitscreen" );
if(response == "endgame")
{
if(level._splitscreen)
{
endparty();
if ( !level._gameEnded )
{
level thread maps\mp\gametypes\_gamelogic::forceEnd();
}
}
continue;
}
if ( response == "endround" )
{
if ( !level._gameEnded )
{
level thread maps\mp\gametypes\_gamelogic::forceEnd();
}
else
{
self closepopupMenu();
self closeInGameMenu();
self iprintln( &"MP_HOST_ENDGAME_RESPONSE" );
}
continue;
}
if ( menu == game["menu_team"] )
{
switch( response )
{
case "autoassign":
self [[level._autoassign]]();
break;
case "spectator":
self [[level._spectator]]();
break;
default:
self [[level._onTeamSelection]]( response );
}
} // the only responses remain are change class events
else if ( menu == game["menu_changeclass"] ||
( isDefined( game["menu_changeclass_defaults_splitscreen"] ) && menu == game["menu_changeclass_defaults_splitscreen"] ) ||
( isDefined( game["menu_changeclass_custom_splitscreen"] ) && menu == game["menu_changeclass_custom_splitscreen"] ) )
{
self closepopupMenu();
self closeInGameMenu();
self.selectedClass = true;
self [[level._class]](response);
}
else if ( !level._console )
{
if(menu == game["menu_quickcommands"])
maps\mp\gametypes\_quickmessages::quickcommands(response);
else if(menu == game["menu_quickstatements"])
maps\mp\gametypes\_quickmessages::quickstatements(response);
else if(menu == game["menu_quickresponses"])
maps\mp\gametypes\_quickmessages::quickresponses(response);
}
}
}
onMenuTeamSelect( selection )
{
self closeMenus();
if(self.pers["team"] != selection)
{
if( level._teamBased && !maps\mp\gametypes\_teams::getJoinTeamPermissions( selection ) )
{
self openpopupMenu(game["menu_team"]);
return;
}
// allow respawn when switching teams during grace period.
if ( level._inGracePeriod && !self.hasDoneCombat )
self.hasSpawned = false;
if(self.sessionstate == "playing")
{
self.switching_teams = true;
self.joining_team = selection;
self.leaving_team = self.pers["team"];
self suicide();
}
self addToTeam( selection );
self.pers["class"] = undefined;
self.class = undefined;
self notify("end_respawn");
}
self beginClassChoice();
}
getTeamAssignment()
{
teams[0] = "allies";
teams[1] = "axis";
if ( !level._teamBased )
return teams[randomInt(2)];
//If sessionteam is already set, it is probably because you are in a matchmaking game
if ( self.sessionteam != "none" && self.sessionteam != "spectator" && self.sessionstate != "playing" && self.sessionstate != "dead" )
{
assignment = self.sessionteam;
}
else if( level._multiTeamBased )
{
/#
println( "" );
println( "SETTING TEAM ASSIGNMENT" );
println( "max num teams = " + level._teamNameList.size );
#/
numTeams = level._teamNameList.size;
//scan for smallest team, assign new player to that team
teamAssignment = level._teamNameList[0];
for( i = 0; i < level._teamNameList.size; i++ )
{
/#
println( level._teamNameList[i] + " has " + level._teamCount[level._teamNameList[i]] + " players on it." );
#/
if ( level._teamCount[level._teamNameList[i]] < level._teamCount[teamAssignment] )
{
teamAssignment = level._teamNameList[i];
}
}
/#
println( "Team assignment = " + teamAssignment );
println( "" );
#/
return teamAssignment;
}
else
{
playerCounts = self maps\mp\gametypes\_teams::CountPlayers();
// if teams are equal return the team with the lowest score
if ( playerCounts["allies"] == playerCounts["axis"] )
{
if( getTeamScore( "allies" ) == getTeamScore( "axis" ) )
assignment = teams[randomInt(2)];
else if ( getTeamScore( "allies" ) < getTeamScore( "axis" ) )
assignment = "allies";
else
assignment = "axis";
}
else if( playerCounts["allies"] < playerCounts["axis"] )
{
assignment = "allies";
}
else
{
assignment = "axis";
}
}
return assignment;
}
menuAutoAssign()
{
self closeMenus();
assignment = getTeamAssignment();
if ( isDefined( self.pers["team"] ) && (self.sessionstate == "playing" || self.sessionstate == "dead") )
{
if ( assignment == self.pers["team"] )
{
self beginClassChoice();
return;
}
else
{
self.switching_teams = true;
self.joining_team = assignment;
self.leaving_team = self.pers["team"];
self suicide();
}
}
self addToTeam( assignment );
self.pers["class"] = undefined;
self.class = undefined;
if ( !isAlive( self ) )
self.statusicon = "hud_status_dead";
self notify("end_respawn");
self beginClassChoice();
}
beginClassChoice( forceNewChoice )
{
if( !level._multiTeamBased )
{
assert( self.pers["team"] == "axis" || self.pers["team"] == "allies" );
}
team = self.pers["team"];
// menu_changeclass_team is the one where you choose one of the n classes to play as.
// menu_class_team is where you can choose to change your team, class, controls, or leave game.
self openpopupMenu( game[ "menu_changeclass_" + team ] );
if ( !isAlive( self ) )
self thread maps\mp\gametypes\_playerlogic::predictAboutToSpawnPlayerOverTime( 0.1 );
}
beginTeamChoice()
{
self openpopupMenu( game["menu_team"] );
}
showMainMenuForTeam()
{
assert( self.pers["team"] == "axis" || self.pers["team"] == "allies" );
team = self.pers["team"];
// menu_changeclass_team is the one where you choose one of the n classes to play as.
// menu_class_team is where you can choose to change your team, class, controls, or leave game.
self openpopupMenu( game[ "menu_class_" + team ] );
}
menuSpectator()
{
self closeMenus();
if( isDefined( self.pers["team"] ) && self.pers["team"] == "spectator" )
return;
if( isAlive( self ) )
{
assert( isDefined( self.pers["team"] ) );
self.switching_teams = true;
self.joining_team = "spectator";
self.leaving_team = self.pers["team"];
self suicide();
}
self addToTeam( "spectator" );
self.pers["class"] = undefined;
self.class = undefined;
self thread maps\mp\gametypes\_playerlogic::spawnSpectator();
}
menuClass( response )
{
self closeMenus();
// clear new status of unlocked classes
if ( response == "demolitions_mp,0" && self getPlayerData( "featureNew", "demolitions" ) )
{
self setPlayerData( "featureNew", "demolitions", false );
}
if ( response == "sniper_mp,0" && self getPlayerData( "featureNew", "sniper" ) )
{
self setPlayerData( "featureNew", "sniper", false );
}
// this should probably be an assert
if( !level._multiTeamBased )
{
if(!isDefined(self.pers["team"]) || (self.pers["team"] != "allies" && self.pers["team"] != "axis"))
return;
}
class = self maps\mp\gametypes\_class::getClassChoice( response );
primary = self maps\mp\gametypes\_class::getWeaponChoice( response );
if ( class == "restricted" )
{
self beginClassChoice();
return;
}
if( (isDefined( self.pers["class"] ) && self.pers["class"] == class) &&
(isDefined( self.pers["primary"] ) && self.pers["primary"] == primary) )
return;
if ( self.sessionstate == "playing" )
{
self.pers["class"] = class;
self.class = class;
self.pers["primary"] = primary;
if ( game["state"] == "postgame" )
return;
if ( level._inGracePeriod && !self.hasDoneCombat ) // used weapons check?
{
if ( !isGameModeBlockingClassChange())
{
self maps\mp\gametypes\_class::setClass( self.pers["class"] );
self.tag_stowed_back = undefined;
self.tag_stowed_hip = undefined;
self maps\mp\gametypes\_class::giveLoadout( self.pers["team"], self.pers["class"] );
}
}
else
{
if ( !isGameModeBlockingClassChange())
{
self iPrintLnBold( game["strings"]["change_class"] );
}
}
}
else
{
self.pers["class"] = class;
self.class = class;
self.pers["primary"] = primary;
if ( game["state"] == "postgame" )
return;
if ( game["state"] == "playing" && !isInKillcam() )
self thread maps\mp\gametypes\_playerlogic::spawnClient();
}
self thread maps\mp\gametypes\_spectating::setSpectatePermissions();
}
addToTeam( team, firstConnect )
{
// UTS update playerCount remove from team
if ( isDefined( self.team ) )
self maps\mp\gametypes\_playerlogic::removeFromTeamCount();
self.pers["team"] = team;
// this is the only place self.team should ever be set
self.team = team;
// session team is readonly in ranked matches on console
if ( !matchMakingGame() || isDefined( self.pers["isBot"] ) )
{
if ( level._teamBased )
{
self.sessionteam = team;
}
else
{
if ( team == "spectator" )
self.sessionteam = "spectator";
else
self.sessionteam = "none";
}
}
// UTS update playerCount add to team
if ( game["state"] != "postgame" )
self maps\mp\gametypes\_playerlogic::addToTeamCount();
self updateObjectiveText();
// give "joined_team" and "joined_spectators" handlers a chance to start
// these are generally triggered from the "connected" notify, which can happen on the same
// frame as these notifies
if ( isDefined( firstConnect ) && firstConnect )
waittillframeend;
self updateMainMenu();
if ( team == "spectator" )
{
self notify( "joined_spectators" );
level notify( "joined_team" );
}
else
{
self notify( "joined_team" );
level notify( "joined_team" );
}
}
isGameModeBlockingClassChange()
{
result = false;
if ( isDefined( level._blockClassChange) && level._blockClassChange == true )
{
result = true;
}
return result;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,512 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
init()
{
if( level._multiTeamBased == true )
{
for( i = 0; i < level._teamNameList.size; i++ )
{
str_spawn_team = "spawn_" + level._teamNameList[i];
str_defeat_team = "defeat_" + level._teamNameList[i];
str_victory_team = "victory_" + level._teamNameList[i];
str_winning_team = "winning_" + level._teamNameList[i];
str_losing_team = "losing_" + level._teamNameList[i];
game["music"][str_spawn_team] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "spawn_music";
game["music"][str_defeat_team] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "defeat_music";
game["music"][str_victory_team] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "victory_music";
game["music"][str_winning_team] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "winning_music";
game["music"][str_losing_team] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "losing_music";
game["voice"][level._teamNameList[i]] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "1mc_";
}
}
game["music"]["spawn_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "spawn_music";
game["music"]["defeat_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "defeat_music";
game["music"]["victory_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "victory_music";
game["music"]["winning_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "winning_music";
game["music"]["losing_allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "losing_music";
game["voice"]["allies"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "allies" ) + "1mc_";
game["music"]["spawn_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "spawn_music";
game["music"]["defeat_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "defeat_music";
game["music"]["victory_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "victory_music";
game["music"]["winning_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "winning_music";
game["music"]["losing_axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "losing_music";
game["voice"]["axis"] = maps\mp\gametypes\_teams::getTeamVoicePrefix( "axis" ) + "1mc_";
game["music"]["defeat"] = "mp_defeat";
game["music"]["victory_spectator"] = "mp_defeat";
game["music"]["winning_time"] = "mp_time_running_out_winning";
game["music"]["losing_time"] = "mp_time_running_out_losing";
game["music"]["winning_score"] = "mp_time_running_out_winning";
game["music"]["losing_score"] = "mp_time_running_out_losing";
game["music"]["victory_tie"] = "mp_defeat";
game["music"]["suspense"] = [];
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_01";
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_02";
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_03";
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_04";
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_05";
game["music"]["suspense"][game["music"]["suspense"].size] = "mp_suspense_06";
game["dialog"]["mission_success"] = "mission_success";
game["dialog"]["mission_failure"] = "mission_fail";
game["dialog"]["mission_draw"] = "draw";
game["dialog"]["round_success"] = "encourage_win";
game["dialog"]["round_failure"] = "encourage_lost";
game["dialog"]["round_draw"] = "draw";
// status
game["dialog"]["timesup"] = "timesup";
game["dialog"]["winning_time"] = "winning";
game["dialog"]["losing_time"] = "losing";
game["dialog"]["winning_score"] = "winning_fight";
game["dialog"]["losing_score"] = "losing_fight";
game["dialog"]["lead_lost"] = "lead_lost";
game["dialog"]["lead_tied"] = "tied";
game["dialog"]["lead_taken"] = "lead_taken";
game["dialog"]["last_alive"] = "lastalive";
game["dialog"]["boost"] = "boost";
if ( !isDefined( game["dialog"]["offense_obj"] ) )
game["dialog"]["offense_obj"] = "boost";
if ( !isDefined( game["dialog"]["defense_obj"] ) )
game["dialog"]["defense_obj"] = "boost";
game["dialog"]["hardcore"] = "hardcore";
game["dialog"]["highspeed"] = "highspeed";
game["dialog"]["tactical"] = "tactical";
game["dialog"]["challenge"] = "challengecomplete";
game["dialog"]["promotion"] = "promotion";
game["dialog"]["bomb_taken"] = "acheive_bomb";
game["dialog"]["bomb_lost"] = "bomb_taken";
game["dialog"]["bomb_defused"] = "bomb_defused";
game["dialog"]["bomb_planted"] = "bomb_planted";
game["dialog"]["obj_taken"] = "securedobj";
game["dialog"]["obj_lost"] = "lostobj";
game["dialog"]["obj_defend"] = "obj_defend";
game["dialog"]["obj_destroy"] = "obj_destroy";
game["dialog"]["obj_capture"] = "capture_obj";
game["dialog"]["objs_capture"] = "capture_objs";
game["dialog"]["hq_located"] = "hq_located";
game["dialog"]["hq_enemy_captured"] = "hq_captured";
game["dialog"]["hq_enemy_destroyed"] = "hq_destroyed";
game["dialog"]["hq_secured"] = "hq_secured";
game["dialog"]["hq_offline"] = "hq_offline";
game["dialog"]["hq_online"] = "hq_online";
game["dialog"]["move_to_new"] = "new_positions";
game["dialog"]["push_forward"] = "pushforward";
game["dialog"]["attack"] = "attack";
game["dialog"]["defend"] = "defend";
game["dialog"]["offense"] = "offense";
game["dialog"]["defense"] = "defense";
game["dialog"]["halftime"] = "halftime";
game["dialog"]["overtime"] = "overtime";
game["dialog"]["side_switch"] = "switching";
game["dialog"]["flag_taken"] = "ourflag";
game["dialog"]["flag_dropped"] = "ourflag_drop";
game["dialog"]["flag_returned"] = "ourflag_return";
game["dialog"]["flag_captured"] = "ourflag_capt";
game["dialog"]["flag_getback"] = "getback_ourflag";
game["dialog"]["enemy_flag_bringhome"] = "enemyflag_tobase";
game["dialog"]["enemy_flag_taken"] = "enemyflag";
game["dialog"]["enemy_flag_dropped"] = "enemyflag_drop";
game["dialog"]["enemy_flag_returned"] = "enemyflag_return";
game["dialog"]["enemy_flag_captured"] = "enemyflag_capt";
game["dialog"]["capturing_a"] = "capturing_a";
game["dialog"]["capturing_b"] = "capturing_b";
game["dialog"]["capturing_c"] = "capturing_c";
game["dialog"]["captured_a"] = "capture_a";
game["dialog"]["captured_b"] = "capture_c";
game["dialog"]["captured_c"] = "capture_b";
game["dialog"]["securing_a"] = "securing_a";
game["dialog"]["securing_b"] = "securing_b";
game["dialog"]["securing_c"] = "securing_c";
game["dialog"]["secured_a"] = "secure_a";
game["dialog"]["secured_b"] = "secure_b";
game["dialog"]["secured_c"] = "secure_c";
game["dialog"]["losing_a"] = "losing_a";
game["dialog"]["losing_b"] = "losing_b";
game["dialog"]["losing_c"] = "losing_c";
game["dialog"]["lost_a"] = "lost_a";
game["dialog"]["lost_b"] = "lost_b";
game["dialog"]["lost_c"] = "lost_c";
game["dialog"]["enemy_taking_a"] = "enemy_take_a";
game["dialog"]["enemy_taking_b"] = "enemy_take_b";
game["dialog"]["enemy_taking_c"] = "enemy_take_c";
game["dialog"]["enemy_has_a"] = "enemy_has_a";
game["dialog"]["enemy_has_b"] = "enemy_has_b";
game["dialog"]["enemy_has_c"] = "enemy_has_c";
game["dialog"]["lost_all"] = "take_positions";
game["dialog"]["secure_all"] = "positions_lock";
game["dialog"]["destroy_sentry"] = "dest_sentrygun";
game["music"]["nuke_music"] = "nuke_music";
game["dialog"]["sentry_gone"] = "sentry_gone";
game["dialog"]["sentry_destroyed"] = "sentry_gone";
game["dialog"]["ti_gone"] = "ti_cancelled";
game["dialog"]["ti_destroyed"] = "ti_blocked";
level thread onPlayerConnect();
level thread onLastAlive();
level thread musicController();
level thread onGameEnded();
level thread onRoundSwitch();
}
onPlayerConnect()
{
for(;;)
{
level waittill ( "connected", player );
player thread onPlayerSpawned();
player thread finalKillcamMusic();
}
}
onPlayerSpawned()
{
self endon ( "disconnect" );
self waittill( "spawned_player" );
if ( !level._splitscreen || level._splitscreen && !isDefined( level._playedStartingMusic ) )
{
self playLocalSound( game["music"]["spawn_" + self.team] );
if ( level._splitscreen )
level._playedStartingMusic = true;
}
if ( isDefined( game["dialog"]["gametype"] ) && (!level._splitscreen || self == level._players[0]) )
{
if ( isDefined( game["dialog"]["allies_gametype"] ) && self.team == "allies" )
self leaderDialogOnPlayer( "allies_gametype" );
else if ( isDefined( game["dialog"]["axis_gametype"] ) && self.team == "axis" )
self leaderDialogOnPlayer( "axis_gametype" );
else
self leaderDialogOnPlayer( "gametype" );
}
gameFlagWait( "prematch_done" );
if ( self.team == game["attackers"] )
self leaderDialogOnPlayer( "offense_obj", "introboost" );
else
self leaderDialogOnPlayer( "defense_obj", "introboost" );
}
onLastAlive()
{
level endon ( "game_ended" );
level waittill ( "last_alive", player );
if ( !isAlive( player ) )
return;
player leaderDialogOnPlayer( "last_alive" );
}
onRoundSwitch()
{
level waittill ( "round_switch", switchType );
if( !isDefined( level._disableRoundSwitchVo ))
{
switch( switchType )
{
case "halftime":
foreach ( player in level._players )
player leaderDialogOnPlayer( "halftime" );
break;
case "overtime":
foreach ( player in level._players )
player leaderDialogOnPlayer( "overtime" );
break;
default:
foreach ( player in level._players )
player leaderDialogOnPlayer( "side_switch" );
break;
}
}
}
onGameEnded()
{
level thread roundWinnerDialog();
level thread gameWinnerDialog();
level waittill ( "game_win", winner );
if ( isDefined( level._nukeDetonated ) )
{
if ( !level._splitScreen )
playSoundOnPlayers( game["music"]["nuke_music"] );
else
level._players[0] playLocalSound( game["music"]["nuke_music"] );
return;
}
if ( level._teamBased )
{
if ( level._splitscreen )
{
if ( winner == "allies" )
playSoundOnPlayers( game["music"]["victory_allies"], "allies" );
else if ( winner == "axis" )
playSoundOnPlayers( game["music"]["victory_axis"], "axis" );
else
playSoundOnPlayers( game["music"]["nuke_music"] );
}
else
{
if ( winner == "allies" )
{
playSoundOnPlayers( game["music"]["victory_allies"], "allies" );
playSoundOnPlayers( game["music"]["defeat_axis"], "axis" );
}
else if ( winner == "axis" )
{
playSoundOnPlayers( game["music"]["victory_axis"], "axis" );
playSoundOnPlayers( game["music"]["defeat_allies"], "allies" );
}
else
{
playSoundOnPlayers( game["music"]["nuke_music"] );
}
}
}
else
{
foreach ( player in level._players )
{
if ( player.pers["team"] != "allies" && player.pers["team"] != "axis" )
player playLocalSound( game["music"]["nuke_music"] );
else if ( isDefined( winner ) && player == winner )
player playLocalSound( game["music"]["victory_" + player.pers["team"] ] );
else if ( !level._splitScreen )
player playLocalSound( game["music"]["defeat_" + player.pers["team"] ] );
}
}
}
roundWinnerDialog()
{
level waittill ( "round_win", winner );
delay = level._roundEndDelay / 4;
if ( delay > 0 )
wait ( delay );
if ( !isDefined( winner ) || isPlayer( winner ) || isDefined( level._nukeDetonated ) )
return;
if ( winner == "allies" )
{
leaderDialog( "round_success", "allies" );
leaderDialog( "round_failure", "axis" );
}
else if ( winner == "axis" )
{
leaderDialog( "round_success", "axis" );
leaderDialog( "round_failure", "allies" );
}
}
gameWinnerDialog()
{
level waittill ( "game_win", winner );
delay = level._postRoundTime / 2;
if ( delay > 0 )
wait ( delay );
if ( !isDefined( winner ) || isPlayer( winner ) || isDefined( level._nukeDetonated ) )
return;
if ( winner == "allies" )
{
leaderDialog( "mission_success", "allies" );
leaderDialog( "mission_failure", "axis" );
}
else if ( winner == "axis" )
{
leaderDialog( "mission_success", "axis" );
leaderDialog( "mission_failure", "allies" );
}
else
{
leaderDialog( "mission_draw" );
}
}
musicController()
{
level endon ( "game_ended" );
if ( !level._hardcoreMode )
thread suspenseMusic();
level waittill ( "match_ending_soon", reason );
assert( isDefined( reason ) );
if ( getWatchedDvar( "roundlimit" ) == 1 || game["roundsPlayed"] == (getWatchedDvar( "roundlimit" ) - 1) )
{
if ( !level._splitScreen )
{
if ( reason == "time" )
{
if ( level._teamBased )
{
if ( game["teamScores"]["allies"] > game["teamScores"]["axis"] )
{
if ( !level._hardcoreMode )
{
playSoundOnPlayers( game["music"]["winning_allies"], "allies" );
playSoundOnPlayers( game["music"]["losing_axis"], "axis" );
}
leaderDialog( "winning_time", "allies" );
leaderDialog( "losing_time", "axis" );
}
else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
if ( !level._hardcoreMode )
{
playSoundOnPlayers( game["music"]["winning_axis"], "axis" );
playSoundOnPlayers( game["music"]["losing_allies"], "allies" );
}
leaderDialog( "winning_time", "axis" );
leaderDialog( "losing_time", "allies" );
}
}
else
{
if ( !level._hardcoreMode )
playSoundOnPlayers( game["music"]["losing_time"] );
leaderDialog( "timesup" );
}
}
else if ( reason == "score" )
{
if ( level._teamBased )
{
if ( game["teamScores"]["allies"] > game["teamScores"]["axis"] )
{
if ( !level._hardcoreMode )
{
playSoundOnPlayers( game["music"]["winning_allies"], "allies" );
playSoundOnPlayers( game["music"]["losing_axis"], "axis" );
}
leaderDialog( "winning_score", "allies" );
leaderDialog( "losing_score", "axis" );
}
else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
if ( !level._hardcoreMode )
{
playSoundOnPlayers( game["music"]["winning_axis"], "axis" );
playSoundOnPlayers( game["music"]["losing_allies"], "allies" );
}
leaderDialog( "winning_score", "axis" );
leaderDialog( "losing_score", "allies" );
}
}
else
{
winningPlayer = maps\mp\gametypes\_gamescore::getHighestScoringPlayer();
losingPlayers = maps\mp\gametypes\_gamescore::getLosingPlayers();
excludeList[0] = winningPlayer;
if ( !level._hardcoreMode )
{
winningPlayer playLocalSound( game["music"]["winning_" + winningPlayer.pers["team"] ] );
foreach ( otherPlayer in level._players )
{
if ( otherPlayer == winningPlayer )
continue;
otherPlayer playLocalSound( game["music"]["losing_" + otherPlayer.pers["team"] ] );
}
}
winningPlayer leaderDialogOnPlayer( "winning_score" );
leaderDialogOnPlayers( "losing_score", losingPlayers );
}
}
level waittill ( "match_ending_very_soon" );
leaderDialog( "timesup" );
}
}
else
{
if ( !level._hardcoreMode )
playSoundOnPlayers( game["music"]["losing_allies"] );
leaderDialog( "timesup" );
}
}
suspenseMusic()
{
level endon ( "game_ended" );
level endon ( "match_ending_soon" );
numTracks = game["music"]["suspense"].size;
for ( ;; )
{
wait ( randomFloatRange( 60, 120 ) );
playSoundOnPlayers( game["music"]["suspense"][randomInt(numTracks)] );
}
}
finalKillcamMusic()
{
self waittill ( "showing_final_killcam" );
//self playLocalSound( game["music"]["winning"] );
}

View File

@ -0,0 +1,163 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
init()
{
precacheShader("objpoint_default");
level._objPointNames = [];
level._objPoints = [];
if ( level._splitscreen )
level._objPointSize = 15;
else
level._objPointSize = 8;
level._objpoint_alpha_default = .5;
level._objPointScale = 1.0;
}
createTeamObjpoint( name, origin, team, shader, alpha, scale )
{
if( !level._multiteambased )
{
assert( team == "axis" || team == "allies" || team == "all" );
}
objPoint = getObjPointByName( name );
if ( isDefined( objPoint ) )
deleteObjPoint( objPoint );
if ( !isDefined( shader ) )
shader = "objpoint_default";
if ( !isDefined( scale ) )
scale = 1.0;
if ( team != "all" )
objPoint = newTeamHudElem( team );
else
objPoint = newHudElem();
objPoint.name = name;
objPoint.x = origin[0];
objPoint.y = origin[1];
objPoint.z = origin[2];
objPoint.team = team;
objPoint.isFlashing = false;
objPoint.isShown = true;
objPoint setShader( shader, level._objPointSize, level._objPointSize );
objPoint setWaypoint( true, false );
if ( isDefined( alpha ) )
objPoint.alpha = alpha;
else
objPoint.alpha = level._objpoint_alpha_default;
objPoint.baseAlpha = objPoint.alpha;
objPoint.index = level._objPointNames.size;
level._objPoints[name] = objPoint;
level._objPointNames[level._objPointNames.size] = name;
return objPoint;
}
deleteObjPoint( oldObjPoint )
{
assert( level._objPoints.size == level._objPointNames.size );
if ( level._objPoints.size == 1 )
{
assert( level._objPointNames[0] == oldObjPoint.name );
assert( isDefined( level._objPoints[oldObjPoint.name] ) );
level._objPoints = [];
level._objPointNames = [];
oldObjPoint destroy();
return;
}
newIndex = oldObjPoint.index;
oldIndex = (level._objPointNames.size - 1);
objPoint = getObjPointByIndex( oldIndex );
level._objPointNames[newIndex] = objPoint.name;
objPoint.index = newIndex;
level._objPointNames[oldIndex] = undefined;
level._objPoints[oldObjPoint.name] = undefined;
oldObjPoint destroy();
}
updateOrigin( origin )
{
if ( self.x != origin[0] )
self.x = origin[0];
if ( self.y != origin[1] )
self.y = origin[1];
if ( self.z != origin[2] )
self.z = origin[2];
}
setOriginByName( name, origin )
{
objPoint = getObjPointByName( name );
objPoint updateOrigin( origin );
}
getObjPointByName( name )
{
if ( isDefined( level._objPoints[name] ) )
return level._objPoints[name];
else
return undefined;
}
getObjPointByIndex( index )
{
if ( isDefined( level._objPointNames[index] ) )
return level._objPoints[level._objPointNames[index]];
else
return undefined;
}
startFlashing()
{
self endon("stop_flashing_thread");
if ( self.isFlashing )
return;
self.isFlashing = true;
while ( self.isFlashing )
{
self fadeOverTime( 0.75 );
self.alpha = 0.35 * self.baseAlpha;
wait ( 0.75 );
self fadeOverTime( 0.75 );
self.alpha = self.baseAlpha;
wait ( 0.75 );
}
self.alpha = self.baseAlpha;
}
stopFlashing()
{
if ( !self.isFlashing )
return;
self.isFlashing = false;
}

View File

@ -0,0 +1,232 @@
#include maps\mp\_utility;
init()
{
level._persistentDataInfo = [];
maps\mp\gametypes\_class::init();
maps\mp\gametypes\_rank::init();
maps\mp\gametypes\_missions::init();
maps\mp\gametypes\_playercards::init();
level thread updateBufferedStats();
}
initBufferedStats()
{
self.bufferedStats = [];
self.bufferedStats[ "totalShots" ] = self getPlayerData( "totalShots" );
self.bufferedStats[ "accuracy" ] = self getPlayerData( "accuracy" );
self.bufferedStats[ "misses" ] = self getPlayerData( "misses" );
self.bufferedStats[ "hits" ] = self getPlayerData( "hits" );
self.bufferedStats[ "timePlayedAllies" ] = self getPlayerData( "timePlayedAllies" );
self.bufferedStats[ "timePlayedOpfor" ] = self getPlayerData( "timePlayedOpfor" );
self.bufferedStats[ "timePlayedOther" ] = self getPlayerData( "timePlayedOther" );
self.bufferedStats[ "timePlayedTotal" ] = self getPlayerData( "timePlayedTotal" );
self.bufferedChildStats = [];
self.bufferedChildStats[ "round" ] = [];
self.bufferedChildStats[ "round" ][ "timePlayed" ] = self getPlayerData( "round", "timePlayed" );
}
// ==========================================
// Script persistent data functions
// These are made for convenience, so persistent data can be tracked by strings.
// They make use of code functions which are prototyped below.
/*
=============
statGet
Returns the value of the named stat
=============
*/
statGet( dataName )
{
assert( !isDefined( self.bufferedStats[ dataName ] ) ); // should use statGetBuffered consistently with statSetBuffered
return self GetPlayerData( dataName );
}
/*
=============
statSet
Sets the value of the named stat
=============
*/
statSet( dataName, value )
{
assert( !isDefined( self.bufferedStats[ dataName ] ) ); // should use statGetBuffered consistently with statSetBuffered
if ( !self rankingEnabled() )
return;
self SetPlayerData( dataName, value );
}
/*
=============
statAdd
Adds the passed value to the value of the named stat
=============
*/
statAdd( dataName, value )
{
assert( !isDefined( self.bufferedStats[ dataName ] ) ); // should use statGetBuffered consistently with statSetBuffered
if ( !self rankingEnabled() )
return;
curValue = self GetPlayerData( dataName );
self SetPlayerData( dataName, value + curValue );
}
statGetChild( parent, child )
{
return self GetPlayerData( parent, child );
}
statSetChild( parent, child, value )
{
if ( !self rankingEnabled() )
return;
self SetPlayerData( parent, child, value );
}
statAddChild( parent, child, value )
{
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
if ( !self rankingEnabled() )
return;
curValue = self GetPlayerData( parent, child );
self SetPlayerData( parent, child, curValue + value );
}
statGetChildBuffered( parent, child )
{
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
return self.bufferedChildStats[ parent ][ child ];
}
statSetChildBuffered( parent, child, value )
{
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
if ( !self rankingEnabled() )
return;
self.bufferedChildStats[ parent ][ child ] = value;
}
statAddChildBuffered( parent, child, value )
{
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
if ( !self rankingEnabled() )
return;
curValue = statGetChildBuffered( parent, child );
statSetChildBuffered( parent, child, curValue + value );
}
/*
=============
statGetBuffered
Returns the value of the named stat
=============
*/
statGetBuffered( dataName )
{
assert( isDefined( self.bufferedStats[ dataName ] ) );
return self.bufferedStats[ dataName ];
}
/*
=============
statSet
Sets the value of the named stat
=============
*/
statSetBuffered( dataName, value )
{
assert( isDefined( self.bufferedStats[ dataName ] ) );
if ( !self rankingEnabled() )
return;
self.bufferedStats[ dataName ] = value;
}
/*
=============
statAdd
Adds the passed value to the value of the named stat
=============
*/
statAddBuffered( dataName, value )
{
assert( isDefined( self.bufferedStats[ dataName ] ) );
if ( !self rankingEnabled() )
return;
curValue = statGetBuffered( dataName );
statSetBuffered( dataName, curValue + value );
}
updateBufferedStats()
{
// give the first player time to connect
wait ( 0.15 );
nextToUpdate = 0;
while ( !level._gameEnded )
{
nextToUpdate++;
if ( nextToUpdate >= level._players.size )
nextToUpdate = 0;
if ( isDefined( level._players[nextToUpdate] ) )
level._players[nextToUpdate] writeBufferedStats();
wait ( 2.0 );
}
foreach ( player in level._players )
player writeBufferedStats();
}
writeBufferedStats()
{
foreach ( statName, statVal in self.bufferedStats )
{
self setPlayerData( statName, statVal );
}
foreach ( statName, statVal in self.bufferedChildStats )
{
foreach ( childStatName, childStatVal in statVal )
self setPlayerData( statName, childStatName, childStatVal );
}
}

View File

@ -0,0 +1,29 @@
#include common_scripts\utility;
#include maps\mp\_utility;
init()
{
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
//@NOTE: Should we make sure they're really unlocked before setting them? Catch cheaters...
// e.g. isItemUnlocked( iconHandle )
iconHandle = player maps\mp\gametypes\_persistence::statGet( "cardIcon" );
player SetCardIcon( iconHandle );
titleHandle = player maps\mp\gametypes\_persistence::statGet( "cardTitle" );
player SetCardTitle( titleHandle );
nameplateHandle = player maps\mp\gametypes\_persistence::statGet( "cardNameplate" );
player SetCardNameplate( nameplateHandle );
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,270 @@
init()
{
game["menu_quickcommands"] = "quickcommands";
game["menu_quickstatements"] = "quickstatements";
game["menu_quickresponses"] = "quickresponses";
precacheMenu(game["menu_quickcommands"]);
precacheMenu(game["menu_quickstatements"]);
precacheMenu(game["menu_quickresponses"]);
precacheHeadIcon("talkingicon");
precacheString( &"QUICKMESSAGE_FOLLOW_ME" );
precacheString( &"QUICKMESSAGE_MOVE_IN" );
precacheString( &"QUICKMESSAGE_FALL_BACK" );
precacheString( &"QUICKMESSAGE_SUPPRESSING_FIRE" );
precacheString( &"QUICKMESSAGE_ATTACK_LEFT_FLANK" );
precacheString( &"QUICKMESSAGE_ATTACK_RIGHT_FLANK" );
precacheString( &"QUICKMESSAGE_HOLD_THIS_POSITION" );
precacheString( &"QUICKMESSAGE_REGROUP" );
precacheString( &"QUICKMESSAGE_ENEMY_SPOTTED" );
precacheString( &"QUICKMESSAGE_ENEMIES_SPOTTED" );
precacheString( &"QUICKMESSAGE_IM_IN_POSITION" );
precacheString( &"QUICKMESSAGE_AREA_SECURE" );
precacheString( &"QUICKMESSAGE_GRENADE" );
precacheString( &"QUICKMESSAGE_SNIPER" );
precacheString( &"QUICKMESSAGE_NEED_REINFORCEMENTS" );
precacheString( &"QUICKMESSAGE_HOLD_YOUR_FIRE" );
precacheString( &"QUICKMESSAGE_YES_SIR" );
precacheString( &"QUICKMESSAGE_NO_SIR" );
precacheString( &"QUICKMESSAGE_IM_ON_MY_WAY" );
precacheString( &"QUICKMESSAGE_SORRY" );
precacheString( &"QUICKMESSAGE_GREAT_SHOT" );
precacheString( &"QUICKMESSAGE_TOOK_LONG_ENOUGH" );
precacheString( &"QUICKMESSAGE_ARE_YOU_CRAZY" );
precacheString( &"QUICKMESSAGE_WATCH_SIX" );
precacheString( &"QUICKMESSAGE_COME_ON" );
}
quickcommands(response)
{
self endon ( "disconnect" );
if(!isdefined(self.pers["team"]) || self.pers["team"] == "spectator" || isdefined(self.spamdelay))
return;
self.spamdelay = true;
switch(response)
{
case "1":
soundalias = "mp_cmd_followme";
saytext = &"QUICKMESSAGE_FOLLOW_ME";
//saytext = "Follow Me!";
break;
case "2":
soundalias = "mp_cmd_movein";
saytext = &"QUICKMESSAGE_MOVE_IN";
//saytext = "Move in!";
break;
case "3":
soundalias = "mp_cmd_fallback";
saytext = &"QUICKMESSAGE_FALL_BACK";
//saytext = "Fall back!";
break;
case "4":
soundalias = "mp_cmd_suppressfire";
saytext = &"QUICKMESSAGE_SUPPRESSING_FIRE";
//saytext = "Suppressing fire!";
break;
case "5":
soundalias = "mp_cmd_attackleftflank";
saytext = &"QUICKMESSAGE_ATTACK_LEFT_FLANK";
//saytext = "Attack left flank!";
break;
case "6":
soundalias = "mp_cmd_attackrightflank";
saytext = &"QUICKMESSAGE_ATTACK_RIGHT_FLANK";
//saytext = "Attack right flank!";
break;
case "7":
soundalias = "mp_cmd_holdposition";
saytext = &"QUICKMESSAGE_HOLD_THIS_POSITION";
//saytext = "Hold this position!";
break;
default:
assert(response == "8");
soundalias = "mp_cmd_regroup";
saytext = &"QUICKMESSAGE_REGROUP";
//saytext = "Regroup!";
break;
}
self saveHeadIcon();
self doQuickMessage(soundalias, saytext);
wait 2;
self.spamdelay = undefined;
self restoreHeadIcon();
}
quickstatements(response)
{
if(!isdefined(self.pers["team"]) || self.pers["team"] == "spectator" || isdefined(self.spamdelay))
return;
self.spamdelay = true;
switch(response)
{
case "1":
soundalias = "mp_stm_enemyspotted";
saytext = &"QUICKMESSAGE_ENEMY_SPOTTED";
//saytext = "Enemy spotted!";
break;
case "2":
soundalias = "mp_stm_enemiesspotted";
saytext = &"QUICKMESSAGE_ENEMIES_SPOTTED";
//saytext = "Enemy down!";
break;
case "3":
soundalias = "mp_stm_iminposition";
saytext = &"QUICKMESSAGE_IM_IN_POSITION";
//saytext = "I'm in position.";
break;
case "4":
soundalias = "mp_stm_areasecure";
saytext = &"QUICKMESSAGE_AREA_SECURE";
//saytext = "Area secure!";
break;
case "5":
soundalias = "mp_stm_watchsix";
saytext = &"QUICKMESSAGE_WATCH_SIX";
//saytext = "Grenade!";
break;
case "6":
soundalias = "mp_stm_sniper";
saytext = &"QUICKMESSAGE_SNIPER";
//saytext = "Sniper!";
break;
default:
assert(response == "7");
soundalias = "mp_stm_needreinforcements";
saytext = &"QUICKMESSAGE_NEED_REINFORCEMENTS";
//saytext = "Need reinforcements!";
break;
}
self saveHeadIcon();
self doQuickMessage(soundalias, saytext);
wait 2;
self.spamdelay = undefined;
self restoreHeadIcon();
}
quickresponses(response)
{
if(!isdefined(self.pers["team"]) || self.pers["team"] == "spectator" || isdefined(self.spamdelay))
return;
self.spamdelay = true;
switch(response)
{
case "1":
soundalias = "mp_rsp_yessir";
saytext = &"QUICKMESSAGE_YES_SIR";
//saytext = "Yes Sir!";
break;
case "2":
soundalias = "mp_rsp_nosir";
saytext = &"QUICKMESSAGE_NO_SIR";
//saytext = "No Sir!";
break;
case "3":
soundalias = "mp_rsp_onmyway";
saytext = &"QUICKMESSAGE_IM_ON_MY_WAY";
//saytext = "On my way.";
break;
case "4":
soundalias = "mp_rsp_sorry";
saytext = &"QUICKMESSAGE_SORRY";
//saytext = "Sorry.";
break;
case "5":
soundalias = "mp_rsp_greatshot";
saytext = &"QUICKMESSAGE_GREAT_SHOT";
//saytext = "Great shot!";
break;
default:
assert(response == "6");
soundalias = "mp_rsp_comeon";
saytext = &"QUICKMESSAGE_COME_ON";
//saytext = "Took long enough!";
break;
}
self saveHeadIcon();
self doQuickMessage(soundalias, saytext);
wait 2;
self.spamdelay = undefined;
self restoreHeadIcon();
}
doQuickMessage( soundalias, saytext )
{
if(self.sessionstate != "playing")
return;
prefix = maps\mp\gametypes\_teams::getTeamVoicePrefix( self.team );
if(isdefined(level._QuickMessageToAll) && level._QuickMessageToAll)
{
self.headiconteam = "none";
self.headicon = "talkingicon";
self playSound( prefix+soundalias );
self sayAll(saytext);
}
else
{
if(self.sessionteam == "allies")
self.headiconteam = "allies";
else if(self.sessionteam == "axis")
self.headiconteam = "axis";
self.headicon = "talkingicon";
self playSound( prefix+soundalias );
self sayTeam( saytext );
self pingPlayer();
}
}
saveHeadIcon()
{
if(isdefined(self.headicon))
self.oldheadicon = self.headicon;
if(isdefined(self.headiconteam))
self.oldheadiconteam = self.headiconteam;
}
restoreHeadIcon()
{
if(isdefined(self.oldheadicon))
self.headicon = self.oldheadicon;
if(isdefined(self.oldheadiconteam))
self.headiconteam = self.oldheadiconteam;
}

799
maps/mp/gametypes/_rank.gsc Normal file
View File

@ -0,0 +1,799 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
//Those are the fraction of total possible assist points that is given to the player
//For example, with level 1 assist, the player is given 25% of the total possible assist points
LEVEL_1_ASSIST = 0.25;
LEVEL_2_ASSIST = 0.50;
LEVEL_3_ASSIST = 0.75;
GRENADE_ASSIST = 0.625;
init()
{
level._scoreInfo = [];
level._xpScale = getDvarInt( "scr_xpscale" );
if ( level._xpScale > 4 || level._xpScale < 0)
exitLevel( false );
level._xpScale = min( level._xpScale, 4 );
level._xpScale = max( level._xpScale, 0 );
level._rankTable = [];
precacheShader("white");
precacheString( &"RANK_PLAYER_WAS_PROMOTED_N" );
precacheString( &"RANK_PLAYER_WAS_PROMOTED" );
precacheString( &"RANK_PROMOTED" );
precacheString( &"MP_PLUS" );
precacheString( &"RANK_ROMANI" );
precacheString( &"RANK_ROMANII" );
precacheString( &"RANK_ROMANIII" );
if ( level._teamBased )
{
registerScoreInfo( "kill", 100 );
registerScoreInfo( "headshot", 100 );
registerScoreInfo( "assist", 80 );
registerScoreInfo( "suicide", 0 );
registerScoreInfo( "teamkill", 0 );
}
else
{
registerScoreInfo( "kill", 50 );
registerScoreInfo( "headshot", 50 );
registerScoreInfo( "assist", 0 );
registerScoreInfo( "suicide", 0 );
registerScoreInfo( "teamkill", 0 );
}
registerScoreInfo( "win", 1 );
registerScoreInfo( "loss", 0.5 );
registerScoreInfo( "tie", 0.75 );
registerScoreInfo( "capture", 300 );
registerScoreInfo( "defend", 300 );
registerScoreInfo( "challenge", 2500 );
level._maxRank = int(tableLookup( "mp/rankTable.csv", 0, "maxrank", 1 ));
level._maxPrestige = int(tableLookup( "mp/rankIconTable.csv", 0, "maxprestige", 1 ));
pId = 0;
rId = 0;
for ( pId = 0; pId <= level._maxPrestige; pId++ )
{
for ( rId = 0; rId <= level._maxRank; rId++ )
precacheShader( tableLookup( "mp/rankIconTable.csv", 0, rId, pId+1 ) );
}
rankId = 0;
rankName = tableLookup( "mp/ranktable.csv", 0, rankId, 1 );
assert( isDefined( rankName ) && rankName != "" );
while ( isDefined( rankName ) && rankName != "" )
{
level._rankTable[rankId][1] = tableLookup( "mp/ranktable.csv", 0, rankId, 1 );
level._rankTable[rankId][2] = tableLookup( "mp/ranktable.csv", 0, rankId, 2 );
level._rankTable[rankId][3] = tableLookup( "mp/ranktable.csv", 0, rankId, 3 );
level._rankTable[rankId][7] = tableLookup( "mp/ranktable.csv", 0, rankId, 7 );
precacheString( tableLookupIString( "mp/ranktable.csv", 0, rankId, 16 ) );
rankId++;
rankName = tableLookup( "mp/ranktable.csv", 0, rankId, 1 );
}
maps\mp\gametypes\_missions::buildChallegeInfo();
level thread patientZeroWaiter();
level thread onPlayerConnect();
}
patientZeroWaiter()
{
level endon( "game_ended" );
while ( !isDefined( level._players ) || !level._players.size )
wait ( 0.05 );
if ( !matchMakingGame() )
{
if ( (getDvar( "mapname" ) == "mp_rust" && randomInt( 1000 ) == 999) )
level._patientZeroName = level._players[0].name;
}
else
{
if ( getDvar( "scr_patientZero" ) != "" )
level._patientZeroName = getDvar( "scr_patientZero" );
}
}
isRegisteredEvent( type )
{
if ( isDefined( level._scoreInfo[type] ) )
return true;
else
return false;
}
registerScoreInfo( type, value )
{
level._scoreInfo[type]["value"] = value;
}
getScoreInfoValue( type )
{
assist_scalar = 1;
if ( IsSubStr ( type, "assist" ))
{
switch ( type )
{
case "assist_level_1":
assist_scalar = LEVEL_1_ASSIST;
break;
case "assist_level_2":
assist_scalar = LEVEL_2_ASSIST;
break;
case "assist_grenade":
assist_scalar = GRENADE_ASSIST;
break;
case "assist_level_3":
assist_scalar = LEVEL_3_ASSIST;
break;
}
type = "assist";
}
overrideDvar = "scr_" + level._gameType + "_score_" + type;
if ( getDvar( overrideDvar ) != "" )
{
return getDvarInt( overrideDvar );
}
else
{
return ( Int ( floor (level._scoreInfo[type]["value"] * assist_scalar )));
}
}
getScoreInfoLabel( type )
{
return ( level._scoreInfo[type]["label"] );
}
getRankInfoMinXP( rankId )
{
return int(level._rankTable[rankId][2]);
}
getRankInfoXPAmt( rankId )
{
return int(level._rankTable[rankId][3]);
}
getRankInfoMaxXp( rankId )
{
return int(level._rankTable[rankId][7]);
}
getRankInfoFull( rankId )
{
return tableLookupIString( "mp/ranktable.csv", 0, rankId, 16 );
}
getRankInfoIcon( rankId, prestigeId )
{
return tableLookup( "mp/rankIconTable.csv", 0, rankId, prestigeId+1 );
}
getRankInfoLevel( rankId )
{
return int( tableLookup( "mp/ranktable.csv", 0, rankId, 13 ) );
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
/#
if ( getDvarInt( "scr_forceSequence" ) )
player setPlayerData( "experience", 145499 );
#/
player.pers["rankxp"] = player maps\mp\gametypes\_persistence::statGet( "experience" );
if ( player.pers["rankxp"] < 0 ) // paranoid defensive
player.pers["rankxp"] = 0;
player.pers["rankxpstart"] = player.pers["rankxp"]; // let's remember what XP we started with.
rankId = player getRankForXp( player getRankXP() );
player.pers[ "rank" ] = rankId;
player.pers[ "participation" ] = 0;
player.xpUpdateTotal = 0;
player.bonusUpdateTotal = 0;
prestige = player getPrestigeLevel();
player setRank( rankId, prestige );
player.pers["prestige"] = prestige;
player.postGamePromotion = false;
if ( !isDefined( player.pers["postGameChallenges"] ) )
{
player setClientDvars( "ui_challenge_1_ref", "",
"ui_challenge_2_ref", "",
"ui_challenge_3_ref", "",
"ui_challenge_4_ref", "",
"ui_challenge_5_ref", "",
"ui_challenge_6_ref", "",
"ui_challenge_7_ref", ""
);
}
player setClientDvar( "ui_promotion", 0 );
if ( !isDefined( player.pers["summary"] ) )
{
player.pers["summary"] = [];
player.pers["summary"]["xp"] = 0;
player.pers["summary"]["score"] = 0;
player.pers["summary"]["challenge"] = 0;
player.pers["summary"]["match"] = 0;
player.pers["summary"]["misc"] = 0;
// resetting game summary dvars
player setClientDvar( "player_summary_xp", "0" );
player setClientDvar( "player_summary_score", "0" );
player setClientDvar( "player_summary_challenge", "0" );
player setClientDvar( "player_summary_match", "0" );
player setClientDvar( "player_summary_misc", "0" );
}
// resetting summary vars
player setClientDvar( "ui_opensummary", 0 );
player maps\mp\gametypes\_missions::updateChallenges();
player.explosiveKills[0] = 0;
player.xpGains = [];
player.hud_xpEventPopup = player createXpEventPopup();
player.hud_scorePopup = newClientHudElem( player );
player.hud_scorePopup.horzAlign = "center";
player.hud_scorePopup.vertAlign = "middle";
player.hud_scorePopup.alignX = "center";
player.hud_scorePopup.alignY = "middle";
player.hud_scorePopup.x = 0;
if ( level._splitScreen )
player.hud_scorePopup.y = -40;
else
player.hud_scorePopup.y = -60;
player.hud_scorePopup.font = "hudbig";
player.hud_scorePopup.fontscale = 0.75;
player.hud_scorePopup.archived = false;
player.hud_scorePopup.color = (0.5,0.5,0.5);
player.hud_scorePopup.sort = 10000;
player.hud_scorePopup maps\mp\gametypes\_hud::fontPulseInit( 3.0 );
player thread onPlayerSpawned();
player thread onJoinedTeam();
player thread onJoinedSpectators();
}
}
onJoinedTeam()
{
self endon("disconnect");
for(;;)
{
self waittill( "joined_team" );
self thread removeRankHUD();
}
}
onJoinedSpectators()
{
self endon("disconnect");
for(;;)
{
self waittill( "joined_spectators" );
self thread removeRankHUD();
}
}
onPlayerSpawned()
{
self endon("disconnect");
for(;;)
{
self waittill("spawned_player");
}
}
roundUp( floatVal )
{
if ( int( floatVal ) != floatVal )
return int( floatVal+1 );
else
return int( floatVal );
}
giveRankXP( type, value )
{
self endon("disconnect");
lootType = "none";
if ( !self rankingEnabled() )
return;
if( level._multiTeamBased )
{
numteams = 0;
for( i = 0; i < level._teamNameList.size; i++ )
{
if( level._teamCount[level._teamNameList[i]] )
{
numteams = numteams + 1;
}
}
if( numteams < 2 )
{
return;
}
}
else if ( level._teamBased && (!level._teamCount["allies"] || !level._teamCount["axis"]) )
return;
else if ( !level._teamBased && (level._teamCount["allies"] + level._teamCount["axis"] < 2) )
return;
if ( !isDefined( value ) )
value = getScoreInfoValue( type );
if ( !isDefined( self.xpGains[type] ) )
self.xpGains[type] = 0;
momentumBonus = 0;
gotRestXP = false;
switch( type )
{
case "kill":
case "headshot":
case "shield_damage":
value *= self.xpScaler;
case "assist":
case "suicide":
case "teamkill":
case "capture":
case "defend":
case "return":
case "pickup":
case "assault":
case "plant":
case "destroy":
case "save":
case "defuse":
case "escortcheckpoint":
if ( getGametypeNumLives() > 0 )
{
multiplier = max(1,int( 10/getGametypeNumLives() ));
value = int(value * multiplier);
}
value = int( value * level._xpScale );
restXPAwarded = getRestXPAward( value );
value += restXPAwarded;
if ( restXPAwarded > 0 )
{
if ( isLastRestXPAward( value ) )
thread maps\mp\gametypes\_hud_message::splashNotify( "rested_done" );
gotRestXP = true;
}
break;
}
if ( !gotRestXP )
{
// if we didn't get rest XP for this type, we push the rest XP goal ahead so we didn't waste it
if ( self getPlayerData( "restXPGoal" ) > self getRankXP() )
self setPlayerData( "restXPGoal", self getPlayerData( "restXPGoal" ) + value );
}
if( getDvarInt( "prototype_adrenaline_enabled" ) == 1 )
{
value *= self maps\mp\_adrenaline::adrenalineGetXPMultiplier();
self maps\mp\_adrenaline::adrenalineSetXPEarned();
}
oldxp = self getRankXP();
self.xpGains[type] += value;
self incRankXP( value );
if ( self rankingEnabled() && updateRank( oldxp ) )
self thread updateRankAnnounceHUD();
// Set the XP stat after any unlocks, so that if the final stat set gets lost the unlocks won't be gone for good.
self syncXPStat();
if ( !level._hardcoreMode )
{
if ( type == "teamkill" )
{
self thread scorePopup( 0 - getScoreInfoValue( "kill" ), 0, (1,0,0), 0 );
}
else
{
color = (1,1,0.5);
if ( gotRestXP )
color = (1,.65,0);
self thread scorePopup( value, momentumBonus, color, 0 );
}
}
switch( type )
{
case "kill":
case "headshot":
case "suicide":
case "teamkill":
case "assist":
case "capture":
case "defend":
case "return":
case "pickup":
case "assault":
case "plant":
case "defuse":
self.pers["summary"]["score"] += value;
self.pers["summary"]["xp"] += value;
break;
case "win":
case "loss":
case "tie":
self.pers["summary"]["match"] += value;
self.pers["summary"]["xp"] += value;
break;
case "challenge":
self.pers["summary"]["challenge"] += value;
self.pers["summary"]["xp"] += value;
break;
default:
self.pers["summary"]["misc"] += value; //keeps track of ungrouped match xp reward
self.pers["summary"]["match"] += value;
self.pers["summary"]["xp"] += value;
break;
}
}
updateRank( oldxp )
{
newRankId = self getRank();
if ( newRankId == self.pers["rank"] )
return false;
oldRank = self.pers["rank"];
rankId = self.pers["rank"];
self.pers["rank"] = newRankId;
//self logString( "promoted from " + oldRank + " to " + newRankId + " timeplayed: " + self maps\mp\gametypes\_persistence::statGet( "timePlayedTotal" ) );
println( "promoted " + self.name + " from rank " + oldRank + " to " + newRankId + ". Experience went from " + oldxp + " to " + self getRankXP() + "." );
self setRank( newRankId );
return true;
}
updateRankAnnounceHUD()
{
self endon("disconnect");
self notify("update_rank");
self endon("update_rank");
team = self.pers["team"];
if ( !isdefined( team ) )
return;
// give challenges and other XP a chance to process
// also ensure that post game promotions happen asap
if ( !levelFlag( "game_over" ) )
level waittill_notify_or_timeout( "game_over", 0.25 );
newRankName = self getRankInfoFull( self.pers["rank"] );
rank_char = level._rankTable[self.pers["rank"]][1];
subRank = int(rank_char[rank_char.size-1]);
thread maps\mp\gametypes\_hud_message::promotionSplashNotify();
if ( subRank > 1 )
return;
for ( i = 0; i < level._players.size; i++ )
{
player = level._players[i];
playerteam = player.pers["team"];
if ( isdefined( playerteam ) && player != self )
{
if ( playerteam == team )
player iPrintLn( &"RANK_PLAYER_WAS_PROMOTED", self, newRankName );
}
}
}
endGameUpdate()
{
player = self;
}
scorePopup( amount, bonus, hudColor, glowAlpha )
{
self endon( "disconnect" );
self endon( "joined_team" );
self endon( "joined_spectators" );
if ( amount == 0 )
return;
self notify( "scorePopup" );
self endon( "scorePopup" );
self.xpUpdateTotal += amount;
self.bonusUpdateTotal += bonus;
wait ( 0.05 );
if ( self.xpUpdateTotal < 0 )
self.hud_scorePopup.label = &"";
else
self.hud_scorePopup.label = &"MP_PLUS";
self.hud_scorePopup.color = hudColor;
self.hud_scorePopup.glowColor = hudColor;
self.hud_scorePopup.glowAlpha = glowAlpha;
self.hud_scorePopup setValue(self.xpUpdateTotal);
self.hud_scorePopup.alpha = 0.85;
self.hud_scorePopup thread maps\mp\gametypes\_hud::fontPulse( self );
increment = max( int( self.bonusUpdateTotal / 20 ), 1 );
if ( self.bonusUpdateTotal )
{
while ( self.bonusUpdateTotal > 0 )
{
self.xpUpdateTotal += min( self.bonusUpdateTotal, increment );
self.bonusUpdateTotal -= min( self.bonusUpdateTotal, increment );
self.hud_scorePopup setValue( self.xpUpdateTotal );
wait ( 0.05 );
}
}
else
{
wait ( 1.0 );
}
self.hud_scorePopup fadeOverTime( 0.75 );
self.hud_scorePopup.alpha = 0;
self.xpUpdateTotal = 0;
}
removeRankHUD()
{
self.hud_scorePopup.alpha = 0;
}
getRank()
{
rankXp = self.pers["rankxp"];
rankId = self.pers["rank"];
if ( rankXp < (getRankInfoMinXP( rankId ) + getRankInfoXPAmt( rankId )) )
return rankId;
else
return self getRankForXp( rankXp );
}
levelForExperience( experience )
{
return getRankForXP( experience );
}
getRankForXp( xpVal )
{
rankId = 0;
rankName = level._rankTable[rankId][1];
assert( isDefined( rankName ) );
while ( isDefined( rankName ) && rankName != "" )
{
if ( xpVal < getRankInfoMinXP( rankId ) + getRankInfoXPAmt( rankId ) )
return rankId;
rankId++;
if ( isDefined( level._rankTable[rankId] ) )
rankName = level._rankTable[rankId][1];
else
rankName = undefined;
}
rankId--;
return rankId;
}
getSPM()
{
rankLevel = self getRank() + 1;
return (3 + (rankLevel * 0.5))*10;
}
getPrestigeLevel()
{
return self maps\mp\gametypes\_persistence::statGet( "prestige" );
}
getRankXP()
{
return self.pers["rankxp"];
}
getRankXPStart()
{
return self.pers["rankxpstart"];
}
incRankXP( amount )
{
if ( !self rankingEnabled() )
return;
if ( isDefined( self.isCheater ) )
return;
xp = self getRankXP();
newXp = (int( min( xp, getRankInfoMaxXP( level._maxRank ) ) ) + amount);
if ( self.pers["rank"] == level._maxRank && newXp >= getRankInfoMaxXP( level._maxRank ) )
newXp = getRankInfoMaxXP( level._maxRank );
self.pers["rankxp"] = newXp;
}
getRestXPAward( baseXP )
{
if ( !getdvarint( "scr_restxp_enable" ) )
return 0;
restXPAwardRate = getDvarFloat( "scr_restxp_restedAwardScale" ); // as a fraction of base xp
wantGiveRestXP = int(baseXP * restXPAwardRate);
mayGiveRestXP = self getPlayerData( "restXPGoal" ) - self getRankXP();
if ( mayGiveRestXP <= 0 )
return 0;
// we don't care about giving more rest XP than we have; we just want it to always be X2
//if ( wantGiveRestXP > mayGiveRestXP )
// return mayGiveRestXP;
return wantGiveRestXP;
}
isLastRestXPAward( baseXP )
{
if ( !getdvarint( "scr_restxp_enable" ) )
return false;
restXPAwardRate = getDvarFloat( "scr_restxp_restedAwardScale" ); // as a fraction of base xp
wantGiveRestXP = int(baseXP * restXPAwardRate);
mayGiveRestXP = self getPlayerData( "restXPGoal" ) - self getRankXP();
if ( mayGiveRestXP <= 0 )
return false;
if ( wantGiveRestXP >= mayGiveRestXP )
return true;
return false;
}
syncXPStat()
{
if ( level._xpScale > 4 || level._xpScale <= 0)
exitLevel( false );
xp = self getRankXP();
self maps\mp\gametypes\_persistence::statSet( "experience", xp );
}
createXpEventPopup()
{
hud_xpEventPopup = newClientHudElem( self );
hud_xpEventPopup.children = [];
hud_xpEventPopup.horzAlign = "center";
hud_xpEventPopup.vertAlign = "middle";
hud_xpEventPopup.alignX = "center";
hud_xpEventPopup.alignY = "middle";
hud_xpEventPopup.x = 55;
if ( level._splitScreen )
hud_xpEventPopup.y = -20;
else
hud_xpEventPopup.y = -35;
hud_xpEventPopup.font = "hudbig";
hud_xpEventPopup.fontscale = 0.65;
hud_xpEventPopup.archived = false;
hud_xpEventPopup.color = (0.5,0.5,0.5);
hud_xpEventPopup.sort = 10000;
hud_xpEventPopup.elemType = "msgText";
hud_xpEventPopup maps\mp\gametypes\_hud::fontPulseInit( 3.0 );
return hud_xpEventPopup;
}
xpEventPopup( event, hudColor, glowAlpha )
{
self endon( "disconnect" );
self endon( "joined_team" );
self endon( "joined_spectators" );
self notify( "xpEventPopup" );
self endon( "xpEventPopup" );
wait ( 0.05 );
if ( !isDefined( hudColor ) )
hudColor = (1,1,0.5);
if ( !isDefined( glowAlpha ) )
glowAlpha = 0;
self.hud_xpEventPopup.color = hudColor;
self.hud_xpEventPopup.glowColor = hudColor;
self.hud_xpEventPopup.glowAlpha = glowAlpha;
self.hud_xpEventPopup setText(event);
self.hud_xpEventPopup.alpha = 0.85;
wait ( 1.0 );
self.hud_xpEventPopup fadeOverTime( 0.75 );
self.hud_xpEventPopup.alpha = 0;
}

View File

@ -0,0 +1,103 @@
init()
{
level._hostname = getdvar("sv_hostname");
if(level._hostname == "")
level._hostname = "CoDHost";
setdvar("sv_hostname", level._hostname);
level._allowvote = getdvarint("g_allowvote", 1);
SetDvar("g_allowvote", level._allowvote);
makedvarserverinfo("ui_allowvote", level._allowvote);
level._friendlyfire = maps\mp\gametypes\_tweakables::getTweakableValue( "team", "fftype" );
makedvarserverinfo("ui_friendlyfire", level._friendlyfire);
constrainGameType(getdvar("g_gametype"));
for(;;)
{
updateServerSettings();
wait 5;
}
}
updateServerSettings()
{
sv_hostname = getdvar("sv_hostname");
if(level._hostname != sv_hostname)
{
level._hostname = sv_hostname;
}
g_allowvote = getdvarint("g_allowvote", 1);
if(level._allowvote != g_allowvote)
{
level._allowvote = g_allowvote;
setdvar("ui_allowvote", level._allowvote);
}
scr_friendlyfire = maps\mp\gametypes\_tweakables::getTweakableValue( "team", "fftype" );
if(level._friendlyfire != scr_friendlyfire)
{
level._friendlyfire = scr_friendlyfire;
setdvar("ui_friendlyfire", level._friendlyfire);
}
}
constrainGameType(gametype)
{
entities = getentarray();
for(i = 0; i < entities.size; i++)
{
entity = entities[i];
if(gametype == "dm")
{
if(isdefined(entity.script_gametype_dm) && entity.script_gametype_dm != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "tdm")
{
if(isdefined(entity.script_gametype_tdm) && entity.script_gametype_tdm != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "ctf")
{
if(isdefined(entity.script_gametype_ctf) && entity.script_gametype_ctf != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "hq")
{
if(isdefined(entity.script_gametype_hq) && entity.script_gametype_hq != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "sd")
{
if(isdefined(entity.script_gametype_sd) && entity.script_gametype_sd != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
else if(gametype == "koth")
{
if(isdefined(entity.script_gametype_koth) && entity.script_gametype_koth != "1")
{
//iprintln("DELETED(GameType): ", entity.classname);
entity delete();
}
}
}
}

View File

@ -0,0 +1,168 @@
#include maps\mp\_utility;
#include common_scripts\utility;
init()
{
precacheShellShock( "frag_grenade_mp" );
precacheShellShock( "damage_mp" );
precacheRumble( "artillery_rumble" );
precacheRumble( "grenade_rumble" );
precacheMenu( "dirt_effect_center" );
precacheMenu( "dirt_effect_left" );
precacheMenu( "dirt_effect_right" );
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
player thread dtp_dirt_land();
}
}
shellshockOnDamage( cause, damage )
{
if ( self maps\mp\_flashgrenades::isFlashbanged() )
return; // don't interrupt flashbang shellshock
if ( self _hasPerk( "specialty_blastshield" ) )
return;
if ( cause == "MOD_EXPLOSIVE" ||
cause == "MOD_GRENADE" ||
cause == "MOD_GRENADE_SPLASH" ||
cause == "MOD_PROJECTILE" ||
cause == "MOD_PROJECTILE_SPLASH" )
{
time = 0;
if(damage >= 90)
time = 4;
else if(damage >= 50)
time = 3;
else if(damage >= 25)
time = 2;
else if(damage > 10)
time = 2;
if ( time )
{
self shellshock("frag_grenade_mp", 0.5);
}
}
}
endOnDeath()
{
self waittill( "death" );
waittillframeend;
self notify ( "end_explode" );
}
grenade_earthQuake()
{
self thread endOnDeath();
self endon( "end_explode" );
self waittill( "explode", position );
PlayRumbleOnPosition( "grenade_rumble", position );
earthquake( 0.5, 0.75, position, 800 );
foreach ( player in level._players )
{
if ( player isUsingRemote() )
continue;
if ( distance( position, player.origin ) > 600 )
continue;
if ( player DamageConeTrace( position ) )
player thread dirtEffect( position );
}
}
dirtEffect( position )
{
self endon ( "disconnect" );
forwardVec = vectorNormalize( anglesToForward( self.angles ) );
rightVec = vectorNormalize( anglesToRight( self.angles ) );
grenadeVec = vectorNormalize( position - self.origin );
fDot = vectorDot( grenadeVec, forwardVec );
rDot = vectorDot( grenadeVec, rightVec );
printLn( fDot );
printLn( rDot );
effectMenus = [];
if ( fDot > 0 && fDot > 0.5 && self getCurrentWeapon() != "riotshield_mp" )
effectMenus[effectMenus.size] = "dirt_effect_center";
if ( abs(fDot) < 0.866 )
{
if ( rDot > 0 )
effectMenus[effectMenus.size] = "dirt_effect_right";
else
effectMenus[effectMenus.size] = "dirt_effect_left";
}
foreach ( menu in effectMenus )
self openMenu( menu );
if ( isAlive( self ) )
self waittill_notify_or_timeout( "death", 2.0 );
foreach ( menu in effectMenus )
self closeMenu( menu );
}
c4_earthQuake()
{
self thread endOnDeath();
self endon( "end_explode" );
self waittill( "explode", position );
PlayRumbleOnPosition( "grenade_rumble", position );
earthquake( 0.4, 0.75, position, 512 );
}
barrel_earthQuake()
{
PlayRumbleOnPosition( "grenade_rumble", self.origin );
earthquake( 0.4, 0.5, self.origin, 512 );
}
artillery_earthQuake()
{
PlayRumbleOnPosition( "artillery_rumble", self.origin );
earthquake( 0.7, 0.5, self.origin, 800 );
}
dtp_dirt_land()
{
self endon( "disconnect" );
for(;;)
{
self waittill( "dtp_land" );
// always play the effect from the center
effectMenus = [];
effectMenus[effectMenus.size] = "dirt_effect_center";
// open effects
foreach ( menu in effectMenus )
self openMenu( menu );
if ( isAlive( self ) )
self waittill_notify_or_timeout( "death", 2.0 );
// get rid of them
foreach ( menu in effectMenus )
self closeMenu( menu );
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,210 @@
init()
{
//tagZP<NOTE> what is this, may or may not need to extend for MTDM
level._spectateOverride["allies"] = spawnstruct();
level._spectateOverride["axis"] = spawnstruct();
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
{
level waittill( "connected", player );
player thread onJoinedTeam();
player thread onJoinedSpectators();
player thread onSpectatingClient();
}
}
onJoinedTeam()
{
self endon("disconnect");
for(;;)
{
self waittill( "joined_team" );
self setSpectatePermissions();
}
}
onJoinedSpectators()
{
self endon("disconnect");
for(;;)
{
self waittill( "joined_spectators" );
self setSpectatePermissions();
}
}
onSpectatingClient()
{
self endon("disconnect");
for( ;; )
{
self waittill( "spectating_cycle" );
// show the card for the player we're viewing. Could be undefined if the cyling failed
spectatedPlayer = self GetSpectatingPlayer();
if ( isDefined( spectatedPlayer ) )
{
self SetCardDisplaySlot( spectatedPlayer, 6 );
}
}
}
updateSpectateSettings()
{
level endon ( "game_ended" );
for ( index = 0; index < level._players.size; index++ )
level._players[index] setSpectatePermissions();
}
getOtherTeam( team )
{
if( level._multiTeamBased )
{
assertMsg( "getOtherTeam() should not be called in Multi Team Based gametypes" );
}
if ( team == "axis" )
return "allies";
else if ( team == "allies" )
return "axis";
else
return "none";
}
setSpectatePermissions()
{
team = self.sessionteam;
if ( level._gameEnded && gettime() - level._gameEndTime >= 2000 )
{
self allowSpectateTeam( "allies", false );
self allowSpectateTeam( "axis", false );
self allowSpectateTeam( "freelook", false );
if( level._multiTeamBased )
{
for( i = 0; i < level._teamNameList.size; i++ )
{
self allowSpectateTeam( level._teamNameList[i], false );
}
}
self allowSpectateTeam( "none", true );
return;
}
spectateType = maps\mp\gametypes\_tweakables::getTweakableValue( "game", "spectatetype" );
switch( spectateType )
{
case 0: // disabled
self allowSpectateTeam( "allies", false );
self allowSpectateTeam( "axis", false );
self allowSpectateTeam( "freelook", false );
self allowSpectateTeam( "none", false );
if( level._multiTeamBased )
{
for( i = 0; i < level._teamNameList.size; i++ )
{
self allowSpectateTeam( level._teamNameList[i], false );
}
}
break;
case 1: // team/player only
if ( !level._teamBased )
{
self allowSpectateTeam( "allies", true );
self allowSpectateTeam( "axis", true );
self allowSpectateTeam( "none", true );
self allowSpectateTeam( "freelook", false );
}
else if ( isDefined( team ) && (team == "allies" || team == "axis") && !level._multiTeamBased )
{
self allowSpectateTeam( team, true );
self allowSpectateTeam( getOtherTeam( team ), false );
self allowSpectateTeam( "freelook", false );
self allowSpectateTeam( "none", false );
}
else if ( isDefined( team ) && level._multiTeamBased )
{
//the multi team case will drop in here
self allowSpectateTeam( "allies", false );
self allowSpectateTeam( "axis", false );
for( i = 0; i < level._teamNameList.size; i++ )
{
if( team == level._teamNameList[i] )
{
self allowSpectateTeam( level._teamNameList[i], true );
}
else
{
self allowSpectateTeam( level._teamNameList[i], false );
}
}
self allowSpectateTeam( "freelook", false );
self allowSpectateTeam( "none", false );
}
else
{
self allowSpectateTeam( "allies", false );
self allowSpectateTeam( "axis", false );
self allowSpectateTeam( "freelook", false );
self allowSpectateTeam( "none", false );
if( level._multiTeamBased )
{
for( i = 0; i < level._teamNameList.size; i++ )
{
self allowSpectateTeam( level._teamNameList[i], false );
}
}
}
break;
case 2: // free
self allowSpectateTeam( "allies", true );
self allowSpectateTeam( "axis", true );
self allowSpectateTeam( "freelook", true );
self allowSpectateTeam( "none", true );
if( level._multiTeamBased )
{
for( i = 0; i < level._teamNameList.size; i++ )
{
self allowSpectateTeam( level._teamNameList[i], true );
}
}
break;
}
if ( isDefined( team ) && (team == "axis" || team == "allies") && !level._multiTeamBased )
{
if ( isdefined( level._spectateOverride[team].allowFreeSpectate ))
self allowSpectateTeam( "freelook", true );
if ( isdefined( level._spectateOverride[team].allowEnemySpectate ))
self allowSpectateTeam( getOtherTeam( team ), true );
}
}

View File

@ -0,0 +1,419 @@
#include maps\mp\_utility;
InitStingerUsage()
{
self.stingerStage = undefined;
self.stingerTarget = undefined;
self.stingerLockStartTime = undefined;
self.stingerLostSightlineTime = undefined;
self thread ResetStingerLockingOnDeath();
level._stingerTargets = [];
}
ResetStingerLocking()
{
if ( !IsDefined( self.stingerUseEntered ) )
return;
self.stingerUseEntered = undefined;
self notify( "stop_javelin_locking_feedback" );
self notify( "stop_javelin_locked_feedback" );
self WeaponLockFree();
InitStingerUsage();
}
ResetStingerLockingOnDeath()
{
self endon( "disconnect" );
self notify ( "ResetStingerLockingOnDeath" );
self endon ( "ResetStingerLockingOnDeath" );
for ( ;; )
{
self waittill( "death" );
self ResetStingerLocking();
}
}
StillValidStingerLock( ent )
{
assert( IsDefined( self ) );
if ( !IsDefined( ent ) )
return false;
if ( !(self WorldPointInReticle_Circle( ent.origin, 65, 85 )) )
return false;
if ( self.stingerTarget == level._ac130.planeModel && !isDefined( level._ac130player ) )
return false;
return true;
}
LoopStingerLockingFeedback()
{
self endon( "stop_javelin_locking_feedback" );
for ( ;; )
{
if ( isDefined( level._chopper ) && isDefined( level._chopper.gunner ) && isDefined( self.stingerTarget ) && self.stingerTarget == level._chopper.gunner )
level._chopper.gunner playLocalSound( "missile_locking" );
if ( isDefined( level._ac130player ) && isDefined( self.stingerTarget ) && self.stingerTarget == level._ac130.planeModel )
level._ac130player playLocalSound( "missile_locking" );
self playLocalSound( "stinger_locking" );
self PlayRumbleOnEntity( "ac130_25mm_fire" );
wait 0.6;
}
}
LoopStingerLockedFeedback()
{
self endon( "stop_javelin_locked_feedback" );
for ( ;; )
{
if ( isDefined( level._chopper ) && isDefined( level._chopper.gunner ) && isDefined( self.stingerTarget ) && self.stingerTarget == level._chopper.gunner )
level._chopper.gunner playLocalSound( "missile_locking" );
if ( isDefined( level._ac130player ) && isDefined( self.stingerTarget ) && self.stingerTarget == level._ac130.planeModel )
level._ac130player playLocalSound( "missile_locking" );
self playLocalSound( "stinger_locked" );
self PlayRumbleOnEntity( "ac130_25mm_fire" );
wait 0.25;
}
}
/#
DrawStar( point )
{
Line( point + (10,0,0), point - (10,0,0) );
Line( point + (0,10,0), point - (0,10,0) );
Line( point + (0,0,10), point - (0,0,10) );
}
#/
LockSightTest( target )
{
eyePos = self GetEye();
if ( !isDefined( target ) ) //targets can disapear during targeting.
return false;
passed = BulletTracePassed( eyePos, target.origin, false, target );
if ( passed )
return true;
front = target GetPointInBounds( 1, 0, 0 );
passed = BulletTracePassed( eyePos, front, false, target );
if ( passed )
return true;
back = target GetPointInBounds( -1, 0, 0 );
passed = BulletTracePassed( eyePos, back, false, target );
if ( passed )
return true;
return false;
}
StingerDebugDraw( target )
{
/#
if ( GetDVar( "missileDebugDraw" ) != "1" )
return;
if ( !IsDefined( target ) )
return;
org = target.origin;
DrawStar( org );
org = target GetPointInBounds( 1, 0, 0 );
DrawStar( org );
org = target GetPointInBounds( -1, 0, 0 );
DrawStar( org );
#/
}
SoftSightTest()
{
LOST_SIGHT_LIMIT = 500;
if ( self LockSightTest( self.stingerTarget ) )
{
self.stingerLostSightlineTime = 0;
return true;
}
if ( self.stingerLostSightlineTime == 0 )
self.stingerLostSightlineTime = getTime();
timePassed = GetTime() - self.stingerLostSightlineTime;
//PrintLn( "Losing sight of target [", timePassed, "]..." );
if ( timePassed >= LOST_SIGHT_LIMIT )
{
//PrintLn( "Lost sight of target." );
ResetStingerLocking();
return false;
}
return true;
}
GetTargetList()
{
targets = [];
if ( level._teamBased )
{
if ( IsDefined( level._chopper ) && ( level._chopper.team != self.team || level._chopper.owner == self ) )
targets[targets.size] = level._chopper;
if ( IsDefined( level._raven ) && ( level._raven.team != self.team || level._raven.owner == self ) )
targets[targets.size] = level._raven;
if ( isDefined( level._ac130player ) && level._ac130player.team != self.team )
targets[targets.size] = level._ac130.planemodel;
if ( isDefined( level._harriers) )
{
foreach( harrier in level._harriers )
{
if ( isDefined( harrier ) && ( harrier.team != self.team || ( isDefined( harrier.owner ) && harrier.owner == self ) ) )
targets[targets.size] = harrier;
}
}
foreach( target_player in level._players )
{
if (( target_player.team != self.team ) && (target_player _hasPerk("specialty_juggersuit")))
{
targets[targets.size] = target_player;
}
}
if( level._multiTeamBased )
{
//for all teams
for( i = 0; i < level._teamNameList.size; i++ )
{
//that are not our team
if( self.team != level._teamNameList[i] )
{
//does that team have any uav's
if( level._UAVModels[level._teamNameList[i]].size )
{
//add each uav to the target list
foreach ( UAV in level._UAVModels[level._teamNameList[i]] )
{
targets[targets.size] = UAV;
}
}
}
}
}
else if ( level._UAVModels[level._otherTeam[self.team]].size )
{
foreach ( UAV in level._UAVModels[level._otherTeam[self.team]] )
targets[targets.size] = UAV;
}
if ( isDefined( level._littleBird ) )
{
foreach ( bird in level._littleBird )
{
if ( !isDefined( bird ) )
continue;
if ( self.team != bird.owner.team || self == bird.owner )
targets[targets.size] = bird;
}
}
}
else
{
if ( IsDefined( level._chopper ) && ( level._chopper.owner != self ) ) ///check for teams
targets[targets.size] = level._chopper;
if ( isDefined( level._ac130player ) )
targets[targets.size] = level._ac130.planemodel;
if ( isDefined( level._harriers) )
{
foreach( harrier in level._harriers )
{
if ( isDefined( harrier ) )
targets[targets.size] = harrier;
}
}
foreach( target_player in level._players )
{
if (( target_player != self ) && (target_player _hasPerk("specialty_juggersuit")))
{
targets[targets.size] = target_player;
}
}
if ( level._UAVModels.size )
{
foreach ( ownerGuid, UAV in level._UAVModels )
{
if ( isDefined( UAV.owner ) && UAV.owner == self )
continue;
targets[targets.size] = UAV;
}
}
}
return targets;
}
StingerUsageLoop()
{
self endon("death");
self endon("disconnect");
LOCK_LENGTH = 1000;
InitStingerUsage();
for( ;; )
{
wait 0.05;
weapon = self getCurrentWeapon();
if ( weapon != "stinger_mp" && weapon != "at4_mp" )
{
ResetStingerLocking();
continue;
}
if ( self PlayerADS() < 0.95 )
{
ResetStingerLocking();
continue;
}
self.stingerUseEntered = true;
if ( !IsDefined( self.stingerStage ) )
self.stingerStage = 0;
StingerDebugDraw( self.stingerTarget );
if ( self.stingerStage == 0 ) // searching for target
{
targets = GetTargetList();
if ( targets.size == 0 )
continue;
targetsInReticle = [];
foreach ( target in targets )
{
if ( !isDefined( target ) )
continue;
insideReticle = self WorldPointInReticle_Circle( target.origin, 65, 75 );
if ( insideReticle )
targetsInReticle[targetsInReticle.size] = target;
}
if ( targetsInReticle.size == 0 )
continue;
sortedTargets = SortByDistance( targetsInReticle, self.origin );
if ( !( self LockSightTest( sortedTargets[0] ) ) )
continue;
//PrintLn( "Found a target to lock to..." );
thread LoopStingerLockingFeedback();
self.stingerTarget = sortedTargets[0];
self.stingerLockStartTime = GetTime();
self.stingerStage = 1;
self.stingerLostSightlineTime = 0;
}
if ( self.stingerStage == 1 ) // locking on to a target
{
if ( !(self StillValidStingerLock( self.stingerTarget )) )
{
//PrintLn( "Failed to get lock." );
ResetStingerLocking();
continue;
}
passed = SoftSightTest();
if ( !passed )
continue;
timePassed = getTime() - self.stingerLockStartTime;
//PrintLn( "Locking [", timePassed, "]..." );
if( self _hasPerk( "specialty_fasterlockon" ))
{
if( timePassed < ( LOCK_LENGTH * 0.5 ))
{
continue;
}
}
else
{
if ( timePassed < LOCK_LENGTH )
continue;
}
self notify( "stop_javelin_locking_feedback" );
thread LoopStingerLockedFeedback();
//PrintLn( "Locked!");
if ( self.stingerTarget.model == "vehicle_av8b_harrier_jet_mp" || self.stingerTarget.model == "vehicle_little_bird_armed" )
{
self WeaponLockFinalize( self.stingerTarget );
}
else if ( IsPlayer( self.stingerTarget ) )
{
self WeaponLockFinalize( self.stingerTarget, (0,0,32) );
}
else
{
self WeaponLockFinalize( self.stingerTarget, (100,0,-32) );
}
self.stingerStage = 2;
}
if ( self.stingerStage == 2 ) // target locked
{
passed = SoftSightTest();
if ( !passed )
continue;
if ( !(self StillValidStingerLock( self.stingerTarget )) )
{
//PrintLn( "Gave up lock." );
ResetStingerLocking();
continue;
}
}
}
}

2121
maps/mp/gametypes/_teams.gsc Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,364 @@
#include maps\mp\_utility;
getTweakableDVarValue( category, name )
{
switch( category )
{
case "rule":
dVar = level._rules[name].dVar;
break;
case "game":
dVar = level._gameTweaks[name].dVar;
break;
case "team":
dVar = level._teamTweaks[name].dVar;
break;
case "player":
dVar = level._playerTweaks[name].dVar;
break;
case "class":
dVar = level._classTweaks[name].dVar;
break;
case "weapon":
dVar = level._weaponTweaks[name].dVar;
break;
case "hardpoint":
dVar = level._hardpointTweaks[name].dVar;
break;
case "hud":
dVar = level._hudTweaks[name].dVar;
break;
default:
dVar = undefined;
break;
}
assert( isDefined( dVar ) );
value = getDvarInt( dVar );
return value;
}
getTweakableDVar( category, name )
{
switch( category )
{
case "rule":
value = level._rules[name].dVar;
break;
case "game":
value = level._gameTweaks[name].dVar;
break;
case "team":
value = level._teamTweaks[name].dVar;
break;
case "player":
value = level._playerTweaks[name].dVar;
break;
case "class":
value = level._classTweaks[name].dVar;
break;
case "weapon":
value = level._weaponTweaks[name].dVar;
break;
case "hardpoint":
value = level._hardpointTweaks[name].dVar;
break;
case "hud":
value = level._hudTweaks[name].dVar;
break;
default:
value = undefined;
break;
}
assert( isDefined( value ) );
return value;
}
getTweakableValue( category, name )
{
switch( category )
{
case "rule":
value = level._rules[name].value;
break;
case "game":
value = level._gameTweaks[name].value;
break;
case "team":
value = level._teamTweaks[name].value;
break;
case "player":
value = level._playerTweaks[name].value;
break;
case "class":
value = level._classTweaks[name].value;
break;
case "weapon":
value = level._weaponTweaks[name].value;
break;
case "hardpoint":
value = level._hardpointTweaks[name].value;
break;
case "hud":
value = level._hudTweaks[name].value;
break;
default:
value = undefined;
break;
}
/#
overrideDvar = "scr_" + level._gameType + "_" + category + "_" + name;
return getDvarInt( overrideDvar, value );
#/
assert( isDefined( value ) );
return value;
}
getTweakableLastValue( category, name )
{
switch( category )
{
case "rule":
value = level._rules[name].lastValue;
break;
case "game":
value = level._gameTweaks[name].lastValue;
break;
case "team":
value = level._teamTweaks[name].lastValue;
break;
case "player":
value = level._playerTweaks[name].lastValue;
break;
case "class":
value = level._classTweaks[name].lastValue;
break;
case "weapon":
value = level._weaponTweaks[name].lastValue;
break;
case "hardpoint":
value = level._hardpointTweaks[name].lastValue;
break;
case "hud":
value = level._hudTweaks[name].lastValue;
break;
default:
value = undefined;
break;
}
assert( isDefined( value ) );
return value;
}
setTweakableValue( category, name, value )
{
switch( category )
{
case "rule":
dVar = level._rules[name].dVar;
break;
case "game":
dVar = level._gameTweaks[name].dVar;
break;
case "team":
dVar = level._teamTweaks[name].dVar;
break;
case "player":
dVar = level._playerTweaks[name].dVar;
break;
case "class":
dVar = level._classTweaks[name].dVar;
break;
case "weapon":
dVar = level._weaponTweaks[name].dVar;
break;
case "hardpoint":
dVar = level._hardpointTweaks[name].dVar;
break;
case "hud":
dVar = level._hudTweaks[name].dVar;
break;
default:
dVar = undefined;
break;
}
setDvar( dVar, value );
}
setTweakableLastValue( category, name, value )
{
switch( category )
{
case "rule":
level._rules[name].lastValue = value;
break;
case "game":
level._gameTweaks[name].lastValue = value;
break;
case "team":
level._teamTweaks[name].lastValue = value;
break;
case "player":
level._playerTweaks[name].lastValue = value;
break;
case "class":
level._classTweaks[name].lastValue = value;
break;
case "weapon":
level._weaponTweaks[name].lastValue = value;
break;
case "hardpoint":
level._hardpointTweaks[name].lastValue = value;
break;
case "hud":
level._hudTweaks[name].lastValue = value;
break;
default:
break;
}
}
registerTweakable( category, name, dvar, value )
{
if ( isString( value ) )
{
value = getDvar( dvar, value );
}
else
{
value = getDvarInt( dvar, value );
}
switch( category )
{
case "rule":
if ( !isDefined( level._rules[name] ) )
level._rules[name] = spawnStruct();
level._rules[name].value = value;
level._rules[name].lastValue = value;
level._rules[name].dVar = dvar;
break;
case "game":
if ( !isDefined( level._gameTweaks[name] ) )
level._gameTweaks[name] = spawnStruct();
level._gameTweaks[name].value = value;
level._gameTweaks[name].lastValue = value;
level._gameTweaks[name].dVar = dvar;
break;
case "team":
if ( !isDefined( level._teamTweaks[name] ) )
level._teamTweaks[name] = spawnStruct();
level._teamTweaks[name].value = value;
level._teamTweaks[name].lastValue = value;
level._teamTweaks[name].dVar = dvar;
break;
case "player":
if ( !isDefined( level._playerTweaks[name] ) )
level._playerTweaks[name] = spawnStruct();
level._playerTweaks[name].value = value;
level._playerTweaks[name].lastValue = value;
level._playerTweaks[name].dVar = dvar;
break;
case "class":
if ( !isDefined( level._classTweaks[name] ) )
level._classTweaks[name] = spawnStruct();
level._classTweaks[name].value = value;
level._classTweaks[name].lastValue = value;
level._classTweaks[name].dVar = dvar;
break;
case "weapon":
if ( !isDefined( level._weaponTweaks[name] ) )
level._weaponTweaks[name] = spawnStruct();
level._weaponTweaks[name].value = value;
level._weaponTweaks[name].lastValue = value;
level._weaponTweaks[name].dVar = dvar;
break;
case "hardpoint":
if ( !isDefined( level._hardpointTweaks[name] ) )
level._hardpointTweaks[name] = spawnStruct();
level._hardpointTweaks[name].value = value;
level._hardpointTweaks[name].lastValue = value;
level._hardpointTweaks[name].dVar = dvar;
break;
case "hud":
if ( !isDefined( level._hudTweaks[name] ) )
level._hudTweaks[name] = spawnStruct();
level._hudTweaks[name].value = value;
level._hudTweaks[name].lastValue = value;
level._hudTweaks[name].dVar = dvar;
break;
}
}
init()
{
level._clientTweakables = [];
level._tweakablesInitialized = true;
level._rules = [];
level._gameTweaks = [];
level._teamTweaks = [];
level._playerTweaks = [];
level._classTweaks = [];
level._weaponTweaks = [];
level._hardpointTweaks = [];
level._hudTweaks = [];
// commented out tweaks have not yet been implemented
if ( level._console )
{
registerTweakable( "game", "graceperiod", "scr_game_graceperiod", 15 ); //*
}
else
{
registerTweakable( "game", "playerwaittime", "scr_game_playerwaittime", 15 ); //*
registerTweakable( "game", "matchstarttime", "scr_game_matchstarttime", 5 ); //*
}
registerTweakable( "game", "onlyheadshots", "scr_game_onlyheadshots", 0 ); //*
registerTweakable( "game", "allowkillcam", "scr_game_allowkillcam", 1 ); //*
registerTweakable( "game", "spectatetype", "scr_game_spectatetype", 2 ); //*
registerTweakable( "game", "deathpointloss", "scr_game_deathpointloss", 0 ); //*
registerTweakable( "game", "suicidepointloss", "scr_game_suicidepointloss", 0 ); //*
registerTweakable( "team", "teamkillpointloss", "scr_team_teamkillpointloss", 0 ); //*
// registerTweakable( "team", "respawntime", "scr_team_respawntime", 0 );
registerTweakable( "team", "fftype", "scr_team_fftype", 0 );
registerTweakable( "team", "teamkillspawndelay", "scr_team_teamkillspawndelay", 0 );
// registerTweakable( "player", "respawndelay", "scr_player_respawndelay", 0 ); //*
registerTweakable( "player", "maxhealth", "scr_player_maxhealth", 125 ); //*
registerTweakable( "player", "healthregentime", "scr_player_healthregentime", 5 ); //*
registerTweakable( "player", "healthregenratepercent", "scr_player_healthregenratepercent", 10 ); //*
registerTweakable( "player", "forcerespawn", "scr_player_forcerespawn", 1 ); //*
registerTweakable( "weapon", "allowfrag", "scr_weapon_allowfrags", 1 );
registerTweakable( "weapon", "allowsmoke", "scr_weapon_allowsmoke", 1 );
registerTweakable( "weapon", "allowflash", "scr_weapon_allowflash", 1 );
registerTweakable( "weapon", "allowc4", "scr_weapon_allowc4", 1 );
registerTweakable( "weapon", "allowclaymores", "scr_weapon_allowclaymores", 1 );
registerTweakable( "weapon", "allowrpgs", "scr_weapon_allowrpgs", 1 );
registerTweakable( "weapon", "allowmines", "scr_weapon_allowmines", 1 );
registerTweakable( "hardpoint", "allowartillery", "scr_hardpoint_allowartillery", 1 );
registerTweakable( "hardpoint", "allowuav", "scr_hardpoint_allowuav", 1 );
registerTweakable( "hardpoint", "allowsupply", "scr_hardpoint_allowsupply", 1 );
registerTweakable( "hardpoint", "allowhelicopter", "scr_hardpoint_allowhelicopter", 1 );
registerTweakable( "hud", "showobjicons", "ui_hud_showobjicons", 1 ); //*
makeDVarServerInfo( "ui_hud_showobjicons", 1 );
}

File diff suppressed because it is too large Load Diff

1885
maps/mp/gametypes/convoy.gsc Normal file

File diff suppressed because it is too large Load Diff

100
maps/mp/gametypes/dm.gsc Normal file
View File

@ -0,0 +1,100 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
Deathmatch
Objective: Score points by eliminating other players
Map ends: When one player reaches the score limit, or time limit is reached
Respawning: No wait / Away from other players
Level requirements
------------------
Spawnpoints:
classname mp_dm_spawn
All players spawn from these. The spawnpoint chosen is dependent on the current locations of enemies at the time of spawn.
Players generally spawn away from enemies.
Spectator Spawnpoints:
classname mp_global_intermission
Spectators spawn from these and intermission is viewed from these positions.
Atleast one is required, any more and they are randomly chosen between.
*/
/*QUAKED mp_dm_spawn (1.0 0.5 0.0) (-16 -16 0) (16 16 72)
Players spawn away from enemies at one of these positions.*/
main()
{
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerTimeLimitDvar( level._gameType, 10, 0, 1440 );
registerScoreLimitDvar( level._gameType, 1000, 0, 5000 );
registerWinLimitDvar( level._gameType, 1, 0, 5000 );
registerRoundLimitDvar( level._gameType, 1, 0, 10 );
registerNumLivesDvar( level._gameType, 0, 0, 10 );
registerHalfTimeDvar( level._gameType, 0, 0, 1 );
level._onStartGameType = ::onStartGameType;
level._getSpawnPoint = ::getSpawnPoint;
game["dialog"]["gametype"] = "freeforall";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
else if (getDvarInt( "scr_" + level._gameType + "_promode" ) )
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
}
onStartGameType()
{
setClientNameMode("auto_change");
setObjectiveText( "allies", &"OBJECTIVES_DM" );
setObjectiveText( "axis", &"OBJECTIVES_DM" );
if ( level._splitscreen )
{
setObjectiveScoreText( "allies", &"OBJECTIVES_DM" );
setObjectiveScoreText( "axis", &"OBJECTIVES_DM" );
}
else
{
setObjectiveScoreText( "allies", &"OBJECTIVES_DM_SCORE" );
setObjectiveScoreText( "axis", &"OBJECTIVES_DM_SCORE" );
}
setObjectiveHintText( "allies", &"OBJECTIVES_DM_HINT" );
setObjectiveHintText( "axis", &"OBJECTIVES_DM_HINT" );
level._spawnMins = ( 0, 0, 0 );
level._spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_dm_spawn" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_dm_spawn" );
level._mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level._spawnMins, level._spawnMaxs );
setMapCenter( level._mapCenter );
allowed[0] = "dm";
maps\mp\gametypes\_gameobjects::main(allowed);
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 10 );
maps\mp\gametypes\_rank::registerScoreInfo( "suicide", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "teamkill", 0 );
level._QuickMessageToAll = true;
}
getSpawnPoint()
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( self.pers["team"] );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_DM( spawnPoints );
return spawnPoint;
}

File diff suppressed because it is too large Load Diff

1083
maps/mp/gametypes/hvt.gsc Normal file

File diff suppressed because it is too large Load Diff

171
maps/mp/gametypes/war.gsc Normal file
View File

@ -0,0 +1,171 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
War
Objective: Score points for your team by eliminating players on the opposing team
Map ends: When one team reaches the score limit, or time limit is reached
Respawning: No wait / Near teammates
Level requirementss
------------------
Spawnpoints:
classname mp_tdm_spawn
All players spawn from these. The spawnpoint chosen is dependent on the current locations of teammates and enemies
at the time of spawn. Players generally spawn behind their teammates relative to the direction of enemies.
Spectator Spawnpoints:
classname mp_global_intermission
Spectators spawn from these and intermission is viewed from these positions.
Atleast one is required, any more and they are randomly chosen between.
*/
/*QUAKED mp_tdm_spawn (0.0 0.0 1.0) (-16 -16 0) (16 16 72)
Players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_tdm_spawn_axis_start (0.5 0.0 1.0) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
/*QUAKED mp_tdm_spawn_allies_start (0.0 0.5 1.0) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
main()
{
if(getdvar("mapname") == "mp_background")
return;
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerRoundSwitchDvar( level._gameType, 0, 0, 9 );
registerTimeLimitDvar( level._gameType, 10, 0, 1440 );
registerScoreLimitDvar( level._gameType, 500, 0, 5000 );
registerRoundLimitDvar( level._gameType, 1, 0, 10 );
registerWinLimitDvar( level._gameType, 1, 0, 10 );
registerRoundSwitchDvar( level._gameType, 3, 0, 30 );
registerNumLivesDvar( level._gameType, 0, 0, 10 );
registerHalfTimeDvar( level._gameType, 0, 0, 1 );
level._teamBased = true;
level._onStartGameType = ::onStartGameType;
level._getSpawnPoint = ::getSpawnPoint;
level._onNormalDeath = ::onNormalDeath;
// level.onTimeLimit = ::onTimeLimit; // overtime not fully supported yet
game["dialog"]["gametype"] = "tm_death";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
else if (getDvarInt( "scr_" + level._gameType + "_promode" ) )
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
game["strings"]["overtime_hint"] = &"MP_FIRST_BLOOD";
}
onStartGameType()
{
setClientNameMode("auto_change");
if ( !isdefined( game["switchedsides"] ) )
game["switchedsides"] = false;
if ( game["switchedsides"] )
{
oldAttackers = game["attackers"];
oldDefenders = game["defenders"];
game["attackers"] = oldDefenders;
game["defenders"] = oldAttackers;
}
setObjectiveText( "allies", &"OBJECTIVES_WAR" );
setObjectiveText( "axis", &"OBJECTIVES_WAR" );
if ( level._splitscreen )
{
setObjectiveScoreText( "allies", &"OBJECTIVES_WAR" );
setObjectiveScoreText( "axis", &"OBJECTIVES_WAR" );
}
else
{
setObjectiveScoreText( "allies", &"OBJECTIVES_WAR_SCORE" );
setObjectiveScoreText( "axis", &"OBJECTIVES_WAR_SCORE" );
}
setObjectiveHintText( "allies", &"OBJECTIVES_WAR_HINT" );
setObjectiveHintText( "axis", &"OBJECTIVES_WAR_HINT" );
level._spawnMins = ( 0, 0, 0 );
level._spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_allies_start" );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_axis_start" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_tdm_spawn" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_tdm_spawn" );
level._mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level._spawnMins, level._spawnMaxs );
setMapCenter( level._mapCenter );
allowed[0] = level._gameType;
allowed[1] = "airdrop_pallet";
maps\mp\gametypes\_gameobjects::main(allowed);
}
getSpawnPoint()
{
spawnteam = self.pers["team"];
if ( game["switchedsides"] )
spawnteam = getOtherTeam( spawnteam );
if ( level._inGracePeriod )
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_tdm_spawn_" + spawnteam + "_start" );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
}
else
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
}
return spawnPoint;
}
onNormalDeath( victim, attacker, lifeId )
{
score = maps\mp\gametypes\_rank::getScoreInfoValue( "kill" );
assert( isDefined( score ) );
attacker maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( attacker.pers["team"], score );
if ( game["state"] == "postgame" && game["teamScores"][attacker.team] > game["teamScores"][level._otherTeam[attacker.team]] )
attacker.finalKill = true;
}
onTimeLimit()
{
if ( game["status"] == "overtime" )
{
winner = "forfeit";
}
else if ( game["teamScores"]["allies"] == game["teamScores"]["axis"] )
{
winner = "overtime";
}
else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
winner = "axis";
}
else
{
winner = "allies";
}
thread maps\mp\gametypes\_gamelogic::endGame( winner, game["strings"]["time_limit_reached"] );
}