Merge branch 'develop' of github.com:iw4x/iw4x-rawfiles into feature/teams

This commit is contained in:
Louvenarde committed 2023-12-15 20:15:43 +01:00
commit b67f9be562
27 files changed
+9476 -208

No files matched your search

File diff suppressed because it is too large. Load diff
+156 -69
View File
@@ -60,7 +60,6 @@ init()
level thread onPlayerConnecting();
}
getClassChoice( response )
{
assert( isDefined( level.classMap[response] ) );
@@ -77,7 +76,6 @@ getWeaponChoice( response )
return 0;
}
logClassChoice( class, primaryWeapon, specialType, perks )
{
if ( class == self.lastClass )
@@ -90,7 +88,6 @@ logClassChoice( class, primaryWeapon, specialType, perks )
self.lastClass = class;
}
cac_getWeapon( classIndex, weaponIndex )
{
return self getPlayerData( "customClasses", classIndex, "weaponSetups", weaponIndex, "weapon" );
@@ -131,8 +128,6 @@ cac_getOffhand( classIndex )
return self getPlayerData( "customClasses", classIndex, "specialGrenade" );
}
table_getWeapon( tableName, classIndex, weaponIndex )
{
if ( weaponIndex == 0 )
@@ -303,6 +298,8 @@ giveLoadout( team, class, allowCopycat )
{
self takeAllWeapons();
self.changingWeapon = undefined;
primaryIndex = 0;
// initialize specialty array
@@ -312,7 +309,15 @@ giveLoadout( team, class, allowCopycat )
allowCopycat = true;
primaryWeapon = undefined;
clearAmmo = false;
// set in game mode custom class
loadoutKillstreak1 = undefined;
loadoutKillstreak2 = undefined;
loadoutKillstreak3 = undefined;
clonedLoadout = [];
if ( isDefined( self.pers["copyCatLoadout"] ) && self.pers["copyCatLoadout"]["inUse"] && allowCopycat )
{
self maps\mp\gametypes\_class::setClass( "copycat" );
@@ -356,6 +361,64 @@ giveLoadout( team, class, allowCopycat )
loadoutOffhand = cac_getOffhand( class_num );
loadoutDeathStreak = cac_getDeathstreak( class_num );
}
else if ( class == "gamemode" )
{
gamemodeLoadout = self.pers["gamemodeLoadout"];
loadoutPrimary = gamemodeLoadout["loadoutPrimary"];
loadoutPrimaryAttachment = gamemodeLoadout["loadoutPrimaryAttachment"];
loadoutPrimaryAttachment2 = gamemodeLoadout["loadoutPrimaryAttachment2"] ;
loadoutPrimaryCamo = gamemodeLoadout["loadoutPrimaryCamo"];
loadoutSecondary = gamemodeLoadout["loadoutSecondary"];
loadoutSecondaryAttachment = gamemodeLoadout["loadoutSecondaryAttachment"];
loadoutSecondaryAttachment2 = gamemodeLoadout["loadoutSecondaryAttachment2"];
loadoutSecondaryCamo = gamemodeLoadout["loadoutSecondaryCamo"];
// replace the placeholder throwing knife with the valid secondary if there is one
if ( loadoutPrimary == "throwingknife" && loadoutSecondary != "none" )
{
loadoutPrimary = loadoutSecondary;
loadoutPrimaryAttachment = loadoutSecondaryAttachment;
loadoutPrimaryAttachment2 = loadoutSecondaryAttachment2;
loadoutPrimaryCamo = loadoutSecondaryCamo;
loadoutSecondary = "none";
loadoutSecondaryAttachment = "none";
loadoutSecondaryAttachment2 = "none";
loadoutSecondaryCamo = "none";
}
// otherwise replace with normal default for invalid class
else if ( loadoutPrimary == "throwingknife" && loadoutSecondary == "none" )
{
clearAmmo = true;
loadoutPrimary = "usp";
loadoutPrimaryAttachment = "tactical";
}
loadoutEquipment = gamemodeLoadout["loadoutEquipment"];
loadoutOffhand = gamemodeLoadout["loadoutOffhand"];
// hack, until game mode default class data can be reset
if ( loadoutOffhand == "specialty_null" )
loadoutOffhand = "none";
loadoutPerk1 = gamemodeLoadout["loadoutPerk1"];
loadoutPerk2 = gamemodeLoadout["loadoutPerk2"];
loadoutPerk3 = gamemodeLoadout["loadoutPerk3"];
if ( level.killstreakRewards )
{
loadoutKillstreak1 = gamemodeLoadout["loadoutKillstreak1"];
loadoutKillstreak2 = gamemodeLoadout["loadoutKillstreak2"];
loadoutKillstreak3 = gamemodeLoadout["loadoutKillstreak3"];
}
else
{
loadoutKillstreak1 = "none";
loadoutKillstreak2 = "none";
loadoutKillstreak3 = "none";
}
loadoutDeathStreak = gamemodeLoadout["loadoutDeathstreak"];
}
else
{
class_num = getClassIndex( class );
@@ -377,8 +440,10 @@ giveLoadout( team, class, allowCopycat )
loadoutOffhand = table_getOffhand( level.classTableName, class_num );
loadoutDeathstreak = table_getDeathstreak( level.classTableName, class_num );
}
isGameModeClass = ( class == "gamemode" );
if ( !(isDefined( self.pers["copyCatLoadout"] ) && self.pers["copyCatLoadout"]["inUse"] && allowCopycat) )
if ( !isGameModeClass && !(isDefined( self.pers["copyCatLoadout"] ) && self.pers["copyCatLoadout"]["inUse"] && allowCopycat) )
{
isCustomClass = isSubstr( class, "custom" );
@@ -435,8 +500,33 @@ giveLoadout( team, class, allowCopycat )
loadoutSecondary = table_getWeapon( level.classTableName, 10, 1 );
//loadoutSecondaryCamo = "none";
self.loadoutPrimaryCamo = int(tableLookup( "mp/camoTable.csv", 1, loadoutPrimaryCamo, 0 ));
self.loadoutPrimary = loadoutPrimary;
self.loadoutSecondary = loadoutSecondary;
self.loadoutSecondaryCamo = int(tableLookup( "mp/camoTable.csv", 1, loadoutSecondaryCamo, 0 ));
if ( loadoutSecondary == "none" )
secondaryName = "none";
else
{
secondaryName = buildWeaponName( loadoutSecondary, loadoutSecondaryAttachment, loadoutSecondaryAttachment2 );
self _giveWeapon( secondaryName, int(tableLookup( "mp/camoTable.csv", 1, loadoutSecondaryCamo, 0 ) ) );
}
self SetOffhandPrimaryClass( "other" );
// Action Slots
//self _SetActionSlot( 1, "" );
self _SetActionSlot( 1, "nightvision" );
self _SetActionSlot( 3, "altMode" );
self _SetActionSlot( 4, "" );
// Perks
self _clearPerks();
self _detachAll();
if ( level.killstreakRewards )
{
if ( getDvarInt( "scr_classic" ) == 1 )
@@ -459,56 +549,39 @@ giveLoadout( team, class, allowCopycat )
loadoutKillstreak3 = "none";
}
secondaryName = buildWeaponName( loadoutSecondary, loadoutSecondaryAttachment, loadoutSecondaryAttachment2 );
self _giveWeapon( secondaryName, int(tableLookup( "mp/camoTable.csv", 1, loadoutSecondaryCamo, 0 ) ) );
self.loadoutPrimaryCamo = int(tableLookup( "mp/camoTable.csv", 1, loadoutPrimaryCamo, 0 ));
self.loadoutPrimary = loadoutPrimary;
self.loadoutSecondary = loadoutSecondary;
self.loadoutSecondaryCamo = int(tableLookup( "mp/camoTable.csv", 1, loadoutSecondaryCamo, 0 ));
self SetOffhandPrimaryClass( "other" );
// Action Slots
//self _SetActionSlot( 1, "" );
self _SetActionSlot( 1, "nightvision" );
self _SetActionSlot( 3, "altMode" );
self _SetActionSlot( 4, "" );
// Perks
self _clearPerks();
self _detachAll();
// these special case giving pistol death have to come before
// perk loadout to ensure player perk icons arent overwritten
if ( level.dieHardMode )
self maps\mp\perks\_perks::givePerk( "specialty_pistoldeath" );
// only give the deathstreak for the initial spawn for this life.
if ( loadoutDeathStreak != "specialty_null" && getTime() == self.spawnTime )
{
deathVal = int( tableLookup( "mp/perkTable.csv", 1, loadoutDeathStreak, 6 ) );
if ( self getPerkUpgrade( loadoutPerk1 ) == "specialty_rollover" || self getPerkUpgrade( loadoutPerk2 ) == "specialty_rollover" || self getPerkUpgrade( loadoutPerk3 ) == "specialty_rollover" )
deathVal -= 1;
if ( self.pers["cur_death_streak"] == deathVal )
{
self thread maps\mp\perks\_perks::givePerk( loadoutDeathStreak );
self thread maps\mp\gametypes\_hud_message::splashNotify( loadoutDeathStreak );
}
else if ( self.pers["cur_death_streak"] > deathVal )
{
self thread maps\mp\perks\_perks::givePerk( loadoutDeathStreak );
}
}
self loadoutAllPerks( loadoutEquipment, loadoutPerk1, loadoutPerk2, loadoutPerk3 );
self setKillstreaks( loadoutKillstreak1, loadoutKillstreak2, loadoutKillstreak3 );
if ( self hasPerk( "specialty_extraammo", true ) && getWeaponClass( secondaryName ) != "weapon_projectile" )
self giveMaxAmmo( secondaryName );
self giveMaxAmmo( secondaryName );
// only give the deathstreak for the initial spawn for this life.
if( self.pers["cur_death_streak"] > 0 )
{
if ( loadoutDeathStreak != "specialty_null" )
{
deathVal = int( tableLookup( "mp/perkTable.csv", 1, loadoutDeathStreak, 6 ) );
if ( self getPerkUpgrade( loadoutPerk1 ) == "specialty_rollover" || self getPerkUpgrade( loadoutPerk2 ) == "specialty_rollover" || self getPerkUpgrade( loadoutPerk3 ) == "specialty_rollover" )
deathVal -= 1;
if ( self.pers["cur_death_streak"] == deathVal )
{
self thread maps\mp\perks\_perks::givePerk( loadoutDeathStreak );
self thread maps\mp\gametypes\_hud_message::splashNotify( loadoutDeathStreak );
}
else if ( self.pers["cur_death_streak"] > deathVal )
{
self thread maps\mp\perks\_perks::givePerk( loadoutDeathStreak );
}
}
}
// Primary Weapon
primaryName = buildWeaponName( loadoutPrimary, loadoutPrimaryAttachment, loadoutPrimaryAttachment2 );
@@ -530,24 +603,42 @@ giveLoadout( team, class, allowCopycat )
// Secondary Offhand
offhandSecondaryWeapon = loadoutOffhand + "_mp";
if ( loadoutOffhand == "flash_grenade" )
self SetOffhandSecondaryClass( "flash" );
else
self SetOffhandSecondaryClass( "smoke" );
self giveWeapon( offhandSecondaryWeapon );
if( loadOutOffhand == "smoke_grenade" )
self setWeaponAmmoClip( offhandSecondaryWeapon, 1 );
else if( loadOutOffhand == "flash_grenade" )
self setWeaponAmmoClip( offhandSecondaryWeapon, 2 );
else if( loadOutOffhand == "concussion_grenade" )
self setWeaponAmmoClip( offhandSecondaryWeapon, 2 );
else
self setWeaponAmmoClip( offhandSecondaryWeapon, 1 );
if ( loadoutOffhand == "none" )
self SetOffhandSecondaryClass( "none" );
else if ( loadoutOffhand == "flash_grenade" )
self SetOffhandSecondaryClass( "flash" );
else if ( loadoutOffhand == "smoke_grenade" || loadoutOffhand == "concussion_grenade" )
self SetOffhandSecondaryClass( "smoke" );
else
self SetOffhandSecondaryClass( "flash" );
switch( loadoutOffhand )
{
case "none":
break;
default:
self giveWeapon( offhandSecondaryWeapon );
if ( loadOutOffhand == "flash_grenade" )
self setWeaponAmmoClip( offhandSecondaryWeapon, 2 );
else if( loadOutOffhand == "concussion_grenade" )
self setWeaponAmmoClip( offhandSecondaryWeapon, 2 );
else
self setWeaponAmmoClip( offhandSecondaryWeapon, 1 );
break;
}
primaryWeapon = primaryName;
self.primaryWeapon = primaryWeapon;
self.secondaryWeapon = secondaryName;
// clear ammo for created default classes using placeholder gun when primary and secondary was set to none
if ( clearAmmo )
{
self SetWeaponAmmoClip( self.primaryWeapon, 0 );
self SetWeaponAmmoStock( self.primaryWeapon, 0 );
}
self maps\mp\gametypes\_teams::playerModelForWeapon( self.pers["primaryWeapon"], getBaseWeaponName( secondaryName ) );
@@ -703,7 +794,6 @@ trackRiotShield()
}
}
tryAttach( placement ) // deprecated; hopefully we won't need to bring this defensive function back
{
if ( !isDefined( placement ) || placement != "back" )
@@ -747,8 +837,6 @@ tryDetach( placement ) // deprecated; hopefully we won't need to bring this defe
return;
}
buildWeaponName( baseName, attachment1, attachment2 )
{
if ( !isDefined( level.letterToNumber ) )
@@ -814,7 +902,6 @@ buildWeaponName( baseName, attachment1, attachment2 )
return ( weaponName + "_mp" );
}
makeLettersToNumbers()
{
array = [];
@@ -934,7 +1021,6 @@ setKillstreaks( streak1, streak2, streak3 )
self.killstreaks = newKillstreaks;
}
replenishLoadout() // used by ammo hardpoint.
{
team = self.pers["team"];
@@ -959,7 +1045,6 @@ replenishLoadout() // used by ammo hardpoint.
self SetWeaponAmmoClip( level.classGrenades[class]["secondary"]["type"], level.classGrenades[class]["secondary"]["count"] );
}
onPlayerConnecting()
{
for(;;)
@@ -970,14 +1055,18 @@ onPlayerConnecting()
{
player.pers["class"] = "";
}
if ( !isDefined( player.pers["lastClass"] ) )
{
player.pers["lastClass"] = "";
}
player.class = player.pers["class"];
player.lastClass = "";
player.lastClass = player.pers["lastClass"];
player.detectExplosives = false;
player.bombSquadIcons = [];
player.bombSquadIds = [];
}
}
}
fadeAway( waitDelay, fadeDelay )
{
@@ -987,7 +1076,6 @@ fadeAway( waitDelay, fadeDelay )
self.alpha = 0;
}
setClass( newClass )
{
self.curClass = newClass;
@@ -1003,7 +1091,6 @@ getPerkForClass( perkSlot, className )
return table_getPerk( level.classTableName, class_num, perkSlot );
}
classHasPerk( className, perkName )
{
return( getPerkForClass( 0, className ) == perkName || getPerkForClass( 1, className ) == perkName || getPerkForClass( 2, className ) == perkName );
@@ -0,0 +1,416 @@
#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, overridePointsPopup )
{
if ( isDefined( level.nukeIncoming ) )
return;
if ( !isDefined( overridePointsPopup ) )
overridePointsPopup = false;
score = player.pers["score"];
onPlayerScore( event, player, victim );
if ( score == player.pers["score"] )
return;
if ( !player rankingEnabled() && !level.hardcoreMode && !overridePointsPopup )
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) );
player.score = player.pers["score"];
player maps\mp\gametypes\_persistence::statSetChild( "round", "score", player.score );
if ( !level.teambased )
thread sendUpdatedDMScores();
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;
_setTeamScore( team, _getTeamScore( team ) + score );
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 ( 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 maps\mp\gametypes\_gamelogic::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.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 ) || (player.pers["team"] != "allies" && player.pers["team"] != "axis") )
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.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"];
}
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 ( self.pers["team"] != "axis" && self.pers["team"] != "allies" )
return;
if ( self.pers["team"] == killedplayer.pers["team"] )
return;
self thread [[level.onXPEvent]]( "assist" );
self incPersStat( "assists", 1 );
self.assists = self getPersStat( "assists" );
self incPlayerStat( "assists", 1 );
givePlayerScore( "assist", 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();
}
@@ -0,0 +1,14 @@
dm
dom
sd
sab
war
koth
oneflag
arena
dd
ctf
gtnw
conf
gun
infect
+28 -28
View File
@@ -123,9 +123,9 @@ onMenuResponse()
{
self endon("disconnect");
for (;;)
for(;;)
{
self waittill( "menuresponse", menu, response );
self waittill("menuresponse", menu, response);
if ( response == "back" )
{
@@ -142,21 +142,20 @@ onMenuResponse()
continue;
}
if (response == "changeteam")
if(response == "changeteam")
{
self closepopupMenu();
self closeInGameMenu();
self openpopupMenu(game["menu_team"]);
}
if (response == "changeclass_marines")
if(response == "changeclass_marines" )
{
self closepopupMenu();
self closeInGameMenu();
if ( getDvar( "g_gametype" ) != "oitc" && getDvar( "g_gametype" ) != "gg" && getDvar( "g_gametype" ) != "ss" && !isDefined(level.customClassCB) )
{
if ( allowClassChoice() )
self openpopupMenu( game["menu_changeclass_allies"] );
}
continue;
}
@@ -164,17 +163,17 @@ onMenuResponse()
{
self closepopupMenu();
self closeInGameMenu();
if ( getDvar( "g_gametype" ) != "oitc" && getDvar( "g_gametype" ) != "gg" && getDvar( "g_gametype" ) != "ss" && !isDefined(level.customClassCB) )
{
if ( allowClassChoice() )
self openpopupMenu( game["menu_changeclass_axis"] );
}
continue;
}
if (response == "changeclass_marines_splitscreen" )
if(response == "changeclass_marines_splitscreen" )
self openpopupMenu( "changeclass_marines_splitscreen" );
if (response == "changeclass_opfor_splitscreen" )
if(response == "changeclass_opfor_splitscreen" )
self openpopupMenu( "changeclass_opfor_splitscreen" );
if ( response == "endround" )
@@ -186,7 +185,7 @@ onMenuResponse()
if ( !level.gameEnded )
{
setDvar( "sv_dontRotate", 1 );
setDvar("sv_dontrotate", 1);
level thread maps\mp\gametypes\_gamelogic::forceEnd();
}
else
@@ -198,9 +197,9 @@ onMenuResponse()
continue;
}
if (menu == game["menu_team"])
if(menu == game["menu_team"])
{
switch (response)
switch(response)
{
case "allies":
self [[level.allies]]();
@@ -320,29 +319,30 @@ menuAutoAssign()
beginClassChoice( forceNewChoice )
{
assert( self.pers["team"] == "axis" || self.pers["team"] == "allies" );
if ( getDvar( "g_gametype" ) == "oitc" || getDvar( "g_gametype" ) == "gg" || getDvar( "g_gametype" ) == "ss" || isDefined(level.customClassCB) )
{
if ( !isAlive( self ) )
self thread maps\mp\gametypes\_playerlogic::predictAboutToSpawnPlayerOverTime( 0.1 );
self.selectedClass = true;
self menuClass( "assault_mp,0" );
return;
}
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 game mode allows class choice
if ( allowClassChoice() )
self openpopupMenu( game[ "menu_changeclass_" + team ] );
else
self thread bypassClassChoice();
if ( !isAlive( self ) )
self thread maps\mp\gametypes\_playerlogic::predictAboutToSpawnPlayerOverTime( 0.1 );
}
bypassClassChoice()
{
self.selectedClass = true;
self [[level.class]]("class0");
}
beginTeamChoice()
{
if ( getDvarInt( "scr_player_forceautoassign" ) != 0 )
@@ -538,7 +538,7 @@ addToTeam( team, firstConnect )
self.team = team;
// session team is readonly in ranked matches on console
if ( !matchMakingGame() || isDefined( self.pers["isBot"] ) )
if ( !matchMakingGame() || isDefined( self.pers["isBot"] ) || !allowTeamChoice() )
{
if ( level.teamBased )
{
+100 -60
View File
@@ -116,6 +116,12 @@ maySpawn()
spawnClient()
{
if ( isDefined( self.addtoteam ) )
{
maps\mp\gametypes\_menus::addToTeam( self.addtoteam );
self.addtoteam = undefined;
}
assert( isDefined( self.team ) );
assert( isValidClass( self.class ) );
@@ -504,13 +510,16 @@ tiValidationCheck()
return true;
}
spawnPlayer()
spawnPlayer( fauxSpawn )
{
self endon( "disconnect" );
self endon( "joined_spectators" );
self notify( "spawned" );
self notify( "end_respawn" );
if ( !isDefined( fauxSpawn ) )
fauxSpawn = false;
if ( isDefined( self.setSpawnPoint ) && self tiValidationCheck() )
{
spawnPoint = self.setSpawnPoint;
@@ -559,62 +568,69 @@ spawnPlayer()
self.fauxDead = undefined;
self.killsThisLife = [];
self updateSessionState( "playing", "" );
self ClearKillcamState();
self.cancelkillcam = 1;
self openMenu( "killedby_card_hide" );
if ( !fauxSpawn )
{
self.killsThisLife = [];
self updateSessionState( "playing", "" );
self ClearKillcamState();
self.cancelkillcam = 1;
self openMenu( "killedby_card_hide" );
self.maxhealth = maps\mp\gametypes\_tweakables::getTweakableValue( "player", "maxhealth" );
self.maxhealth = maps\mp\gametypes\_tweakables::getTweakableValue( "player", "maxhealth" );
self.health = self.maxhealth;
self.friendlydamage = undefined;
self.hasSpawned = true;
self.spawnTime = getTime();
self.wasTI = !isDefined( spawnPoint );
self.afk = false;
self.lastStand = undefined;
self.infinalStand = undefined;
self.inC4Death = undefined;
self.damagedPlayers = [];
self.moveSpeedScaler = 1;
self.killStreakScaler = 1;
self.xpScaler = 1;
self.objectiveScaler = 1;
self.inLastStand = false;
self.clampedHealth = undefined;
self.shieldDamage = 0;
self.shieldBulletHits = 0;
self.recentShieldXP = 0;
self.health = self.maxhealth;
self.friendlydamage = undefined;
self.hasSpawned = true;
self.spawnTime = getTime();
self.wasTI = !isDefined( spawnPoint );
self.afk = false;
self.lastStand = undefined;
self.infinalStand = undefined;
self.inC4Death = undefined;
self.damagedPlayers = [];
self.moveSpeedScaler = 1;
self.killStreakScaler = 1;
self.xpScaler = 1;
self.objectiveScaler = 1;
self.inLastStand = false;
self.clampedHealth = undefined;
self.shieldDamage = 0;
self.shieldBulletHits = 0;
self.recentShieldXP = 0;
}
self.disabledWeapon = 0;
self.disabledWeaponSwitch = 0;
self.disabledOffhandWeapons = 0;
self resetUsability();
if ( self.pers["lives"] == getGametypeNumLives() )
{
maps\mp\gametypes\_playerlogic::addToLivesCount();
}
if ( self.pers["lives"] )
self.pers["lives"]--;
self maps\mp\gametypes\_playerlogic::addToAliveCount();
if ( !hadSpawned || gameHasStarted() || (gameHasStarted() && level.inGracePeriod && self.hasDoneCombat) )
self maps\mp\gametypes\_playerlogic::removeFromLivesCount();
if ( !self.wasAliveAtMatchStart )
if ( !fauxSpawn )
{
acceptablePassedTime = 20;
if ( getTimeLimit() > 0 && acceptablePassedTime < getTimeLimit() * 60 / 4 )
acceptablePassedTime = getTimeLimit() * 60 / 4;
if ( self.pers["lives"] == getGametypeNumLives() )
{
maps\mp\gametypes\_playerlogic::addToLivesCount();
}
if ( level.inGracePeriod || getTimePassed() < acceptablePassedTime * 1000 )
self.wasAliveAtMatchStart = true;
if ( self.pers["lives"] )
self.pers["lives"]--;
self maps\mp\gametypes\_playerlogic::addToAliveCount();
if ( !hadSpawned || gameHasStarted() || (gameHasStarted() && level.inGracePeriod && self.hasDoneCombat) )
self maps\mp\gametypes\_playerlogic::removeFromLivesCount();
if ( !self.wasAliveAtMatchStart )
{
acceptablePassedTime = 20;
if ( getTimeLimit() > 0 && acceptablePassedTime < getTimeLimit() * 60 / 4 )
acceptablePassedTime = getTimeLimit() * 60 / 4;
if ( level.inGracePeriod || getTimePassed() < acceptablePassedTime * 1000 )
self.wasAliveAtMatchStart = true;
}
}
self setClientDvar( "cg_thirdPerson", "0" );
@@ -636,6 +652,14 @@ spawnPlayer()
self.spawnPos = spawnOrigin;
self spawn( spawnOrigin, spawnAngles );
// immediately fix our stance if we were spawned in place so we don't get stuck in geo
if ( fauxSpawn && isDefined( self.faux_spawn_stance ) )
{
self setStance( self.faux_spawn_stance );
self.faux_spawn_stance = undefined;
}
[[level.onSpawnPlayer]]();
// Don't do this stuff for TI spawn points
@@ -684,7 +708,7 @@ spawnPlayer()
prof_end( "spawnPlayer_postUTS" );
self logstring( "S " + self.origin[0] + " " + self.origin[1] + " " + self.origin[2] );
//self logstring( "S " + self.origin[0] + " " + self.origin[1] + " " + self.origin[2] );
// give "connected" handlers a chance to start
// many of these start onPlayerSpawned handlers which rely on the "spawned_player"
@@ -1122,17 +1146,21 @@ Callback_PlayerConnect()
logPrint("J;" + self.guid + ";" + self getEntityNumber() + ";" + self.name + "\n");
if ( matchMakingGame() && game["clientid"] <= 24 && game["clientid"] != getMatchData( "playerCount" ) )
if ( game["clientid"] <= 24 && game["clientid"] != getMatchData( "playerCount" ) )
{
setMatchData( "playerCount", game["clientid"] );
setMatchData( "players", self.clientid, "xuid", self getXuid() );
/#
if ( ( getDvarInt( "scr_forcerankedmatch" ) && level.teamBased ) || ( isDefined( self.pers["isBot"] ) && level.teamBased ) )
self.sessionteam = maps\mp\gametypes\_menus::getTeamAssignment();
#/
assert( getdvarint( "scr_runlevelandquit" ) == 1 || (level.teamBased && (self.sessionteam == "allies" || self.sessionteam == "axis")) || (!level.teamBased && self.sessionteam == "none" ) );
//assert( (level.teamBased && self.sessionteam == self.team) || (!level.teamBased && self.sessionteam == "none") );
setMatchData( "players", self.clientid, "team", self.sessionteam );
if( matchMakingGame() && allowTeamChoice() )
{
/#
if ( ( getDvarInt( "scr_forcerankedmatch" ) && level.teamBased ) || ( isDefined( self.pers["isBot"] ) && level.teamBased ) )
self.sessionteam = maps\mp\gametypes\_menus::getTeamAssignment();
#/
assert( getdvarint( "scr_runlevelandquit" ) == 1 || (level.teamBased && (self.sessionteam == "allies" || self.sessionteam == "axis")) || (!level.teamBased && self.sessionteam == "none" ) );
//assert( (level.teamBased && self.sessionteam == self.team) || (!level.teamBased && self.sessionteam == "none") );
setMatchData( "players", self.clientid, "team", self.sessionteam );
}
}
if ( !level.teamBased )
@@ -1236,9 +1264,16 @@ Callback_PlayerConnect()
self thread kickIfDontSpawn();
return;
}
self [[level.spectator]]();
self maps\mp\gametypes\_menus::beginTeamChoice();
else if ( allowTeamChoice() )
{
self [[level.spectator]]();
self maps\mp\gametypes\_menus::beginTeamChoice();
}
else
{
self [[ level.spectator ]]();
self [[level.autoassign]]();
}
}
else
{
@@ -1253,7 +1288,12 @@ Callback_PlayerConnect()
self thread spawnSpectator();
if ( self.pers["team"] == "spectator" )
self maps\mp\gametypes\_menus::beginTeamChoice();
{
if ( allowTeamChoice() )
self maps\mp\gametypes\_menus::beginTeamChoice();
else
self [[level.autoassign]]();
}
else
self maps\mp\gametypes\_menus::beginClassChoice();
}
+763
View File
@@ -0,0 +1,763 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
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", 20 );
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 )
{
overrideDvar = "scr_" + level.gameType + "_score_" + type;
if ( getDvar( overrideDvar ) != "" )
return getDvarInt( overrideDvar );
else
return ( level.scoreInfo[type]["value"] );
}
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;
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_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.hud_xpEventPopup = player createXpEventPopup();
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.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":
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 );
}
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;
}
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;
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;
}
xpEventPopupFinalize( event, hudColor, glowAlpha )
{
self endon( "disconnect" );
self endon( "joined_team" );
self endon( "joined_spectators" );
self notify( "xpEventPopup" );
self endon( "xpEventPopup" );
if ( level.hardcoremode )
return;
wait ( 0.05 );
if ( !isDefined( hudColor ) )
hudColor = (1,1,0.5);
if ( !isDefined( glowAlpha ) )
glowAlpha = 0;
if ( !isDefined( self ) )
return;
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 );
if ( !isDefined( self ) )
return;
self.hud_xpEventPopup fadeOverTime( 0.75 );
self.hud_xpEventPopup.alpha = 0;
self notify( "PopComplete" );
}
xpEventPopupTerminate()
{
self endon( "PopComplete" );
waittill_any( "joined_team", "joined_spectators" );
self.hud_xpEventPopup fadeOverTime( 0.05 );
self.hud_xpEventPopup .alpha = 0;
}
xpEventPopup( event, hudColor, glowAlpha )
{
thread xpEventPopupFinalize( event, hudColor, glowAlpha );
thread xpEventPopupTerminate();
}
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"];
}
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 );
}
File diff suppressed because it is too large. Load diff
+398
View File
@@ -0,0 +1,398 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
/*
Confirmed Kill
Objective: Score points for your team by eliminating players on the opposing team.
Score bonus points for picking up dogtags from downed enemies.
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.
*/
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, 5, 0, 20 );
registerScoreLimitDvar( level.gameType, 65, 0, 100 );
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.onPrecacheGameType = ::onPrecacheGameType;
game["dialog"]["gametype"] = "kill_confirmed";
level.conf_fx["vanish"] = loadFx( "impacts/small_snowhit" );
}
onPrecacheGameType()
{
precachemodel( "prop_dogtags_friend" );
precachemodel( "prop_dogtags_foe" );
precacheshader( "waypoint_dogtags" );
}
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_CONF" );
setObjectiveText( "axis", &"OBJECTIVES_CONF" );
setObjectiveScoreText( "allies", &"OBJECTIVES_CONF_SCORE" );
setObjectiveScoreText( "axis", &"OBJECTIVES_CONF_SCORE" );
setObjectiveHintText( "allies", &"OBJECTIVES_CONF_HINT" );
setObjectiveHintText( "axis", &"OBJECTIVES_CONF_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 );
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "kill_confirmed", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "kill_denied", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "tags_retrieved", 250 );
level.dogtags = [];
allowed[0] = level.gameType;
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 )
{
level thread spawnDogTags( victim, attacker );
if ( game["state"] == "postgame" && game["teamScores"][attacker.team] > game["teamScores"][level.otherTeam[attacker.team]] )
attacker.finalKill = true;
}
spawnDogTags( victim, attacker )
{
if ( isDefined( level.dogtags[victim.guid] ) )
{
PlayFx( level.conf_fx["vanish"], level.dogtags[victim.guid].curOrigin );
level.dogtags[victim.guid] notify( "reset" );
}
else
{
visuals[0] = spawn( "script_model", (0,0,0) );
visuals[0] setModel( "prop_dogtags_foe" );
visuals[1] = spawn( "script_model", (0,0,0) );
visuals[1] setModel( "prop_dogtags_friend" );
trigger = spawn( "trigger_radius", (0,0,0), 0, 32, 32 );
level.dogtags[victim.guid] = maps\mp\gametypes\_gameobjects::createUseObject( "any", trigger, visuals, (0,0,16) );
// we don't need these
_objective_delete( level.dogtags[victim.guid].objIDAllies );
_objective_delete( level.dogtags[victim.guid].objIDAxis );
maps\mp\gametypes\_objpoints::deleteObjPoint( level.dogtags[victim.guid].objPoints["allies"] );
maps\mp\gametypes\_objpoints::deleteObjPoint( level.dogtags[victim.guid].objPoints["axis"] );
level.dogtags[victim.guid] maps\mp\gametypes\_gameobjects::setUseTime( 0 );
level.dogtags[victim.guid].onUse = ::onUse;
level.dogtags[victim.guid].victim = victim;
level.dogtags[victim.guid].victimTeam = victim.pers["team"];
level.dogtags[victim.guid].objId = maps\mp\gametypes\_gameobjects::getNextObjID();
objective_add( level.dogtags[victim.guid].objId, "invisible", (0,0,0) );
objective_icon( level.dogtags[victim.guid].objId, "waypoint_dogtags" );
level thread clearOnVictimDisconnect( victim );
victim thread tagTeamUpdater( level.dogtags[victim.guid] );
}
pos = victim.origin + (0,0,14);
level.dogtags[victim.guid].curOrigin = pos;
level.dogtags[victim.guid].trigger.origin = pos;
level.dogtags[victim.guid].visuals[0].origin = pos;
level.dogtags[victim.guid].visuals[1].origin = pos;
level.dogtags[victim.guid] maps\mp\gametypes\_gameobjects::allowUse( "any" );
level.dogtags[victim.guid].visuals[0] thread showToTeam( level.dogtags[victim.guid], getOtherTeam( victim.pers["team"] ) );
level.dogtags[victim.guid].visuals[1] thread showToTeam( level.dogtags[victim.guid], victim.pers["team"] );
level.dogtags[victim.guid].attacker = attacker;
//level.dogtags[victim.guid] thread timeOut( victim );
objective_position( level.dogtags[victim.guid].objId, pos );
objective_state( level.dogtags[victim.guid].objId, "active" );
//objective_player( level.dogtags[victim.guid].objId, attacker getEntityNumber() );
playSoundAtPos( pos, "mp_killconfirm_tags_drop" );
level.dogtags[victim.guid] thread bounce();
}
showToTeam( gameObject, team )
{
gameObject endon ( "death" );
gameObject endon( "reset" );
self hide();
foreach ( player in level.players )
{
if( player.team == team )
self ShowToPlayer( player );
}
for ( ;; )
{
level waittill ( "joined_team" );
self hide();
foreach ( player in level.players )
{
if ( player.team == team )
self ShowToPlayer( player );
if ( gameObject.victimTeam == player.team && player == gameObject.attacker )
objective_state( gameObject.objId, "invisible" );
}
}
}
onUse( player )
{
// friendly pickup
if ( player.pers["team"] == self.victimTeam )
{
self.trigger playSound( "mp_killconfirm_tags_deny" );
if ( self.victim == player )
{
event = "tags_retrieved";
splash = &"SPLASHES_TAGS_RETRIEVED";
}
else
{
event = "kill_denied";
splash = &"SPLASHES_KILL_DENIED";
}
// tell the attacker their kill was denied
if ( isDefined( self.attacker ) )
self.attacker thread maps\mp\gametypes\_rank::xpEventPopup( &"SPLASHES_DENIED_KILL", ( 1,0.5,0.5) );
}
// enemy pickup
else
{
self.trigger playSound( "mp_killconfirm_tags_pickup" );
event = "kill_confirmed";
splash = &"SPLASHES_KILL_CONFIRMED";
// if not us, tell the attacker their kill was confirmed
if ( self.attacker != player )
self.attacker onPickup( event, splash );
self.trigger playSoundToPlayer( game["voice"][player.pers["team"]] + "kill_confirmed", player );
player maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( player.pers["team"], 1 );
}
player onPickup( event, splash );
// do all this at the end now so the location doesn't change before playing the sound on the entity
self resetTags();
}
onPickup( event, splash )
{
level endon( "game_ended" );
self endon( "disconnect" );
self thread maps\mp\gametypes\_rank::xpEventPopup( splash );
maps\mp\gametypes\_gamescore::givePlayerScore( event, self, undefined, true );
self thread maps\mp\gametypes\_rank::giveRankXP( event );
}
resetTags()
{
self.attacker = undefined;
self notify( "reset" );
self.visuals[0] hide();
self.visuals[1] hide();
self.curOrigin = (0,0,1000);
self.trigger.origin = (0,0,1000);
self.visuals[0].origin = (0,0,1000);
self.visuals[1].origin = (0,0,1000);
self maps\mp\gametypes\_gameobjects::allowUse( "none" );
objective_state( self.objId, "invisible" );
}
bounce()
{
level endon( "game_ended" );
self endon( "reset" );
bottomPos = self.curOrigin;
topPos = self.curOrigin + (0,0,12);
while( true )
{
self.visuals[0] moveTo( topPos, 0.5, 0.15, 0.15 );
self.visuals[0] rotateYaw( 180, 0.5 );
self.visuals[1] moveTo( topPos, 0.5, 0.15, 0.15 );
self.visuals[1] rotateYaw( 180, 0.5 );
wait( 0.5 );
self.visuals[0] moveTo( bottomPos, 0.5, 0.15, 0.15 );
self.visuals[0] rotateYaw( 180, 0.5 );
self.visuals[1] moveTo( bottomPos, 0.5, 0.15, 0.15 );
self.visuals[1] rotateYaw( 180, 0.5 );
wait( 0.5 );
}
}
timeOut( victim )
{
level endon( "game_ended" );
victim endon( "disconnect" );
self notify( "timeout" );
self endon( "timeout" );
level maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( 30.0 );
self.visuals[0] hide();
self.visuals[1] hide();
self.curOrigin = (0,0,1000);
self.trigger.origin = (0,0,1000);
self.visuals[0].origin = (0,0,1000);
self.visuals[1].origin = (0,0,1000);
self maps\mp\gametypes\_gameobjects::allowUse( "none" );
}
tagTeamUpdater( tags )
{
level endon( "game_ended" );
self endon( "disconnect" );
while( true )
{
self waittill( "joined_team" );
tags.victimTeam = self.pers["team"];
tags resetTags();
}
}
clearOnVictimDisconnect( victim )
{
level endon( "game_ended" );
guid = victim.guid;
victim waittill( "disconnect" );
if ( isDefined( level.dogtags[guid] ) )
{
// block further use
level.dogtags[guid] maps\mp\gametypes\_gameobjects::allowUse( "none" );
// tell the attacker their kill was denied
if ( isDefined( level.dogtags[guid].attacker ) )
level.dogtags[guid].attacker thread maps\mp\gametypes\_rank::xpEventPopup( &"SPLASHES_DENIED_KILL", (1,0.5,0.5) );
// play vanish effect, reset, and wait for reset to process
PlayFx( level.conf_fx["vanish"], level.dogtags[guid].curOrigin );
level.dogtags[guid] notify( "reset" );
wait( 0.05 );
// sanity check before removal
if ( isDefined( level.dogtags[guid] ) )
{
// delete objective and visuals
objective_delete( level.dogtags[guid].objId );
level.dogtags[guid].trigger delete();
for ( i=0; i<level.dogtags[guid].visuals.size; i++ )
level.dogtags[guid].visuals[i] delete();
level.dogtags[guid] notify ( "deleted" );
// remove from list
level.dogtags[guid] = undefined;
}
}
}
+1
View File
@@ -0,0 +1 @@
"MPUI_CONF"
+577
View File
@@ -0,0 +1,577 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include maps\mp\gametypes\_class;
#include common_scripts\utility;
/*
Gun Game
Objective: Progress through all weapon tiers by killing enemy players
Map ends: When a player progresses through all weapon tiers
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();
// must be done before scorelimit is set
setGuns();
registerTimeLimitDvar( level.gameType, 10 );
scoreLimit = level.gun_guns.size;
SetDvar( "scr_gun_scorelimit", scoreLimit );
registerScoreLimitDvar( level.gametype, level.gun_guns.size );
registerRoundLimitDvar( level.gameType, 1, 0, 10 );
registerWinLimitDvar( level.gameType, 1, 0, 10 );
registerNumLivesDvar( level.gameType, 0, 0, 10 );
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
setSpecialLoadout();
level.teamBased = false;
level.doPrematch = true;
level.killstreakRewards = false;
level.onPrecacheGameType = ::onPrecacheGameType;
level.onStartGameType = ::onStartGameType;
level.onSpawnPlayer = ::onSpawnPlayer;
level.getSpawnPoint = ::getSpawnPoint;
level.onPlayerKilled = ::onPlayerKilled;
level.onTimeLimit = ::onTimeLimit;
}
onprecachegametype()
{
precachestring( &"MP_GUN" );
}
onStartGameType()
{
setClientNameMode("auto_change");
setObjectiveText( "allies", &"OBJECTIVES_DM" );
setObjectiveText( "axis", &"OBJECTIVES_DM" );
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 );
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "suicide", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "teamkill", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "execution", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "avenger", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "defender", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "posthumous", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "revenge", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "double", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "triple", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "multi", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "buzzkill", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "firstblood", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "comeback", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "longshot", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "assistedsuicide", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "knifethrow", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "gained_gun_score", 1 );
maps\mp\gametypes\_rank::registerScoreInfo( "dropped_gun_score", -1 );
maps\mp\gametypes\_rank::registerScoreInfo( "gained_gun_rank", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "dropped_enemy_gun_rank", 100 );
allowed = [];
maps\mp\gametypes\_gameobjects::main(allowed);
// Prevent class and team change
setDvar( "ui_allow_classchange", 0 );
setdvar( "ui_allow_teamchange", 0 );
level.QuickMessageToAll = true;
level.blockWeaponDrops = true;
// set index on enter
level thread onPlayerConnect();
level.killstreakRewards = false;
}
onPlayerConnect()
{
for ( ;; )
{
level waittill( "connected", player );
player.gun_firstSpawn = true;
player.gunGameGunIndex = 0;
player.gunGamePrevGunIndex = 0;
player initGunHUD();
player thread refillAmmo();
player thread refillSingleCountAmmo();
}
}
getSpawnPoint()
{
// first time here?
if ( self.gun_firstSpawn )
{
self.gun_firstSpawn = false;
// everyone is a gamemode class in gun, no class selection
self.pers["class"] = "gamemode";
self.pers["lastClass"] = "";
self.class = self.pers["class"];
self.lastClass = self.pers["lastClass"];
// random team
if ( cointoss() )
self maps\mp\gametypes\_menus::addToTeam( "axis", true );
else
self maps\mp\gametypes\_menus::addToTeam( "allies", true );
}
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( self.pers["team"] );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_DM( spawnPoints );
return spawnPoint;
}
onSpawnPlayer()
{
// level.onSpawnPlayer() gets called before giveLoadout()
// so wait until it is done then override weapons
self.pers["gamemodeLoadout"] = level.gun_loadouts[self.pers["team"]];
self thread waitLoadoutDone();
level notify ( "spawned_player" );
}
waitLoadoutDone()
{
level endon( "game_ended" );
self endon( "disconnect" );
self waittill( "spawned_player" );
self _setPerk( "specialty_bling" );
self giveNextGun( true );
}
onPlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
{
if ( sMeansOfDeath == "MOD_FALLING" || ( isDefined( attacker ) && isPlayer( attacker ) ) )
{
isMeleeWeapon = maps\mp\gametypes\_weapons::isRiotShield( sWeapon );
if ( sMeansOfDeath == "MOD_FALLING" || attacker == self || ( sMeansOfDeath == "MOD_MELEE" && !isMeleeWeapon ) )
{
self playLocalSound( "mp_war_objective_lost" );
// drop level for suicide and getting knifed
self.gunGamePrevGunIndex = self.gunGameGunIndex;
self.gunGameGunIndex = int( max( 0, self.gunGameGunIndex-1 ) );
if ( self.gunGamePrevGunIndex > self.gunGameGunIndex )
{
self thread maps\mp\gametypes\_rank::xpEventPopup( &"SPLASHES_DROPPED_GUN_RANK" );
maps\mp\gametypes\_gamescore::givePlayerScore( "dropped_gun_score", self, undefined, true, true );
}
if ( sMeansOfDeath == "MOD_MELEE" )
{
if ( self.gunGamePrevGunIndex )
{
attacker thread maps\mp\gametypes\_rank::xpEventPopup( &"SPLASHES_DROPPED_ENEMY_GUN_RANK" );
attacker thread maps\mp\gametypes\_rank::giveRankXP( "dropped_enemy_gun_rank" );
}
}
}
else if ( ( sMeansOfDeath == "MOD_PISTOL_BULLET" )
|| ( sMeansOfDeath == "MOD_RIFLE_BULLET" )
|| ( sMeansOfDeath == "MOD_HEAD_SHOT" )
|| ( sMeansOfDeath == "MOD_PROJECTILE" ) || ( sMeansOfDeath == "MOD_PROJECTILE_SPLASH" )
|| ( sMeansOfDeath == "MOD_IMPACT" )
|| ( sMeansOfDeath == "MOD_GRENADE" ) || ( sMeansOfDeath == "MOD_GRENADE_SPLASH" )
|| ( sMeansOfDeath == "MOD_MELEE" && isMeleeWeapon )
)
{
// Prevent sequential kills from counting by validating the primary weapon
// Let throwing knife kills count even though they're not the primary weapon
if ( sWeapon != attacker.primaryWeapon )
return;
attacker.gunGamePrevGunIndex = attacker.gunGameGunIndex;
attacker.gunGameGunIndex++;
attacker thread maps\mp\gametypes\_rank::giveRankXP( "gained_gun_rank" );
maps\mp\gametypes\_gamescore::givePlayerScore( "gained_gun_score", attacker, self, true, true );
if ( attacker.gunGameGunIndex == level.gun_guns.size-1 )
{
playSoundOnPlayers( "mp_enemy_obj_captured" );
level thread teamPlayerCardSplash( "callout_top_gun_rank", attacker );
}
if ( attacker.gunGameGunIndex < level.gun_guns.size )
{
attacker thread maps\mp\gametypes\_rank::xpEventPopup( &"SPLASHES_GAINED_GUN_RANK" );
attacker playLocalSound( "mp_war_objective_taken" );
attacker giveNextGun();
}
}
}
}
giveNextGun( doSetSpawnWeapon )
{
// get the next one
newWeapon = level.gun_guns[self.gunGameGunIndex];
// add attachments
newWeapon = addAttachments( newWeapon );
// give gun
self takeAllWeapons();
_giveWeapon( newWeapon );
// set vars
if ( isDefined( doSetSpawnWeapon ) )
self setSpawnWeapon( newWeapon );
weaponTokens = StrTok( newWeapon, "_" );
weaponName = weaponTokens[0];
self.pers["primaryWeapon"] = weaponName;
self.primaryWeapon = newWeapon;
// use it!
self GiveStartAmmo( newWeapon );
self switchToWeapon( newWeapon );
// gain/drop scoring/messaging
if ( self.gunGamePrevGunIndex > self.gunGameGunIndex )
{
// we dropped :(
self thread maps\mp\gametypes\_rank::xpEventPopup( &"SPLASHES_DROPPED_GUN_RANK" );
}
else if ( self.gunGamePrevGunIndex < self.gunGameGunIndex )
{
// we gained :)
self thread maps\mp\gametypes\_rank::xpEventPopup( &"SPLASHES_GAINED_GUN_RANK" );
}
self.gunGamePrevGunIndex = self.gunGameGunIndex;
// update the personal gun progress hud
self updateGunHUD();
}
addAttachments( weaponName )
{
if ( isDefined( level.gun_attachments[weaponName] ) && isDefined( level.gun_attachments[weaponName]["attach1"] ) )
attach1 = level.gun_attachments[weaponName]["attach1"];
else
attach1 = "none";
if ( isDefined( level.gun_attachments[weaponName] ) && isDefined( level.gun_attachments[weaponName]["attach2"] ) )
attach2 = level.gun_attachments[weaponName]["attach2"];
else
attach2 = "none";
fullWeaponName = buildWeaponName( weaponName, attach1, attach2 );
return fullWeaponName;
}
onTimeLimit()
{
level.finalKillCam_winner = "none";
winners = getHighestProgressedPlayers();
if ( !isDefined( winners ) || !winners.size )
thread maps\mp\gametypes\_gamelogic::endGame( "tie", game[ "end_reason" ][ "time_limit_reached" ] );
else if ( winners.size == 1 )
thread maps\mp\gametypes\_gamelogic::endGame( winners[0], game[ "end_reason" ][ "time_limit_reached" ] );
else
{
if ( winners[winners.size-1].gunGameGunIndex > winners[winners.size-2].gunGameGunIndex )
thread maps\mp\gametypes\_gamelogic::endGame( winners[winners.size-1], game[ "end_reason" ][ "time_limit_reached" ] );
else
thread maps\mp\gametypes\_gamelogic::endGame( "tie", game[ "end_reason" ][ "time_limit_reached" ] );
}
}
getHighestProgressedPlayers()
{
highestProgress = -1;
highestProgressedPlayers = [];
foreach( player in level.players )
{
if ( isDefined( player.gunGameGunIndex ) && player.gunGameGunIndex >= highestProgress )
{
highestProgress = player.gunGameGunIndex;
highestProgressedPlayers[highestProgressedPlayers.size] = player;
}
}
return highestProgressedPlayers;
}
refillAmmo()
{
level endon( "game_ended" );
self endon( "disconnect" );
while ( true )
{
self waittill( "reload" );
self GiveStartAmmo( self.primaryWeapon );
}
}
refillSingleCountAmmo()
{
level endon( "game_ended" );
self endon( "disconnect" );
while ( true )
{
if ( isReallyAlive( self ) && self.team != "spectator" && isDefined( self.primaryWeapon ) && self getAmmoCount( self.primaryWeapon ) == 0 )
{
// fake a reload time
wait( 2 );
self notify( "reload" );
wait( 1 );
}
else
wait( 0.05 );
}
}
initGunHUD()
{
self.gun_progressDisplay[0] = self createFontString( "small", 1.6 );
self.gun_progressDisplay[0] setPoint( "TOP LEFT", "TOP LEFT", 115, 5 );
self.gun_progressDisplay[0] setText( &"MP_WEAPON" );
self.gun_progressDisplay[0].alpha = 1;
self.gun_progressDisplay[0].archived = false;
self.gun_progressDisplay[0].hideWhenInMenu = true;
self.gun_progressDisplay[1] = self createFontString( "small", 1.6 );
self.gun_progressDisplay[1] setPoint( "TOP LEFT", "TOP LEFT", 115, 23 );
self.gun_progressDisplay[1] setText( "1 / " + level.gun_guns.size );
self.gun_progressDisplay[1].alpha = 1;
self.gun_progressDisplay[1].archived = false;
self.gun_progressDisplay[1].hideWhenInMenu = true;
thread hideOnGameEnd();
thread hideInKillCam();
}
updateGunHUD()
{
self.gun_progressDisplay[1] setText( (self.gunGameGunIndex+1) + " / " + level.gun_guns.size );
}
hideInKillCam()
{
self endon( "disconnect" );
var_0 = 1;
for (;;)
{
if ( var_0 && ( !isalive( self ) || isinkillcam() ) )
{
self.gun_progressdisplay[0].alpha = 0;
self.gun_progressdisplay[1].alpha = 0;
var_0 = 0;
}
else if ( !var_0 && ( isalive( self ) && !isinkillcam() ) )
{
self.gun_progressdisplay[0].alpha = 1;
self.gun_progressdisplay[1].alpha = 1;
var_0 = 1;
}
wait 0.05;
}
}
hideOnGameEnd()
{
self endon( "disconnect" );
level waittill( "game_ended" );
self.gun_progressDisplay[0].alpha = 0;
self.gun_progressDisplay[1].alpha = 0;
}
setGuns()
{
level.gun_guns = [];
// hand guns
level.gun_guns[0] = "deserteagle";
// machine pistols
level.gun_guns[1] = "glock";
level.gun_guns[2] = "tmp";
// sub
level.gun_guns[3] = "mp5k";
level.gun_guns[4] = "p90";
level.gun_guns[5] = "kriss";
// assault - auto
level.gun_guns[6] = "ak47";
level.gun_guns[7] = "masada";
level.gun_guns[8] = "scar";
// lmg
level.gun_guns[9] = "sa80";
level.gun_guns[10] = "aug";
// shotgun
level.gun_guns[11] = "spas12";
level.gun_guns[12] = "aa12";
level.gun_guns[13] = "model1887";
// assault - burst
level.gun_guns[14] = "famas";
level.gun_guns[15] = "m16";
// sniper
level.gun_guns[16] = "barrett";
level.gun_guns[17] = "cheytac";
// launcher
level.gun_guns[18] = "m79";
level.gun_guns[19] = "javelin";
// default attachments for all guns that take them
level.gun_attachments = [];
// pistol
level.gun_attachments["coltanaconda"]["attach1"] = "tactical";
level.gun_attachments["usp"]["attach1"] = "tactical";
level.gun_attachments["deserteagle"]["attach1"] = "tactical";
level.gun_attachments["deserteaglegold"]["attach1"] = "tactical";
level.gun_attachments["beretta"]["attach1"] = "tactical";
// machine pistol
level.gun_attachments["tmp"]["attach1"] = "reflex";
level.gun_attachments["glock"]["attach1"] = "reflex";
level.gun_attachments["pp2000"]["attach1"] = "reflex";
level.gun_attachments["beretta393"]["attach1"] = "reflex";
// smg
level.gun_attachments["mp5k"]["attach1"] = "reflex";
level.gun_attachments["mp5k"]["attach2"] = "xmags";
level.gun_attachments["uzi"]["attach1"] = "reflex";
level.gun_attachments["uzi"]["attach2"] = "xmags";
level.gun_attachments["p90"]["attach1"] = "reflex";
level.gun_attachments["p90"]["attach2"] = "xmags";
level.gun_attachments["kriss"]["attach1"] = "reflex";
level.gun_attachments["kriss"]["attach2"] = "xmags";
level.gun_attachments["ump45"]["attach1"] = "reflex";
level.gun_attachments["ump45"]["attach2"] = "xmags";
level.gun_attachments["ak74u"]["attach1"] = "reflex";
level.gun_attachments["ak74u"]["attach2"] = "xmags";
// assault
level.gun_attachments["ak47"]["attach1"] = "reflex";
level.gun_attachments["ak47"]["attach2"] = "xmags";
level.gun_attachments["ak47classic"]["attach1"] = "reflex";
level.gun_attachments["ak47classic"]["attach2"] = "xmags";
level.gun_attachments["m16"]["attach1"] = "reflex";
level.gun_attachments["m16"]["attach2"] = "xmags";
level.gun_attachments["m4"]["attach1"] = "reflex";
level.gun_attachments["m4"]["attach2"] = "xmags";
level.gun_attachments["fn2000"]["attach1"] = "reflex";
level.gun_attachments["fn2000"]["attach2"] = "xmags";
level.gun_attachments["masada"]["attach1"] = "reflex";
level.gun_attachments["masada"]["attach2"] = "xmags";
level.gun_attachments["famas"]["attach1"] = "reflex";
level.gun_attachments["famas"]["attach2"] = "xmags";
level.gun_attachments["fal"]["attach1"] = "reflex";
level.gun_attachments["fal"]["attach2"] = "xmags";
level.gun_attachments["scar"]["attach1"] = "reflex";
level.gun_attachments["scar"]["attach2"] = "xmags";
level.gun_attachments["tavor"]["attach1"] = "reflex";
level.gun_attachments["tavor"]["attach2"] = "xmags";
level.gun_attachments["tavor"]["attach1"] = "reflex";
level.gun_attachments["tavor"]["attach2"] = "xmags";
// sniper
level.gun_attachments["barrett"]["attach1"] = "xmags";
level.gun_attachments["wa2000"]["attach1"] = "xmags";
level.gun_attachments["m21"]["attach1"] = "xmags";
level.gun_attachments["cheytac"]["attach1"] = "xmags";
level.gun_attachments["dragunov"]["attach1"] = "xmags";
level.gun_attachments["m40a3"]["attach1"] = "xmags";
// shotgun
level.gun_attachments["ranger"]["attach1"] = "akimbo";
level.gun_attachments["model1887"]["attach1"] = "akimbo";
level.gun_attachments["striker"]["attach1"] = "grip";
level.gun_attachments["striker"]["attach2"] = "xmags";
level.gun_attachments["aa12"]["attach1"] = "grip";
level.gun_attachments["aa12"]["attach2"] = "xmags";
level.gun_attachments["m1014"]["attach1"] = "grip";
level.gun_attachments["m1014"]["attach2"] = "xmags";
level.gun_attachments["spas12"]["attach1"] = "grip";
level.gun_attachments["spas12"]["attach2"] = "xmags";
// lmg
level.gun_attachments["rpd"]["attach1"] = "grip";
level.gun_attachments["rpd"]["attach2"] = "reflex";
level.gun_attachments["sa80"]["attach1"] = "grip";
level.gun_attachments["sa80"]["attach2"] = "reflex";
level.gun_attachments["mg4"]["attach1"] = "grip";
level.gun_attachments["mg4"]["attach2"] = "reflex";
level.gun_attachments["m240"]["attach1"] = "grip";
level.gun_attachments["m240"]["attach2"] = "reflex";
level.gun_attachments["aug"]["attach1"] = "grip";
level.gun_attachments["aug"]["attach2"] = "reflex";
}
setSpecialLoadout()
{
// no killstreaks defined for special classes
level.gun_loadouts["axis"]["loadoutPrimary"] = "masada"; // can't use "none" for primary, this is replaced on spawn anyway
level.gun_loadouts["axis"]["loadoutPrimaryAttachment"] = "none";
level.gun_loadouts["axis"]["loadoutPrimaryAttachment2"] = "none";
level.gun_loadouts["axis"]["loadoutPrimaryCamo"] = "none";
level.gun_loadouts["axis"]["loadoutSecondary"] = "none";
level.gun_loadouts["axis"]["loadoutSecondaryAttachment"] = "none";
level.gun_loadouts["axis"]["loadoutSecondaryAttachment2"] = "none";
level.gun_loadouts["axis"]["loadoutSecondaryCamo"] = "none";
level.gun_loadouts["axis"]["loadoutEquipment"] = "specialty_null";
level.gun_loadouts["axis"]["loadoutOffhand"] = "none";
level.gun_loadouts["axis"]["loadoutPerk1"] = "specialty_null";
level.gun_loadouts["axis"]["loadoutPerk2"] = "specialty_null";
level.gun_loadouts["axis"]["loadoutPerk3"] = "specialty_null";
// FFA games don't have teams, but players are allowed to choose team on the way in
// just for character model and announcer voice variety. Same loadout for both.
level.gun_loadouts["allies"] = level.gun_loadouts["axis"];
}
+1
View File
@@ -0,0 +1 @@
"MPUI_GUNGAME"
+839
View File
@@ -0,0 +1,839 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
main()
{
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerTimeLimitDvar( level.gameType, 10 );
setOverrideWatchDvar( "scorelimit", 0 );
registerRoundLimitDvar( level.gameType, 1 );
registerWinLimitDvar( level.gameType, 1 );
registerNumLivesDvar( level.gameType, 0 );
registerHalfTimeDvar( level.gameType, 0 );
setSpecialLoadouts();
level.teamBased = true;
// don't sit there waiting for both teams to contain players,
// as everyone starts a survivor
level.prematchWaitForTeams = false;
level.onPrecacheGameType = ::onPrecacheGameType;
level.onStartGameType = ::onStartGameType;
level.onSpawnPlayer = ::onSpawnPlayer;
level.getSpawnPoint = ::getSpawnPoint;
level.onPlayerKilled = ::onPlayerKilled;
level.onTimeLimit = ::onTimeLimit;
level.infect_perks = [];
level.infect_perks[level.infect_perks.size] = "specialty_marathon";
level.infect_perks[level.infect_perks.size] = "specialty_fastreload";
level.infect_perks[level.infect_perks.size] = "specialty_scavenger";
level.infect_perks[level.infect_perks.size] = "specialty_fastmantle";
level.infect_perks[level.infect_perks.size] = "specialty_quickdraw";
level.infect_perks[level.infect_perks.size] = "specialty_lightweight";
level.infect_perks[level.infect_perks.size] = "specialty_hardline";
level.infect_perks[level.infect_perks.size] = "specialty_coldblooded";
level.infect_perks[level.infect_perks.size] = "specialty_explosivedamage";
level.infect_perks[level.infect_perks.size] = "specialty_bombsquad";
level.infect_perks[level.infect_perks.size] = "specialty_bulletaccuracy";
level.infect_perks[level.infect_perks.size] = "specialty_localjammer";
level.infect_perks[level.infect_perks.size] = "specialty_quieter";
level.determineWinningTeam = ::determineWinningTeam;
}
determineWinningTeam()
{
// if the game's still going on, the allies are winning since they're still alive
return "allies";
}
onPrecacheGameType()
{
precachestring( &"MP_CONSCRIPTION_STARTS_IN" );
}
onStartGameType()
{
setclientnamemode( "auto_change" );
setObjectiveText( "allies", &"OBJECTIVES_INFECT" );
setObjectiveText( "axis", &"OBJECTIVES_INFECT" );
setObjectiveScoreText( "allies", &"OBJECTIVES_INFECT_SCORE" );
setObjectiveScoreText( "axis", &"OBJECTIVES_INFECT_SCORE" );
setObjectiveHintText( "allies", &"OBJECTIVES_INFECT_HINT" );
setObjectiveHintText( "axis", &"OBJECTIVES_INFECT_HINT" );
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
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 = [];
maps\mp\gametypes\_gameobjects::main(allowed);
maps\mp\gametypes\_rank::registerScoreInfo( "firstblood", 0 );
maps\mp\gametypes\_rank::registerScoreInfo( "first_draft", 350 );
maps\mp\gametypes\_rank::registerScoreInfo( "final_rogue", 200 );
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "draft_rogue", 200 );
maps\mp\gametypes\_rank::registerScoreInfo( "survivor", 50 );
level.QuickMessageToAll = true;
level.blockWeaponDrops = true;
level.infect_allowSuicide = false;
SetDvar( "ui_allow_teamchange", 0 );
SetDvar( "scr_teambalance", 0 );
level.infect_timerDisplay = createServerTimer( "objective", 1.4 );
level.infect_timerDisplay setPoint( "TOPLEFT", "TOPLEFT", 115, 5 );
level.infect_timerDisplay.label = &"MP_DRAFT_STARTS_IN";
level.infect_timerDisplay.alpha = 0;
level.infect_timerDisplay.archived = false;
level.infect_timerDisplay.hideWhenInMenu = true;
level.infect_choseFirstInfected = false;
level.infect_choosingFirstInfected = false;
level.infect_awardedFinalSurvivor = false;
level.infect_countdownInProgress = false;
level.infect_teamScores["axis"] = 0;
level.infect_teamScores["allies"] = 0;
level.infect_players = [];
level thread onPlayerConnect();
level thread watchInfectForfeit();
}
onPlayerConnect()
{
for (;;)
{
level waittill( "connected", player );
player.infect_firstSpawn = true;
player.infected_Rejoined = false;
player.infect_JoinedAtStart = true;
if( gameFlag( "prematch_done" ) )
{
player.infect_JoinedAtStart = false;
}
// infected who quit and rejoined same game
if( IsDefined( level.infect_players[player.name] ) )
{
player.infected_Rejoined = true;
}
}
}
getSpawnPoint()
{
// first time here?
if ( self.infect_firstSpawn )
{
self.infect_firstSpawn = false;
// everyone is a gamemode class in infect, no class selection
self.pers["class"] = "gamemode";
self.pers["lastClass"] = "";
self.class = self.pers["class"];
self.lastClass = self.pers["lastClass"];
// survivors are allies
teamChoice = "allies";
// everyone starts as survivors, unless an infected quit and rejoined same game
if( self.infected_Rejoined )
{
teamChoice = "axis";
}
self maps\mp\gametypes\_menus::addToTeam( teamChoice, true );
thread onPlayerDisconnect();
}
if ( level.inGracePeriod )
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_tdm_spawn" );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
}
else
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( self.pers["team"] );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
}
return spawnPoint;
}
onSpawnPlayer()
{
self.teamChangedThisFrame = undefined;
self.infect_spawnPos = self.origin;
// resynch teams
updateTeamScores();
// let the first spawned player kick this off
if ( !level.infect_choosingFirstInfected )
{
level.infect_choosingFirstInfected = true;
level thread chooseFirstInfected();
}
// infected who quit and rejoined same game?
if( self.infected_Rejoined )
{
self.infect_rejoined = undefined;
// stop initial infect countdown (if quit/join player was initial and a new coutdown is underway)
if ( !level.infect_allowSuicide )
{
level notify( "infect_stopCountdown" );
level.infect_choseFirstInfected = true;
level.infect_allowSuicide = true;
foreach( player in level.players )
{
if ( isDefined( player.infect_isBeingChosen ) )
player.infect_isBeingChosen = undefined;
}
}
// if an initial was already chosen while they were gone and they are still initial, set them to normal
foreach( player in level.players )
{
if ( isDefined( player.isInitialInfected ) )
player thread setInitialToNormalInfected();
}
// if they're the only infected, then set them as initial infected
if ( level.infect_teamScores["axis"] == 1 )
self.isInitialInfected = true;
}
// onSpawnPlayer() is called before giveLoadout()
// set self.pers["gamemodeLoadout"] for giveLoadout() to use
if ( isDefined( self.isInitialInfected ) )
self.pers["gamemodeLoadout"] = level.infect_loadouts["axis_initial"];
else
self.pers["gamemodeLoadout"] = level.infect_loadouts[self.pers["team"]];
self thread onSpawnFinished();
level notify ( "spawned_player" );
}
onSpawnFinished()
{
self endon( "death" );
self endon( "disconnect" );
self waittill( "spawned_player" );
if ( self.pers["team"] == "axis" )
thread setInfectedMsg();
wait 0.05;
if ( self.pers["team"] == "axis" )
maps\mp\killstreaks\_killstreaks::clearKillstreaks();
if ( matchMakingGame() )
{
foreach ( player in level.infect_perks )
{
if ( _hasPerk( player ) )
{
var_2 = tablelookup( "mp/perktable.csv", 1, player, 8 );
if ( !_hasPerk( var_2 ) )
_setPerk( var_2, 0 );
}
}
if ( self.pers["team"] == "allies" ) // SURVIVORS
{
if ( !_hasPerk( "specialty_scavenger" ) )
{
_setPerk( "specialty_scavenger", 0 );
var_2 = tablelookup( "mp/perktable.csv", 1, "specialty_scavenger", 8 );
if ( !_hasPerk( var_2 ) )
_setPerk( var_2, 0 );
}
}
else if ( self.pers["team"] == "axis" ) // INFECTED
{
if ( isDefined( self.isInitialInfected ) && !_hasPerk( "specialty_marathon" ) )
{
_setPerk( "specialty_marathon", 0 );
var_2 = tablelookup( "mp/perktable.csv", 1, "specialty_marathon", 8 );
if ( !_hasPerk( var_2 ) )
_setPerk( var_2, 0 );
}
if ( !_hasPerk( "specialty_falldamage" ) )
_setPerk( "specialty_falldamage", 0 );
if ( _hasPerk( "specialty_marathon" ) )
{
_setPerk( "specialty_lightweight", 0 );
self setMoveSpeedScale( 1.2 );
}
}
}
}
setInfectedMsg()
{
if ( isDefined( self.isInitialInfected ) )
{
thread maps\mp\gametypes\_rank::xpEventPopup( &"SPLASHES_FIRST_MERCENARY", ( 1, 0, 0 ), 0.3 );
}
else if ( isDefined( self.changingToRegularInfected ) )
{
self.changingToRegularInfected = undefined;
if ( isDefined( self.changingToRegularInfectedByKill ) )
{
self.changingToRegularInfectedByKill = undefined;
thread maps\mp\gametypes\_rank::xpEventPopup( &"SPLASHES_FIRSTBLOOD" );
maps\mp\gametypes\_gamescore::givePlayerScore( "first_draft", self );
thread maps\mp\gametypes\_rank::giveRankXP( "first_draft" );
}
}
else
{
thread maps\mp\gametypes\_rank::xpEventPopup( &"SPLASHES_DRAFTED", ( 1, 0, 0 ), 0.3 );
}
}
chooseFirstInfected()
{
level endon( "game_ended" );
level endon( "infect_stopCountdown" );
level.infect_allowSuicide = false;
gameFlagWait( "prematch_done" );
level.infect_timerDisplay.label = &"MP_DRAFT_STARTS_IN";
level.infect_timerDisplay setTimer( 15 );
level.infect_timerDisplay.alpha = 1;
maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( 15.0 );
level.infect_timerDisplay.alpha = 0;
possibleInfected = [];
foreach( player in level.players )
{
if ( player.team == "spectator" )
continue;
if ( !player.hasSpawned )
continue;
possibleInfected[possibleInfected.size] = player;
}
firstInfectedPlayer = possibleInfected[ randomInt( possibleInfected.size ) ];
firstInfectedPlayer setFirstInfected( true );
}
setFirstInfected( wasChosen )
{
self endon( "disconnect" );
if ( wasChosen )
self.infect_isBeingChosen = true;
// wait alive
while( !isReallyAlive( self ) || self isUsingRemote() )
wait( 0.05 );
// remove placement item if carrying
if ( IsDefined( self.isCarrying ) && self.isCarrying == true )
{
self notify( "force_cancel_placement" );
wait( 0.05 );
}
// not while mantling
while ( self IsMantling() )
wait( 0.05 );
// not while in air
while ( !self isOnGround() && !self IsOnLadder() )
wait( 0.05 );
// move to other team
if ( wasChosen )
{
self maps\mp\gametypes\_menus::addToTeam( "axis" );
level.infect_choseFirstInfected = true;
self.infect_isBeingChosen = undefined;
// resynch teams
level notify( "update_game_time" );
updateTeamScores();
// allow suicides now
level.infect_allowSuicide = true;
}
// store initial
self.isInitialInfected = true;
// set the gamemodeloadout for giveLoadout() to use
self.pers["gamemodeLoadout"] = level.infect_loadouts["axis_initial"];
// remove old TI if it exists
if ( isDefined ( self.setSpawnpoint ) )
self maps\mp\perks\_perkfunctions::deleteTI( self.setSpawnpoint );
// set faux TI to respawn in place
spawnPoint = spawn( "script_model", self.origin );
spawnPoint.angles = self.angles;
spawnPoint.playerSpawnPos = self.origin;
spawnPoint.notTI = true;
self.setSpawnPoint = spawnPoint;
// faux spawn
self notify( "faux_spawn" );
self.faux_spawn_stance = self getStance();
thread maps\mp\gametypes\_playerlogic::spawnPlayer( true );
// store infected
if ( wasChosen )
level.infect_players[self.name] = true;
// tell the world!
thread teamPlayerCardSplash( "callout_first_mercenary", self );
playSoundOnPlayers( "mp_enemy_obj_captured" );
}
setInitialToNormalInfected( gotKill )
{
level endon( "game_ended" );
self.isInitialInfected = undefined;
self.changingToRegularInfected = true;
if ( isDefined( gotKill ) )
self.changingToRegularInfectedByKill = true;
// wait till we spawn if we died at the same time
while ( !isReallyAlive( self ) )
wait( 0.05 );
// remove placement item if carrying
if ( IsDefined( self.isCarrying ) && self.isCarrying == true )
{
self notify( "force_cancel_placement" );
wait( 0.05 );
}
// not while mantling
while ( self IsMantling() )
wait( 0.05 );
// not while in air
while ( !self isOnGround() )
wait( 0.05 );
// Gotta check again, more time has passed, wait till we spawn if we died at the same time
while ( !isReallyAlive( self ) )
wait( 0.05 );
// set the gamemodeloadout for giveLoadout() to use
self.pers["gamemodeLoadout"] = level.infect_loadouts["axis"];
// remove old TI if it exists
if ( isDefined ( self.setSpawnpoint ) )
self maps\mp\perks\_perkfunctions::deleteTI( self.setSpawnpoint );
// set faux TI to respawn in place
spawnPoint = spawn( "script_model", self.origin );
spawnPoint.angles = self.angles;
spawnPoint.playerSpawnPos = self.origin;
spawnPoint.notTI = true;
self.setSpawnPoint = spawnPoint;
// faux spawn
self notify( "faux_spawn" );
self.faux_spawn_stance = self getStance();
thread maps\mp\gametypes\_playerlogic::spawnPlayer( true );
}
onPlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
{
processKill = false;
wasSuicide = false;
if ( self.team == "allies" && isDefined( attacker ) )
{
if ( isPlayer( attacker ) && attacker != self )
processKill = true;
else if ( level.infect_allowSuicide && ( attacker == self || !isPlayer( attacker ) ) )
{
processKill = true;
wasSuicide = true;
}
}
if ( processKill )
{
// track team change for this frame (so explosives can't team kill, now that they changed teams)
self.teamChangedThisFrame = true;
// move victim to infected
self maps\mp\gametypes\_menus::addToTeam( "axis" );
// resynch teams
updateTeamScores();
// store infected
level.infect_players[self.name] = true;
if ( wasSuicide )
{
// set initial infected to regular infected since a survivor just commited suicide and initial infected is no longer alone
if ( level.infect_teamScores["axis"] > 1 )
{
foreach( player in level.players )
{
if ( isDefined( player.isInitialInfected ) )
player thread setInitialToNormalInfected();
}
}
}
else
{
// set attacker to regular infected if they were the first infected
if ( isDefined( attacker.isInitialInfected ) )
attacker thread setInitialToNormalInfected( true );
else
{
// regular attacker reward
attacker thread maps\mp\gametypes\_rank::xpEventPopup( &"SPLASHES_DRAFTED" );
maps\mp\gametypes\_gamescore::givePlayerScore( "draft_rogue", attacker, self, true );
attacker thread maps\mp\gametypes\_rank::giveRankXP( "draft_rogue" );
}
}
// generic messages/sounds, and reward survivors
if ( level.infect_teamScores["allies"] > 1 )
{
playSoundOnPlayers( "mp_enemy_obj_captured", "allies" );
playSoundOnPlayers( "mp_war_objective_taken", "axis" );
thread teamPlayerCardSplash( "callout_got_drafted", self, "allies" );
if ( !wasSuicide )
{
thread teamPlayerCardSplash( "callout_drafted_rogue", attacker, "axis" );
foreach ( player in level.players )
{
if( !isReallyAlive( player ) || self.sessionstate == "spectator" )
continue;
if ( player.team == "allies" && player != self && distance( player.infect_spawnPos, player.origin ) > 32 )
{
player thread maps\mp\gametypes\_rank::xpEventPopup( &"SPLASHES_SURVIVOR" );
maps\mp\gametypes\_gamescore::givePlayerScore( "survivor", player, undefined, true );
player thread maps\mp\gametypes\_rank::giveRankXP( "survivor" );
}
}
}
}
// inform/reward last
else if ( level.infect_teamScores["allies"] == 1 )
{
onFinalSurvivor();
}
// infected win
else if ( level.infect_teamScores["allies"] == 0 )
{
onSurvivorsEliminated();
}
}
}
onFinalSurvivor()
{
playSoundOnPlayers( "mp_obj_captured" );
foreach ( player in level.players )
{
if( !isDefined(player) )
continue;
if ( player.team == "allies" )
{
player thread maps\mp\gametypes\_rank::xpEventPopup( &"SPLASHES_FINAL_ROGUE" );
if ( !level.infect_awardedFinalSurvivor )
{
if ( player.gameModeJoinedAtStart && isDefined( player.infect_spawnPos ) && distance( player.infect_spawnPos, player.origin ) > 32 )
{
maps\mp\gametypes\_gamescore::givePlayerScore( "final_rogue", player, undefined, true );
player thread maps\mp\gametypes\_rank::giveRankXP( "final_rogue" );
}
level.infect_awardedFinalSurvivor = true;
}
thread teamplayercardsplash( "callout_final_rogue", player );
if (matchMakingGame() )
level thread finalsurvivoruav( player );
break;
}
}
}
finalSurvivorUAV( finalPlayer )
{
level endon( "game_ended" );
finalPlayer endon( "disconnect" );
finalPlayer endon( "eliminated" );
level endon( "infect_lateJoiner" );
level thread endUAVonLateJoiner( finalPlayer );
removeUAV = false;
level.radarMode["axis"] = "normal_radar";
foreach ( player in level.players )
{
if ( player.team == "axis" )
player.radarMode = "normal_radar";
}
//setTeamRadarStrength( "axis", 1 );
while( true )
{
prevPos = finalPlayer.origin;
wait( 4 );
if ( removeUAV )
{
setTeamRadar( "axis", 0 );
removeUAV = false;
}
wait( 6 );
if ( distance( prevPos, finalPlayer.origin ) < 200 )
{
setTeamRadar( "axis", 1 );
removeUAV = true;
foreach ( player in level.players )
player playLocalSound( "recondrone_tag" );
}
}
}
endUAVonLateJoiner( finalPlayer )
{
level endon( "game_ended" );
finalPlayer endon( "disconnect" );
finalPlayer endon( "eliminated" );
while( true )
{
if ( level.infect_teamScores["allies"] > 1 )
{
level notify( "infect_lateJoiner" );
wait( 0.05 );
setTeamRadar( "axis", 0 );
break;
}
wait( 0.05 );
}
}
onPlayerDisconnect()
{
level endon( "game_ended" );
self endon( "eliminated" );
self waittill( "disconnect" );
// resynch teams
updateTeamScores();
// team actions or win condition necessary?
if ( isDefined( self.infect_isBeingChosen ) || level.infect_choseFirstInfected )
{
if ( level.infect_teamScores["axis"] && level.infect_teamScores["allies"] )
{
if ( self.team == "allies" && level.infect_teamScores["allies"] == 1 )
{
// final survivor was abandoned: inform, reward, call uav
onFinalSurvivor();
}
else if ( self.team == "axis" && level.infect_teamScores["axis"] == 1 )
{
// final infected was abandoned: inform, set initial
foreach ( player in level.players )
{
if ( player != self && player.team == "axis" )
player setFirstInfected( false );
}
}
}
else if ( level.infect_teamScores["allies"] == 0 )
{
// no more survivors, infected win
onSurvivorsEliminated();
}
else if ( level.infect_teamScores["axis"] == 0 )
{
if ( level.infect_teamScores["allies"] == 1 )
{
// last survivor wins
level.finalKillCam_winner = "allies";
level thread maps\mp\gametypes\_gamelogic::endGame( "allies", game[ "end_reason" ][ "axis_eliminated" ] );
}
else if ( level.infect_teamScores["allies"] > 1 )
{
// pick a new infected and keep the game going
level.infect_choseFirstInfected = false;
level thread chooseFirstInfected();
}
}
}
// clear this regardless on the way out
self.isInitialInfected = undefined;
}
watchInfectForfeit()
{
level endon( "game_ended" );
level.forfeitInProgress = true;
for (;;)
{
if ( !isDefined( level.forfeitInProgress ) )
level.forfeitInProgress = true;
wait 0.05;
}
}
onDeadEvent( team )
{
// override default to supress the normal game ending process
return;
}
onTimeLimit()
{
// survivors win
level.finalKillCam_winner = "allies";
level thread maps\mp\gametypes\_gamelogic::endGame( "allies", game[ "end_reason" ][ "time_limit_reached" ] );
}
onSurvivorsEliminated()
{
// infected win
level.finalKillCam_winner = "axis";
level thread maps\mp\gametypes\_gamelogic::endGame( "axis", game[ "end_reason" ][ "allies_eliminated" ] );
}
getTeamSize( team )
{
size = 0;
foreach( player in level.players )
{
// Make sure we don't check for spectators
// Also need to check for if they are in killcam, because player session states are set to spectator when killcam happens
if ( player.sessionstate == "spectator" && !player.spectatekillcam )
continue;
if( player.team == team )
size++;
}
return size;
}
updateTeamScores()
{
// survivors
level.infect_teamScores["allies"] = getTeamSize( "allies" );
game["teamScores"]["allies"] = level.infect_teamScores["allies"];
setTeamScore( "allies", level.infect_teamScores["allies"] );
// infected
level.infect_teamScores["axis"] = getTeamSize( "axis" );
game["teamScores"]["axis"] = level.infect_teamScores["axis"];
setTeamScore( "axis", level.infect_teamScores["axis"] );
}
setSpecialLoadouts()
{
level.infect_loadouts["axis"]["loadoutPrimary"] = "throwingknife";
level.infect_loadouts["axis"]["loadoutPrimaryAttachment"] = "none";
level.infect_loadouts["axis"]["loadoutPrimaryAttachment2"] = "none";
level.infect_loadouts["axis"]["loadoutPrimaryCamo"] = "none";
level.infect_loadouts["axis"]["loadoutSecondary"] = "none";
level.infect_loadouts["axis"]["loadoutSecondaryAttachment"] = "none";
level.infect_loadouts["axis"]["loadoutSecondaryAttachment2"] = "none";
level.infect_loadouts["axis"]["loadoutSecondaryCamo"] = "none";
level.infect_loadouts["axis"]["loadoutEquipment"] = "throwingknife_mp";
level.infect_loadouts["axis"]["loadoutOffhand"] = "none";
level.infect_loadouts["axis"]["loadoutPerk1"] = "specialty_marathon";
level.infect_loadouts["axis"]["loadoutPerk2"] = "specialty_lightweight";
level.infect_loadouts["axis"]["loadoutPerk3"] = "specialty_heartbreaker";
level.infect_loadouts["axis"]["loadoutKillstreak1"] = "none";
level.infect_loadouts["axis"]["loadoutKillstreak2"] = "none";
level.infect_loadouts["axis"]["loadoutKillstreak3"] = "none";
level.infect_loadouts["axis"]["loadoutDeathstreak"] = "specialty_grenadepulldeath";
level.infect_loadouts["axis_initial"]["loadoutPrimary"] = "scar";
level.infect_loadouts["axis_initial"]["loadoutPrimaryAttachment"] = "reflex";
level.infect_loadouts["axis_initial"]["loadoutPrimaryAttachment2"] = "xmags";
level.infect_loadouts["axis_initial"]["loadoutPrimaryCamo"] = "none";
level.infect_loadouts["axis_initial"]["loadoutSecondary"] = "none";
level.infect_loadouts["axis_initial"]["loadoutSecondaryAttachment"] = "none";
level.infect_loadouts["axis_initial"]["loadoutSecondaryAttachment2"] = "none";
level.infect_loadouts["axis_initial"]["loadoutSecondaryCamo"] = "none";
level.infect_loadouts["axis_initial"]["loadoutEquipment"] = "throwingknife_mp";
level.infect_loadouts["axis_initial"]["loadoutOffhand"] = "none";
level.infect_loadouts["axis_initial"]["loadoutPerk1"] = "specialty_marathon";
level.infect_loadouts["axis_initial"]["loadoutPerk2"] = "specialty_lightweight";
level.infect_loadouts["axis_initial"]["loadoutPerk3"] = "specialty_bulletaccuracy";
level.infect_loadouts["axis_initial"]["loadoutKillstreak1"] = "none";
level.infect_loadouts["axis_initial"]["loadoutKillstreak2"] = "none";
level.infect_loadouts["axis_initial"]["loadoutKillstreak3"] = "none";
level.infect_loadouts["axis_initial"]["loadoutDeathstreak"] = "specialty_grenadepulldeath";
level.infect_loadouts["allies"]["loadoutPrimary"] = "spas12";
level.infect_loadouts["allies"]["loadoutPrimaryAttachment"] = "xmags";
level.infect_loadouts["allies"]["loadoutPrimaryAttachment2"] = "grip";
level.infect_loadouts["allies"]["loadoutPrimaryCamo"] = "none";
level.infect_loadouts["allies"]["loadoutSecondary"] = "pp2000";
level.infect_loadouts["allies"]["loadoutSecondaryAttachment"] = "reflex";
level.infect_loadouts["allies"]["loadoutSecondaryAttachment2"] = "xmags";
level.infect_loadouts["allies"]["loadoutSecondaryCamo"] = "none";
level.infect_loadouts["allies"]["loadoutEquipment"] = "claymore_mp";
level.infect_loadouts["allies"]["loadoutOffhand"] = "flash_grenade";
level.infect_loadouts["allies"]["loadoutPerk1"] = "specialty_scavenger";
level.infect_loadouts["allies"]["loadoutPerk2"] = "specialty_lightweight";
level.infect_loadouts["allies"]["loadoutPerk3"] = "specialty_heartbreaker";
level.infect_loadouts["allies"]["loadoutDeathstreak"] = "specialty_null";
}
@@ -0,0 +1 @@
"MPUI_INF"