Bump r3775
This commit is contained in:
parent
329e500bec
commit
273381fac2
@ -1,2 +1,2 @@
|
|||||||
@echo off
|
@echo off
|
||||||
.\plutonium.exe -install-dir "%cd%" -update-only
|
.\plutonium.exe -install-dir "E:\Games\Plutonium\Plutonium" -update-only
|
BIN
bin/VibeCheck.exe
Normal file
BIN
bin/VibeCheck.exe
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
bin/steam_api64.dll
Normal file
BIN
bin/steam_api64.dll
Normal file
Binary file not shown.
@ -1 +1 @@
|
|||||||
{"revision":3641,"launchTarget":"bin/plutonium-launcher-win32.exe"}
|
{"revision":3755,"launchTarget":"bin/plutonium-launcher-win32.exe"}
|
@ -1,96 +1,819 @@
|
|||||||
|
#include common_scripts\utility;
|
||||||
|
#include maps\mp\_utility;
|
||||||
|
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
// always allow team change
|
if ( GetDvarInt( "scr_disablePlutoniumFixes" ) )
|
||||||
replaceFunc( maps\mp\gametypes\_serversettings::init, ::serverSettings );
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isDedicated() )
|
||||||
|
{
|
||||||
// never forfeit
|
// never forfeit
|
||||||
replaceFunc( maps\mp\gametypes\_globallogic::updateGameEvents, ::updateGameEvents );
|
replaceFunc( GetFunction( "maps/mp/gametypes/_globallogic", "checkforforfeit" ), ::neverForfeit, -1 );
|
||||||
|
|
||||||
|
// fix team change exploit
|
||||||
|
replaceFunc( GetFunction( "maps/mp/gametypes/_globallogic_player", "spectate_player_watcher" ), ::spectate_player_watcher_fix, -1 );
|
||||||
|
|
||||||
|
// fix menuresponse exploits
|
||||||
|
replaceFunc( GetFunction( "maps/mp/gametypes/_globallogic", "forceend" ), ::noop, -1 );
|
||||||
|
replaceFunc( GetFunction( "maps/mp/gametypes/_globallogic", "gamehistoryplayerquit" ), ::noop, -1 );
|
||||||
|
replaceFunc( GetFunction( "maps/mp/gametypes/_globallogic", "killserverpc" ), ::noop, -1 );
|
||||||
|
|
||||||
|
// use item restrictions
|
||||||
|
if ( getdvarint( "scr_useItemRestrictions" ) )
|
||||||
|
{
|
||||||
|
replaceFunc( GetFunction( "maps/mp/gametypes/_class", "giveloadout" ), ::giveloadout_override, -1 );
|
||||||
|
replaceFunc( GetFunction( "maps/mp/gametypes/_class", "getkillstreakindex" ), ::getkillstreakindex_override, -1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
serverSettings()
|
init()
|
||||||
{
|
{
|
||||||
level.hostname = GetDvar( "sv_hostname" );
|
if ( GetDvarInt( "scr_disablePlutoniumFixes" ) )
|
||||||
if ( level.hostname == "" )
|
|
||||||
{
|
{
|
||||||
level.hostname = "CoDHost";
|
return;
|
||||||
}
|
}
|
||||||
SetDvar( "sv_hostname", level.hostname );
|
|
||||||
SetDvar( "ui_hostname", level.hostname );
|
|
||||||
MakeDvarServerInfo( "ui_hostname", "CoDHost" );
|
|
||||||
|
|
||||||
level.motd = GetDvar( "scr_motd" );
|
if ( isDedicated() )
|
||||||
if ( level.motd == "" )
|
|
||||||
{
|
{
|
||||||
level.motd = "";
|
// allow team changing on dedis (gts)
|
||||||
}
|
level.allow_teamchange = getgametypesetting( "allowInGameTeamChange" ) + "";
|
||||||
SetDvar( "scr_motd", level.motd );
|
|
||||||
SetDvar( "ui_motd", level.motd );
|
|
||||||
MakeDvarServerInfo( "ui_motd", "" );
|
|
||||||
|
|
||||||
level.allowvote = GetDvar( "g_allowVote" );
|
|
||||||
if ( level.allowvote == "" )
|
|
||||||
{
|
|
||||||
level.allowvote = "1";
|
|
||||||
}
|
|
||||||
SetDvar( "g_allowvote", level.allowvote );
|
|
||||||
SetDvar( "ui_allowvote", level.allowvote );
|
|
||||||
MakeDvarServerInfo( "ui_allowvote", "1" );
|
|
||||||
|
|
||||||
level.allow_teamchange = "1";
|
|
||||||
SetDvar( "ui_allow_teamchange", level.allow_teamchange );
|
SetDvar( "ui_allow_teamchange", level.allow_teamchange );
|
||||||
|
|
||||||
level.friendlyfire = getgametypesetting( "friendlyfiretype" );
|
// readd teambalancing
|
||||||
SetDvar( "ui_friendlyfire", level.friendlyfire );
|
if ( level.teambased )
|
||||||
MakeDvarServerInfo( "ui_friendlyfire", "0" );
|
|
||||||
|
|
||||||
if ( GetDvar( "scr_mapsize" ) == "" )
|
|
||||||
{
|
{
|
||||||
SetDvar( "scr_mapsize", "64" );
|
level thread updateTeamBalance();
|
||||||
}
|
}
|
||||||
else if ( GetDvarFloat( "scr_mapsize" ) >= 64 )
|
|
||||||
{
|
|
||||||
SetDvar( "scr_mapsize", "64" );
|
|
||||||
}
|
|
||||||
else if ( GetDvarFloat( "scr_mapsize" ) >= 32 )
|
|
||||||
{
|
|
||||||
SetDvar( "scr_mapsize", "32" );
|
|
||||||
}
|
|
||||||
else if ( GetDvarFloat( "scr_mapsize" ) >= 16 )
|
|
||||||
{
|
|
||||||
SetDvar( "scr_mapsize", "16" );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetDvar( "scr_mapsize", "8" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
level.mapsize = GetDvarFloat( "scr_mapsize" );
|
level thread on_player_connect();
|
||||||
maps\mp\gametypes\_serversettings::constraingametype( GetDvar( "g_gametype" ) );
|
}
|
||||||
maps\mp\gametypes\_serversettings::constrainmapsize( level.mapsize );
|
|
||||||
|
on_player_connect()
|
||||||
|
{
|
||||||
|
for ( ;; )
|
||||||
|
{
|
||||||
|
level waittill( "connected", player );
|
||||||
|
player thread player_connected();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
player_connected()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
|
||||||
|
if ( isDedicated() )
|
||||||
|
{
|
||||||
|
// fix max allocation exploit
|
||||||
|
if ( !self istestclient() )
|
||||||
|
{
|
||||||
|
self thread fix_max_allocation_exploit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self thread watch_on_throw_grenade();
|
||||||
|
}
|
||||||
|
|
||||||
|
watch_on_throw_grenade()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
|
||||||
for ( ;; )
|
for ( ;; )
|
||||||
{
|
{
|
||||||
maps\mp\gametypes\_serversettings::updateserversettings();
|
self waittill( "grenade_fire", grenade, weaponName );
|
||||||
wait 5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateGameEvents()
|
// stop grenade team change exploit
|
||||||
|
if ( isDedicated() )
|
||||||
{
|
{
|
||||||
if ( !level.playerQueuedRespawn && !level.numLives && !level.inOverTime )
|
grenade thread deleteOnOwnerTeamChange( self );
|
||||||
return;
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( level.inGracePeriod )
|
fix_max_allocation_exploit()
|
||||||
return;
|
|
||||||
|
|
||||||
if ( level.playerQueuedRespawn )
|
|
||||||
{
|
{
|
||||||
maps\mp\gametypes\_globallogic::doSpawnQueueUpdates();
|
self endon( "disconnect" );
|
||||||
|
|
||||||
|
this_class = "";
|
||||||
|
|
||||||
|
for ( ;; )
|
||||||
|
{
|
||||||
|
wait 0.05;
|
||||||
|
|
||||||
|
if ( !isDefined( self.class ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( maps\mp\gametypes\_globallogic::doDeadEventUpdates() )
|
if ( this_class == self.class )
|
||||||
return;
|
{
|
||||||
|
continue;
|
||||||
if ( maps\mp\gametypes\_globallogic::doOneLeftEventUpdates() )
|
}
|
||||||
return;
|
|
||||||
|
this_class = self.class;
|
||||||
|
|
||||||
|
if ( !issubstr( self.class, "CLASS_CUSTOM" ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
class_num = int( self.class[self.class.size - 1] ) - 1;
|
||||||
|
|
||||||
|
if ( self GetLoadoutAllocation( class_num ) <= level.maxAllocation )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.class = level.defaultclass;
|
||||||
|
self.pers["class"] = level.defaultclass;
|
||||||
|
|
||||||
|
if ( !isAlive( self ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
self suicide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteOnOwnerTeamChange( owner )
|
||||||
|
{
|
||||||
|
self endon( "death" );
|
||||||
|
|
||||||
|
owner waittill_any( "disconnect", "joined_team", "joined_spectators" );
|
||||||
|
|
||||||
|
self delete ();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTeamBalance()
|
||||||
|
{
|
||||||
|
level thread [[ GetFunction( "maps/mp/teams/_teams", "updateteambalancedvar" ) ]]();
|
||||||
|
|
||||||
|
wait .15;
|
||||||
|
|
||||||
|
if ( level.teamBalance && isRoundBased() && level.numlives )
|
||||||
|
{
|
||||||
|
if ( isDefined( game["BalanceTeamsNextRound"] ) )
|
||||||
|
{
|
||||||
|
iPrintLnbold( &"MP_AUTOBALANCE_NEXT_ROUND" );
|
||||||
|
}
|
||||||
|
|
||||||
|
level waittill( "game_ended" );
|
||||||
|
wait 1;
|
||||||
|
|
||||||
|
if ( isDefined( game["BalanceTeamsNextRound"] ) )
|
||||||
|
{
|
||||||
|
level balanceTeams();
|
||||||
|
game["BalanceTeamsNextRound"] = undefined;
|
||||||
|
}
|
||||||
|
else if ( needsTeamBalance() )
|
||||||
|
{
|
||||||
|
game["BalanceTeamsNextRound"] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
level endon ( "game_ended" );
|
||||||
|
|
||||||
|
for ( ;; )
|
||||||
|
{
|
||||||
|
if ( level.teamBalance > 0 )
|
||||||
|
{
|
||||||
|
if ( needsTeamBalance() )
|
||||||
|
{
|
||||||
|
iPrintLnBold( &"MP_AUTOBALANCE_SECONDS", 15 );
|
||||||
|
wait 15.0;
|
||||||
|
|
||||||
|
if ( needsTeamBalance() )
|
||||||
|
{
|
||||||
|
level balanceTeams();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wait 59.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
wait 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getBinaryTeamData()
|
||||||
|
{
|
||||||
|
allies = 0;
|
||||||
|
axis = 0;
|
||||||
|
|
||||||
|
for ( i = 0; i < level.players.size; i++ )
|
||||||
|
{
|
||||||
|
if ( !isdefined( level.players[i].pers["team"] ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( level.players[i].pers["team"] == "allies" )
|
||||||
|
{
|
||||||
|
allies++;
|
||||||
|
}
|
||||||
|
else if ( level.players[i].pers["team"] == "axis" )
|
||||||
|
{
|
||||||
|
axis++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
answer = spawnstruct();
|
||||||
|
answer.allies = allies;
|
||||||
|
answer.axis = axis;
|
||||||
|
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
getLeastPlayTimePlayerForTeam( team )
|
||||||
|
{
|
||||||
|
answer = undefined;
|
||||||
|
|
||||||
|
for ( i = 0; i < level.players.size; i++ )
|
||||||
|
{
|
||||||
|
if ( !isdefined( level.players[i].pers["team"] ) || !isdefined( level.players[i].pers["teamTime"] ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( level.players[i].pers["team"] != team )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isDefined( answer ) && level.players[i].pers["teamTime"] < answer.pers["teamTime"] )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
answer = level.players[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
needsTeamBalance()
|
||||||
|
{
|
||||||
|
if ( level.teamBalance <= 0 )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
teamdata = getBinaryTeamData();
|
||||||
|
|
||||||
|
if ( abs( teamdata.allies - teamdata.axis ) > level.teamBalance )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
balanceTeams()
|
||||||
|
{
|
||||||
|
iPrintLnBold( game["strings"]["autobalance"] );
|
||||||
|
|
||||||
|
while ( needsTeamBalance() )
|
||||||
|
{
|
||||||
|
teamdata = getBinaryTeamData();
|
||||||
|
|
||||||
|
switchto = "axis";
|
||||||
|
|
||||||
|
if ( teamdata.axis > teamdata.allies )
|
||||||
|
{
|
||||||
|
switchto = "allies";
|
||||||
|
}
|
||||||
|
|
||||||
|
switcher = getLeastPlayTimePlayerForTeam( getotherteam( switchto ) );
|
||||||
|
|
||||||
|
if ( !isDefined( switcher ) )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switcher changeTeam( switchto );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
changeTeam( team )
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
|
||||||
|
if ( team != self.pers["team"] )
|
||||||
|
{
|
||||||
|
if ( self.sessionstate == "playing" || self.sessionstate == "dead" )
|
||||||
|
{
|
||||||
|
self.switching_teams = true;
|
||||||
|
self.joining_team = team;
|
||||||
|
self.leaving_team = self.pers["team"];
|
||||||
|
self suicide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.pers["team"] = team;
|
||||||
|
self.team = team;
|
||||||
|
self.pers["class"] = undefined;
|
||||||
|
self.class = undefined;
|
||||||
|
self.pers["weapon"] = undefined;
|
||||||
|
self.pers["savedmodel"] = undefined;
|
||||||
|
|
||||||
|
self [[ GetFunction( "maps/mp/gametypes/_globallogic_ui", "updateObjectiveText" ) ]]();
|
||||||
|
self [[ GetFunction( "maps/mp/gametypes/_spectating", "setspectatepermissions" ) ]]();
|
||||||
|
|
||||||
|
if ( level.teamBased )
|
||||||
|
{
|
||||||
|
self.sessionteam = team;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self.sessionteam = "none";
|
||||||
|
self.ffateam = team;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !isAlive( self ) )
|
||||||
|
{
|
||||||
|
self.statusicon = "hud_status_dead";
|
||||||
|
}
|
||||||
|
|
||||||
|
self notify( "joined_team" );
|
||||||
|
level notify( "joined_team" );
|
||||||
|
self setclientscriptmainmenu( game["menu_class"] );
|
||||||
|
self openmenu( game["menu_class"] );
|
||||||
|
self notify( "end_respawn" );
|
||||||
|
}
|
||||||
|
|
||||||
|
noop()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
neverForfeit()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
spectate_player_watcher_fix()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
|
||||||
|
if ( !level.splitscreen && !level.hardcoremode && getdvarint( "scr_showperksonspawn" ) == 1 && game["state"] != "postgame" && !isdefined( self.perkhudelem ) )
|
||||||
|
{
|
||||||
|
if ( level.perksenabled == 1 )
|
||||||
|
{
|
||||||
|
self [[ GetFunction( "maps/mp/gametypes/_hud_util", "showperks" ) ]]();
|
||||||
|
}
|
||||||
|
|
||||||
|
self thread [[ GetFunction( "maps/mp/gametypes/_globallogic_ui", "hideloadoutaftertime" ) ]]( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
self.watchingactiveclient = 1;
|
||||||
|
self.waitingforplayerstext = undefined;
|
||||||
|
|
||||||
|
while ( true )
|
||||||
|
{
|
||||||
|
if ( self.pers["team"] != "spectator" || level.gameended )
|
||||||
|
{
|
||||||
|
self [[ GetFunction( "maps/mp/gametypes/_hud_message", "clearshoutcasterwaitingmessage" ) ]]();
|
||||||
|
|
||||||
|
if ( !level.inprematchperiod )
|
||||||
|
{
|
||||||
|
self freezecontrols( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
self.watchingactiveclient = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
for ( i = 0; i < level.players.size; i++ )
|
||||||
|
{
|
||||||
|
if ( level.players[i].team != "spectator" )
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( count > 0 )
|
||||||
|
{
|
||||||
|
if ( !self.watchingactiveclient )
|
||||||
|
{
|
||||||
|
self [[ GetFunction( "maps/mp/gametypes/_hud_message", "clearshoutcasterwaitingmessage" ) ]]();
|
||||||
|
self freezecontrols( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
self.watchingactiveclient = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( self.watchingactiveclient )
|
||||||
|
{
|
||||||
|
[[ level.onspawnspectator ]]();
|
||||||
|
self freezecontrols( 1 );
|
||||||
|
self [[ GetFunction( "maps/mp/gametypes/_hud_message", "setshoutcasterwaitingmessage" ) ]]();
|
||||||
|
}
|
||||||
|
|
||||||
|
self.watchingactiveclient = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
wait 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
restrict_attachments( weapon )
|
||||||
|
{
|
||||||
|
tokens = strTok( weapon, "+" );
|
||||||
|
|
||||||
|
if ( tokens.size <= 1 )
|
||||||
|
{
|
||||||
|
return weapon;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_weapon = tokens[ 0 ];
|
||||||
|
|
||||||
|
for ( i = 1; i < tokens.size; i++ )
|
||||||
|
{
|
||||||
|
if ( isitemrestricted( tokens[ i ] ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_weapon += "+" + tokens[ i ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return new_weapon;
|
||||||
|
}
|
||||||
|
|
||||||
|
getkillstreakindex_override( class, killstreaknum )
|
||||||
|
{
|
||||||
|
killstreaknum++;
|
||||||
|
killstreakstring = "killstreak" + killstreaknum;
|
||||||
|
answer = self getloadoutitem( class, killstreakstring );
|
||||||
|
|
||||||
|
if ( !isDefined( answer ) || answer < 0 )
|
||||||
|
{
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = level.tbl_killstreakdata[answer];
|
||||||
|
|
||||||
|
if ( !isdefined( data ) )
|
||||||
|
{
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isitemrestricted( data ) )
|
||||||
|
{
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
giveloadout_override( team, class )
|
||||||
|
{
|
||||||
|
pixbeginevent( "giveLoadout" );
|
||||||
|
self takeallweapons();
|
||||||
|
primaryindex = 0;
|
||||||
|
self.specialty = [];
|
||||||
|
self.killstreak = [];
|
||||||
|
primaryweapon = undefined;
|
||||||
|
self notify( "give_map" );
|
||||||
|
class_num_for_killstreaks = 0;
|
||||||
|
primaryweaponoptions = 0;
|
||||||
|
secondaryweaponoptions = 0;
|
||||||
|
playerrenderoptions = 0;
|
||||||
|
primarygrenadecount = 0;
|
||||||
|
iscustomclass = 0;
|
||||||
|
|
||||||
|
if ( issubstr( class, "CLASS_CUSTOM" ) )
|
||||||
|
{
|
||||||
|
pixbeginevent( "custom class" );
|
||||||
|
class_num = int( class[class.size - 1] ) - 1;
|
||||||
|
|
||||||
|
if ( -1 == class_num )
|
||||||
|
{
|
||||||
|
class_num = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.class_num = class_num;
|
||||||
|
self [[ GetFunction( "maps/mp/gametypes/_class", "reset_specialty_slots" ) ]]( class_num );
|
||||||
|
playerrenderoptions = self calcplayeroptions( class_num );
|
||||||
|
class_num_for_killstreaks = class_num;
|
||||||
|
iscustomclass = 1;
|
||||||
|
pixendevent();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pixbeginevent( "default class" );
|
||||||
|
assert( isdefined( self.pers["class"] ), "Player during spawn and loadout got no class!" );
|
||||||
|
class_num = level.classtoclassnum[class];
|
||||||
|
self.class_num = class_num;
|
||||||
|
pixendevent();
|
||||||
|
}
|
||||||
|
|
||||||
|
knifeweaponoptions = self calcweaponoptions( class_num, 2 );
|
||||||
|
|
||||||
|
if ( !isitemrestricted( "knife" ) )
|
||||||
|
{
|
||||||
|
self giveweapon( "knife_mp", 0, knifeweaponoptions );
|
||||||
|
}
|
||||||
|
|
||||||
|
self.specialty = self getloadoutperks( class_num );
|
||||||
|
|
||||||
|
for ( i = 0; i < self.specialty.size; i++ )
|
||||||
|
{
|
||||||
|
if ( isitemrestricted( self.specialty[i] ) )
|
||||||
|
{
|
||||||
|
arrayremoveindex( self.specialty, i );
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self [[ GetFunction( "maps/mp/gametypes/_class", "register_perks" ) ]]();
|
||||||
|
self setactionslot( 3, "altMode" );
|
||||||
|
self setactionslot( 4, "" );
|
||||||
|
self [[ GetFunction( "maps/mp/gametypes/_class", "givekillstreaks" ) ]]( class_num_for_killstreaks );
|
||||||
|
spawnweapon = "";
|
||||||
|
initialweaponcount = 0;
|
||||||
|
|
||||||
|
if ( isdefined( self.pers["weapon"] ) && self.pers["weapon"] != "none" && ![[ GetFunction( "maps/mp/killstreaks/_killstreaks", "iskillstreakweapon" ) ]]( self.pers["weapon"] ) )
|
||||||
|
{
|
||||||
|
weapon = self.pers["weapon"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
weapon = self getloadoutweapon( class_num, "primary" );
|
||||||
|
weapon = [[ GetFunction( "maps/mp/gametypes/_class", "removeduplicateattachments" ) ]]( weapon );
|
||||||
|
|
||||||
|
if ( [[ GetFunction( "maps/mp/killstreaks/_killstreaks", "iskillstreakweapon" ) ]]( weapon ) )
|
||||||
|
{
|
||||||
|
weapon = "weapon_null_mp";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isitemrestricted( strTok( weapon, "_" )[0] ) )
|
||||||
|
{
|
||||||
|
weapon = "weapon_null_mp";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sidearm = self getloadoutweapon( class_num, "secondary" );
|
||||||
|
sidearm = [[ GetFunction( "maps/mp/gametypes/_class", "removeduplicateattachments" ) ]]( sidearm );
|
||||||
|
|
||||||
|
if ( [[ GetFunction( "maps/mp/killstreaks/_killstreaks", "iskillstreakweapon" ) ]]( sidearm ) )
|
||||||
|
{
|
||||||
|
sidearm = "weapon_null_mp";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isitemrestricted( strTok( sidearm, "_" )[0] ) )
|
||||||
|
{
|
||||||
|
sidearm = "weapon_null_mp";
|
||||||
|
}
|
||||||
|
|
||||||
|
self.primaryweaponkill = 0;
|
||||||
|
self.secondaryweaponkill = 0;
|
||||||
|
|
||||||
|
if ( self isbonuscardactive( 2, self.class_num ) )
|
||||||
|
{
|
||||||
|
self.primaryloadoutweapon = weapon;
|
||||||
|
self.primaryloadoutaltweapon = weaponaltweaponname( weapon );
|
||||||
|
self.secondaryloadoutweapon = sidearm;
|
||||||
|
self.secondaryloadoutaltweapon = weaponaltweaponname( sidearm );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( self isbonuscardactive( 0, self.class_num ) )
|
||||||
|
{
|
||||||
|
self.primaryloadoutweapon = weapon;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( self isbonuscardactive( 1, self.class_num ) )
|
||||||
|
{
|
||||||
|
self.secondaryloadoutweapon = sidearm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( sidearm != "weapon_null_mp" )
|
||||||
|
{
|
||||||
|
secondaryweaponoptions = self calcweaponoptions( class_num, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
primaryweapon = weapon;
|
||||||
|
|
||||||
|
if ( primaryweapon != "weapon_null_mp" )
|
||||||
|
{
|
||||||
|
primaryweaponoptions = self calcweaponoptions( class_num, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( sidearm != "" && sidearm != "weapon_null_mp" && sidearm != "weapon_null" )
|
||||||
|
{
|
||||||
|
sidearm = restrict_attachments( sidearm );
|
||||||
|
|
||||||
|
self giveweapon( sidearm, 0, secondaryweaponoptions );
|
||||||
|
|
||||||
|
if ( self hasperk( "specialty_extraammo" ) )
|
||||||
|
{
|
||||||
|
self givemaxammo( sidearm );
|
||||||
|
}
|
||||||
|
|
||||||
|
spawnweapon = sidearm;
|
||||||
|
initialweaponcount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
primarytokens = strtok( primaryweapon, "_" );
|
||||||
|
self.pers["primaryWeapon"] = primarytokens[0];
|
||||||
|
/#
|
||||||
|
println( "^5GiveWeapon( " + weapon + " ) -- weapon" );
|
||||||
|
#/
|
||||||
|
|
||||||
|
if ( primaryweapon != "" && primaryweapon != "weapon_null_mp" && primaryweapon != "weapon_null" )
|
||||||
|
{
|
||||||
|
primaryweapon = restrict_attachments( primaryweapon );
|
||||||
|
|
||||||
|
self giveweapon( primaryweapon, 0, primaryweaponoptions );
|
||||||
|
|
||||||
|
if ( self hasperk( "specialty_extraammo" ) )
|
||||||
|
{
|
||||||
|
self givemaxammo( primaryweapon );
|
||||||
|
}
|
||||||
|
|
||||||
|
spawnweapon = primaryweapon;
|
||||||
|
initialweaponcount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( initialweaponcount < 2 )
|
||||||
|
{
|
||||||
|
knife = "knife_held_mp";
|
||||||
|
|
||||||
|
if ( isitemrestricted( "knife_held" ) )
|
||||||
|
{
|
||||||
|
knife = "weapon_null_mp";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( knife != "weapon_null_mp" )
|
||||||
|
{
|
||||||
|
self giveweapon( knife, 0, knifeweaponoptions );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( initialweaponcount == 0 )
|
||||||
|
{
|
||||||
|
spawnweapon = knife;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !isdefined( self.spawnweapon ) && isdefined( self.pers["spawnWeapon"] ) )
|
||||||
|
{
|
||||||
|
self.spawnweapon = self.pers["spawnWeapon"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isdefined( self.spawnweapon ) && doesweaponreplacespawnweapon( self.spawnweapon, spawnweapon ) && !self.pers["changed_class"] )
|
||||||
|
{
|
||||||
|
spawnweapon = self.spawnweapon;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.pers["changed_class"] = 0;
|
||||||
|
assert( spawnweapon != "" );
|
||||||
|
self.spawnweapon = spawnweapon;
|
||||||
|
self.pers["spawnWeapon"] = self.spawnweapon;
|
||||||
|
self setspawnweapon( spawnweapon );
|
||||||
|
grenadetypeprimary = self getloadoutitemref( class_num, "primarygrenade" );
|
||||||
|
|
||||||
|
if ( isitemrestricted( grenadetypeprimary ) )
|
||||||
|
{
|
||||||
|
grenadetypeprimary = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( [[ GetFunction( "maps/mp/killstreaks/_killstreaks", "iskillstreakweapon" ) ]]( grenadetypeprimary + "_mp" ) )
|
||||||
|
{
|
||||||
|
grenadetypeprimary = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
grenadetypesecondary = self getloadoutitemref( class_num, "specialgrenade" );
|
||||||
|
|
||||||
|
if ( isitemrestricted( grenadetypesecondary ) )
|
||||||
|
{
|
||||||
|
grenadetypesecondary = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( [[ GetFunction( "maps/mp/killstreaks/_killstreaks", "iskillstreakweapon" ) ]]( grenadetypesecondary + "_mp" ) )
|
||||||
|
{
|
||||||
|
grenadetypesecondary = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( grenadetypeprimary != "" && grenadetypeprimary != "weapon_null_mp" && [[ GetFunction( "maps/mp/gametypes/_class", "isequipmentallowed" ) ]]( grenadetypeprimary ) )
|
||||||
|
{
|
||||||
|
grenadetypeprimary += "_mp";
|
||||||
|
primarygrenadecount = self getloadoutitem( class_num, "primarygrenadecount" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( grenadetypesecondary != "" && grenadetypesecondary != "weapon_null_mp" && [[ GetFunction( "maps/mp/gametypes/_class", "isequipmentallowed" ) ]]( grenadetypesecondary ) )
|
||||||
|
{
|
||||||
|
grenadetypesecondary += "_mp";
|
||||||
|
grenadesecondarycount = self getloadoutitem( class_num, "specialgrenadecount" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !( grenadetypeprimary != "" && grenadetypeprimary != "weapon_null_mp" && [[ GetFunction( "maps/mp/gametypes/_class", "isequipmentallowed" ) ]]( grenadetypeprimary ) ) )
|
||||||
|
{
|
||||||
|
if ( grenadetypesecondary != level.weapons["frag"] )
|
||||||
|
{
|
||||||
|
grenadetypeprimary = level.weapons["frag"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grenadetypeprimary = level.weapons["flash"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/#
|
||||||
|
println( "^5GiveWeapon( " + grenadetypeprimary + " ) -- grenadeTypePrimary" );
|
||||||
|
#/
|
||||||
|
self giveweapon( grenadetypeprimary );
|
||||||
|
self setweaponammoclip( grenadetypeprimary, primarygrenadecount );
|
||||||
|
self switchtooffhand( grenadetypeprimary );
|
||||||
|
self.grenadetypeprimary = grenadetypeprimary;
|
||||||
|
self.grenadetypeprimarycount = primarygrenadecount;
|
||||||
|
|
||||||
|
if ( self.grenadetypeprimarycount > 1 )
|
||||||
|
{
|
||||||
|
self dualgrenadesactive();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( grenadetypesecondary != "" && grenadetypesecondary != "weapon_null_mp" && [[ GetFunction( "maps/mp/gametypes/_class", "isequipmentallowed" ) ]]( grenadetypesecondary ) )
|
||||||
|
{
|
||||||
|
self setoffhandsecondaryclass( grenadetypesecondary );
|
||||||
|
/#
|
||||||
|
println( "^5GiveWeapon( " + grenadetypesecondary + " ) -- grenadeTypeSecondary" );
|
||||||
|
#/
|
||||||
|
self giveweapon( grenadetypesecondary );
|
||||||
|
self setweaponammoclip( grenadetypesecondary, grenadesecondarycount );
|
||||||
|
self.grenadetypesecondary = grenadetypesecondary;
|
||||||
|
self.grenadetypesecondarycount = grenadesecondarycount;
|
||||||
|
}
|
||||||
|
|
||||||
|
self bbclasschoice( class_num, primaryweapon, sidearm );
|
||||||
|
|
||||||
|
if ( !sessionmodeiszombiesgame() )
|
||||||
|
{
|
||||||
|
for ( i = 0; i < 3; i++ )
|
||||||
|
{
|
||||||
|
if ( level.loadoutkillstreaksenabled && isdefined( self.killstreak[i] ) && isdefined( level.killstreakindices[self.killstreak[i]] ) )
|
||||||
|
{
|
||||||
|
killstreaks[i] = level.killstreakindices[self.killstreak[i]];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
killstreaks[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
self recordloadoutperksandkillstreaks( primaryweapon, sidearm, grenadetypeprimary, grenadetypesecondary, killstreaks[0], killstreaks[1], killstreaks[2] );
|
||||||
|
}
|
||||||
|
|
||||||
|
self [[ GetFunction( "maps/mp/teams/_teams", "set_player_model" ) ]]( team, weapon );
|
||||||
|
self [[ GetFunction( "maps/mp/gametypes/_class", "initstaticweaponstime" ) ]]();
|
||||||
|
self thread [[ GetFunction( "maps/mp/gametypes/_class", "initweaponattachments" ) ]]( spawnweapon );
|
||||||
|
self setplayerrenderoptions( playerrenderoptions );
|
||||||
|
|
||||||
|
if ( isdefined( self.movementspeedmodifier ) )
|
||||||
|
{
|
||||||
|
self setmovespeedscale( self.movementspeedmodifier * self getmovespeedscale() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isdefined( level.givecustomloadout ) )
|
||||||
|
{
|
||||||
|
spawnweapon = self [[ level.givecustomloadout ]]();
|
||||||
|
|
||||||
|
if ( isdefined( spawnweapon ) )
|
||||||
|
{
|
||||||
|
self thread [[ GetFunction( "maps/mp/gametypes/_class", "initweaponattachments" ) ]]( spawnweapon );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self [[ GetFunction( "maps/mp/gametypes/_class", "cac_selector" ) ]]();
|
||||||
|
|
||||||
|
if ( !isdefined( self.firstspawn ) )
|
||||||
|
{
|
||||||
|
if ( isdefined( spawnweapon ) )
|
||||||
|
{
|
||||||
|
self initialweaponraise( spawnweapon );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self initialweaponraise( weapon );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self seteverhadweaponall( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
self.firstspawn = 0;
|
||||||
|
pixendevent();
|
||||||
}
|
}
|
@ -1,13 +1,138 @@
|
|||||||
|
#include common_scripts\utility;
|
||||||
|
#include maps\mp\_utility;
|
||||||
|
#include maps\mp\zombies\_zm_utility;
|
||||||
|
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
if ( GetDvarInt( "scr_disablePlutoniumFixes" ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isDedicated() )
|
||||||
|
{
|
||||||
|
// fix menuresponse exploits
|
||||||
|
replaceFunc( GetFunction( "maps/mp/gametypes_zm/_zm_gametype", "menu_onmenuresponse" ), ::menu_onmenuresponse_fix, -1 );
|
||||||
|
|
||||||
|
// fix player spawnpoints
|
||||||
|
replaceFunc( GetFunction( "maps/mp/zombies/_zm", "getfreespawnpoint" ), ::getFreeSpawnpoint_override, -1 );
|
||||||
|
|
||||||
|
// use coop revive
|
||||||
|
level.using_solo_revive = false;
|
||||||
|
replaceFunc( GetFunction( "maps/mp/zombies/_zm", "check_quickrevive_for_hotjoin" ), ::check_quickrevive_for_hotjoin_fix, -1 );
|
||||||
|
|
||||||
|
// add a timeout for all_players_connected and kill solo revive
|
||||||
|
replaceFunc( GetFunction( "maps/mp/zombies/_zm", "onallplayersready" ), ::onallplayersready_override, -1 );
|
||||||
|
|
||||||
|
// make sure game is coop mode
|
||||||
|
func = GetFunction( "maps/mp/zm_alcatraz_utility", "check_solo_status" );
|
||||||
|
|
||||||
|
if ( !isDefined( func ) )
|
||||||
|
{
|
||||||
|
func = GetFunction( "maps/mp/zm_tomb_utility", "check_solo_status" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isDefined( func ) )
|
||||||
|
{
|
||||||
|
replaceFunc( func, ::check_solo_status_override, -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// fix inert zombies spawning
|
||||||
|
func = GetFunction( "maps/mp/zm_transit_classic", "spawn_inert_zombies" );
|
||||||
|
|
||||||
|
if ( isDefined( func ) )
|
||||||
|
{
|
||||||
|
replaceFunc( func, ::spawn_inert_zombies_override, -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// fix tombstone spawning
|
||||||
|
func = GetFunction( "maps/mp/zm_transit_utility", "solo_tombstone_removal" );
|
||||||
|
|
||||||
|
if ( isDefined( func ) )
|
||||||
|
{
|
||||||
|
replaceFunc( func, ::noop, -1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// replaceFunc( GetFunction( "maps/mp/animscripts/zm_utility", "wait_network_frame" ), ::wait_network_frame_override, -1 );
|
||||||
|
// replaceFunc( GetFunction( "maps/mp/zombies/_zm_utility", "wait_network_frame" ), ::wait_network_frame_override, -1 );
|
||||||
|
}
|
||||||
|
|
||||||
init()
|
init()
|
||||||
{
|
{
|
||||||
|
if ( GetDvarInt( "scr_disablePlutoniumFixes" ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable 8 player zombie games
|
||||||
level.player_too_many_players_check = false;
|
level.player_too_many_players_check = false;
|
||||||
|
|
||||||
if ( isDedicated() )
|
if ( isDedicated() )
|
||||||
{
|
{
|
||||||
|
// fix ranking
|
||||||
level thread upload_stats_on_round_end();
|
level thread upload_stats_on_round_end();
|
||||||
level thread upload_stats_on_game_end();
|
level thread upload_stats_on_game_end();
|
||||||
level thread upload_stats_on_player_connect();
|
level thread upload_stats_on_player_connect();
|
||||||
|
|
||||||
|
// fix teamchange exploit
|
||||||
|
level.allow_teamchange = getgametypesetting( "allowInGameTeamChange" ) + "";
|
||||||
|
SetDvar( "ui_allow_teamchange", level.allow_teamchange );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
level thread watch_all_zombies();
|
||||||
|
}
|
||||||
|
|
||||||
|
watch_all_zombies()
|
||||||
|
{
|
||||||
|
can_mantle_over_zambies = ( level.script == "zm_transit" || level.script == "zm_transit_dr" || level.script == "zm_prison" || level.script == "zm_nuked" || level.script == "zm_highrise" );
|
||||||
|
|
||||||
|
for ( ;; )
|
||||||
|
{
|
||||||
|
zombies = getaiarray( level.zombie_team );
|
||||||
|
|
||||||
|
foreach ( zombie in zombies )
|
||||||
|
{
|
||||||
|
if ( isDefined( zombie.pluto_audit ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
zombie.pluto_audit = true;
|
||||||
|
|
||||||
|
// fix jumping over zombies
|
||||||
|
if ( isDedicated() && can_mantle_over_zambies )
|
||||||
|
{
|
||||||
|
zombie thread fix_zombie_physparams();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wait 0.05;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fix_zombie_physparams()
|
||||||
|
{
|
||||||
|
self endon( "death" );
|
||||||
|
|
||||||
|
if ( !is_true( self.completed_emerging_into_playable_area ) )
|
||||||
|
{
|
||||||
|
self waittill( "completed_emerging_into_playable_area" );
|
||||||
|
}
|
||||||
|
|
||||||
|
animname = self.animname;
|
||||||
|
|
||||||
|
if ( !isDefined( animname ) )
|
||||||
|
{
|
||||||
|
animname = self.targetname;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( animname != "zombie" || !self.has_legs )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self setphysparams( 15, 0, 60 );
|
||||||
}
|
}
|
||||||
|
|
||||||
upload_stats_on_round_end()
|
upload_stats_on_round_end()
|
||||||
@ -51,3 +176,356 @@ delay_uploadstats( delay )
|
|||||||
wait delay;
|
wait delay;
|
||||||
uploadstats();
|
uploadstats();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_quickrevive_for_hotjoin_fix( disconnecting_player )
|
||||||
|
{
|
||||||
|
should_update = 0;
|
||||||
|
solo_mode = 0;
|
||||||
|
|
||||||
|
if ( flag( "solo_game" ) )
|
||||||
|
{
|
||||||
|
should_update = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
flag_clear( "solo_game" );
|
||||||
|
|
||||||
|
level.using_solo_revive = solo_mode;
|
||||||
|
level.revive_machine_is_solo = solo_mode;
|
||||||
|
[[ GetFunction( "maps/mp/zombies/_zm", "set_default_laststand_pistol" ) ]]( solo_mode );
|
||||||
|
|
||||||
|
if ( should_update && isdefined( level.quick_revive_machine ) )
|
||||||
|
{
|
||||||
|
[[ GetFunction( "maps/mp/zombies/_zm", "update_quick_revive" ) ]]( solo_mode );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
menu_onmenuresponse_fix()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
|
||||||
|
for ( ;; )
|
||||||
|
{
|
||||||
|
self waittill( "menuresponse", menu, response );
|
||||||
|
|
||||||
|
if ( response == "back" )
|
||||||
|
{
|
||||||
|
self closemenu();
|
||||||
|
self closeingamemenu();
|
||||||
|
|
||||||
|
if ( level.console )
|
||||||
|
{
|
||||||
|
if ( menu == game["menu_changeclass"] || menu == game["menu_changeclass_offline"] || menu == game["menu_team"] || menu == game["menu_controls"] )
|
||||||
|
{
|
||||||
|
if ( self.pers["team"] == "allies" )
|
||||||
|
{
|
||||||
|
self openmenu( game["menu_class"] );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( self.pers["team"] == "axis" )
|
||||||
|
{
|
||||||
|
self openmenu( game["menu_class"] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( response == "changeteam" && level.allow_teamchange == "1" )
|
||||||
|
{
|
||||||
|
self closemenu();
|
||||||
|
self closeingamemenu();
|
||||||
|
self openmenu( game["menu_team"] );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( response == "changeclass_marines" )
|
||||||
|
{
|
||||||
|
self closemenu();
|
||||||
|
self closeingamemenu();
|
||||||
|
self openmenu( game["menu_changeclass_allies"] );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( response == "changeclass_opfor" )
|
||||||
|
{
|
||||||
|
self closemenu();
|
||||||
|
self closeingamemenu();
|
||||||
|
self openmenu( game["menu_changeclass_axis"] );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( response == "changeclass_wager" )
|
||||||
|
{
|
||||||
|
self closemenu();
|
||||||
|
self closeingamemenu();
|
||||||
|
self openmenu( game["menu_changeclass_wager"] );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( response == "changeclass_custom" )
|
||||||
|
{
|
||||||
|
self closemenu();
|
||||||
|
self closeingamemenu();
|
||||||
|
self openmenu( game["menu_changeclass_custom"] );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( response == "changeclass_barebones" )
|
||||||
|
{
|
||||||
|
self closemenu();
|
||||||
|
self closeingamemenu();
|
||||||
|
self openmenu( game["menu_changeclass_barebones"] );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( response == "changeclass_marines_splitscreen" )
|
||||||
|
{
|
||||||
|
self openmenu( "changeclass_marines_splitscreen" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( response == "changeclass_opfor_splitscreen" )
|
||||||
|
{
|
||||||
|
self openmenu( "changeclass_opfor_splitscreen" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( menu == game["menu_team"] && level.allow_teamchange == "1" )
|
||||||
|
{
|
||||||
|
switch ( response )
|
||||||
|
{
|
||||||
|
case "allies":
|
||||||
|
self [[ level.allies ]]();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "axis":
|
||||||
|
self [[ level.teammenu ]]( response );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "autoassign":
|
||||||
|
self [[ level.autoassign ]]( 1 );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "spectator":
|
||||||
|
self [[ level.spectator ]]();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( menu == game["menu_changeclass"] || menu == game["menu_changeclass_offline"] || menu == game["menu_changeclass_wager"] || menu == game["menu_changeclass_custom"] || menu == game["menu_changeclass_barebones"] )
|
||||||
|
{
|
||||||
|
self closemenu();
|
||||||
|
self closeingamemenu();
|
||||||
|
|
||||||
|
if ( level.rankedmatch && issubstr( response, "custom" ) )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
self.selectedclass = 1;
|
||||||
|
self [[ level.class ]]( response );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
check_solo_status_override()
|
||||||
|
{
|
||||||
|
level.is_forever_solo_game = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_network_frame_override()
|
||||||
|
{
|
||||||
|
wait 0.05;
|
||||||
|
}
|
||||||
|
|
||||||
|
noop()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
getFreeSpawnpoint_override( spawnpoints, player )
|
||||||
|
{
|
||||||
|
if ( !isdefined( spawnpoints ) )
|
||||||
|
{
|
||||||
|
/#
|
||||||
|
iprintlnbold( "ZM >> No free spawn points in map" );
|
||||||
|
#/
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !isdefined( game["spawns_randomized"] ) )
|
||||||
|
{
|
||||||
|
game["spawns_randomized"] = 1;
|
||||||
|
spawnpoints = array_randomize( spawnpoints );
|
||||||
|
random_chance = randomint( 100 );
|
||||||
|
|
||||||
|
if ( random_chance > 50 )
|
||||||
|
{
|
||||||
|
set_game_var( "side_selection", 1 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_game_var( "side_selection", 2 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
side_selection = get_game_var( "side_selection" );
|
||||||
|
|
||||||
|
if ( get_game_var( "switchedsides" ) )
|
||||||
|
{
|
||||||
|
if ( side_selection == 2 )
|
||||||
|
{
|
||||||
|
side_selection = 1;
|
||||||
|
}
|
||||||
|
else if ( side_selection == 1 )
|
||||||
|
{
|
||||||
|
side_selection = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isdefined( player ) && isdefined( player.team ) )
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
while ( isdefined( spawnpoints ) && i < spawnpoints.size )
|
||||||
|
{
|
||||||
|
if ( side_selection == 1 )
|
||||||
|
{
|
||||||
|
if ( player.team != "allies" && ( isdefined( spawnpoints[i].script_int ) && spawnpoints[i].script_int == 1 ) )
|
||||||
|
{
|
||||||
|
arrayremovevalue( spawnpoints, spawnpoints[i] );
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
else if ( player.team == "allies" && ( isdefined( spawnpoints[i].script_int ) && spawnpoints[i].script_int == 2 ) )
|
||||||
|
{
|
||||||
|
arrayremovevalue( spawnpoints, spawnpoints[i] );
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( player.team == "allies" && ( isdefined( spawnpoints[i].script_int ) && spawnpoints[i].script_int == 1 ) )
|
||||||
|
{
|
||||||
|
arrayremovevalue( spawnpoints, spawnpoints[i] );
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
else if ( player.team != "allies" && ( isdefined( spawnpoints[i].script_int ) && spawnpoints[i].script_int == 2 ) )
|
||||||
|
{
|
||||||
|
arrayremovevalue( spawnpoints, spawnpoints[i] );
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
max_clients = getdvarint( "sv_maxclients" );
|
||||||
|
|
||||||
|
if ( !isdefined( self.playernum ) )
|
||||||
|
{
|
||||||
|
self.playernum = self getentitynumber();
|
||||||
|
|
||||||
|
assert( self.playernum < max_clients );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( j = 0; j < spawnpoints.size; j++ )
|
||||||
|
{
|
||||||
|
if ( !isdefined( spawnpoints[j].en_num ) )
|
||||||
|
{
|
||||||
|
for ( m = 0; m < spawnpoints.size; m++ )
|
||||||
|
{
|
||||||
|
spawnpoints[m].en_num = m % max_clients;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( spawnpoints[j].en_num == self.playernum )
|
||||||
|
{
|
||||||
|
return spawnpoints[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/#
|
||||||
|
print( "getFreeSpawnpoint: no spawns found, use first spawn" );
|
||||||
|
#/
|
||||||
|
assert( spawnpoints.size > 0 );
|
||||||
|
return spawnpoints[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
onallplayersready_override()
|
||||||
|
{
|
||||||
|
/#
|
||||||
|
println( "ZM >> player_count_expected=" + getnumexpectedplayers() );
|
||||||
|
#/
|
||||||
|
|
||||||
|
player_count_actual = 0;
|
||||||
|
timeout_started = false;
|
||||||
|
timeout_point = 0;
|
||||||
|
|
||||||
|
while ( getnumexpectedplayers() == 0 || getnumconnectedplayers() < getnumexpectedplayers() || player_count_actual != getnumexpectedplayers() )
|
||||||
|
{
|
||||||
|
players = get_players();
|
||||||
|
player_count_actual = 0;
|
||||||
|
|
||||||
|
for ( i = 0; i < players.size; i++ )
|
||||||
|
{
|
||||||
|
players[i] freezecontrols( 1 );
|
||||||
|
|
||||||
|
if ( players[i].sessionstate == "playing" )
|
||||||
|
{
|
||||||
|
player_count_actual++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( player_count_actual > 0 )
|
||||||
|
{
|
||||||
|
if ( !timeout_started )
|
||||||
|
{
|
||||||
|
timeout_started = true;
|
||||||
|
timeout_point = ( getDvarFloat( "sv_connecttimeout" ) * 1000 ) + getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( getTime() > timeout_point )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
timeout_started = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/#
|
||||||
|
println( "ZM >> Num Connected =" + getnumconnectedplayers() + " Expected : " + getnumexpectedplayers() );
|
||||||
|
#/
|
||||||
|
wait 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
setinitialplayersconnected();
|
||||||
|
|
||||||
|
/#
|
||||||
|
println( "ZM >> We have all players - START ZOMBIE LOGIC" );
|
||||||
|
#/
|
||||||
|
|
||||||
|
flag_set( "initial_players_connected" );
|
||||||
|
|
||||||
|
while ( !aretexturesloaded() )
|
||||||
|
{
|
||||||
|
wait 0.05;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread [[ GetFunction( "maps/mp/zombies/_zm", "start_zombie_logic_in_x_sec" ) ]]( 3.0 );
|
||||||
|
|
||||||
|
[[ GetFunction( "maps/mp/zombies/_zm", "fade_out_intro_screen_zm" ) ]]( 5.0, 1.5, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
spawn_inert_zombies_override()
|
||||||
|
{
|
||||||
|
flag_wait( "initial_players_connected" );
|
||||||
|
|
||||||
|
func = GetFunction( "maps/mp/zm_transit_classic", "spawn_inert_zombies" );
|
||||||
|
disableDetourOnce( func );
|
||||||
|
self [[func]]();
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user