r3321
This commit is contained in:
623
storage/t5/scripts/sp/zom/zm_spawn_fix.gsc
Normal file
623
storage/t5/scripts/sp/zom/zm_spawn_fix.gsc
Normal file
@ -0,0 +1,623 @@
|
||||
#include maps\_utility;
|
||||
#include common_scripts\utility;
|
||||
#include maps\_zombiemode_utility;
|
||||
|
||||
main()
|
||||
{
|
||||
if ( GetDvarInt( "scr_disableHotJoinFixes" ) )
|
||||
return;
|
||||
|
||||
if ( isDedicated() )
|
||||
{
|
||||
// always coop
|
||||
replaceFunc( maps\_utility::is_coop, ::alwaysTrue );
|
||||
|
||||
// make sure quickrevive is coop
|
||||
replaceFunc( maps\_zombiemode_perks::vending_trigger_think, ::vending_trigger_think );
|
||||
|
||||
// host is not players[0] on dedi
|
||||
replaceFunc( maps\_utility::get_host, ::getHostDedi );
|
||||
|
||||
// prevent force end exploit
|
||||
replaceFunc( maps\_cooplogic::forceEnd, ::noop );
|
||||
|
||||
// Fix join too early
|
||||
replaceFunc( maps\_load_common::all_players_connected, ::all_players_connected );
|
||||
}
|
||||
}
|
||||
|
||||
init()
|
||||
{
|
||||
if ( GetDvarInt( "scr_disableHotJoinFixes" ) )
|
||||
return;
|
||||
|
||||
// do prints, handle hotjoining and leavers
|
||||
level thread onPlayerConnect();
|
||||
|
||||
// lets be the last to setup func ptrs
|
||||
for ( i = 0; i < 10; i++ )
|
||||
waittillframeend;
|
||||
|
||||
// setup hot joining
|
||||
level.oldSpawnClient = level.spawnClient;
|
||||
level.spawnClient = ::spawnClientOverride;
|
||||
|
||||
if ( !isDefined( level.hotJoinPlayer ) )
|
||||
level.hotJoinPlayer = ::hotJoin;
|
||||
|
||||
// setup how endgame
|
||||
if ( !isDefined( level.endGame ) )
|
||||
{
|
||||
level.endGame = ::endGameNotify;
|
||||
}
|
||||
|
||||
if ( !isDefined( level.isPlayerDead ) )
|
||||
level.isPlayerDead = ::checkIsPlayerDead;
|
||||
|
||||
// make dead players into spectators
|
||||
level.oldOverridePlayerKilled = level.overridePlayerKilled;
|
||||
level.overridePlayerKilled = ::playerKilledOverride;
|
||||
|
||||
// fix spawning
|
||||
level thread endOfRoundSpectatorRespawnWatch();
|
||||
}
|
||||
|
||||
getHostDedi()
|
||||
{
|
||||
return get_players()[0];
|
||||
}
|
||||
|
||||
alwaysTrue()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
noop()
|
||||
{
|
||||
}
|
||||
|
||||
endGameNotify()
|
||||
{
|
||||
level notify( "end_game" );
|
||||
}
|
||||
|
||||
checkIsPlayerDead( player )
|
||||
{
|
||||
return ( player.sessionstate == "spectator" || player maps\_laststand::player_is_in_laststand() || ( isDefined( player.is_zombie ) && player.is_zombie ) );
|
||||
}
|
||||
|
||||
playerKilledOverride()
|
||||
{
|
||||
self [[level.player_becomes_zombie]]();
|
||||
checkForAllDead( self );
|
||||
self [[level.oldOverridePlayerKilled]]();
|
||||
}
|
||||
|
||||
spawnClientOverride()
|
||||
{
|
||||
if ( flag( "all_players_spawned" ) )
|
||||
self thread [[level.hotJoinPlayer]]();
|
||||
else
|
||||
self thread [[level.oldSpawnClient]]();
|
||||
}
|
||||
|
||||
getHotJoinPlayer()
|
||||
{
|
||||
players = get_players();
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
player = players[i];
|
||||
|
||||
if ( !isDefined( player ) || !isDefined( player.sessionstate ) )
|
||||
continue;
|
||||
|
||||
if ( player == self )
|
||||
continue;
|
||||
|
||||
if ( player.sessionstate == "spectator" )
|
||||
continue;
|
||||
|
||||
if ( isDefined( player.is_zombie ) && player.is_zombie )
|
||||
continue;
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getHotJoinAi( team )
|
||||
{
|
||||
ais = GetAiArray( team );
|
||||
ai = undefined;
|
||||
|
||||
if ( ais.size )
|
||||
ai = ais[randomint( ais.size )];
|
||||
|
||||
return ai;
|
||||
}
|
||||
|
||||
getHotJoinInitSpawn()
|
||||
{
|
||||
structs = getstructarray( "initial_spawn_points", "targetname" );
|
||||
players = get_players();
|
||||
i = 0;
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
if ( !isDefined( players[i] ) )
|
||||
continue;
|
||||
|
||||
if ( self == players[i] )
|
||||
break;
|
||||
}
|
||||
|
||||
spawn_obj = structs[i];
|
||||
|
||||
if ( !isDefined( spawn_obj ) )
|
||||
spawn_obj = structs[0];
|
||||
|
||||
return spawn_obj;
|
||||
}
|
||||
|
||||
hotJoin()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "end_respawn" );
|
||||
|
||||
// quik hax: prevent spectators_respawn from spawning us
|
||||
self.sessionstate = "playing";
|
||||
waittillframeend;
|
||||
self.sessionstate = "spectator";
|
||||
|
||||
player = self getHotJoinPlayer();
|
||||
ally = self getHotJoinAi( "allies" );
|
||||
enemy = self getHotJoinAi( "axis" );
|
||||
spawn_pt = self getHotJoinInitSpawn();
|
||||
|
||||
spawn_obj = spawnStruct();
|
||||
|
||||
if ( isDefined( spawn_pt ) )
|
||||
{
|
||||
spawn_obj = spawn_pt;
|
||||
}
|
||||
else if ( isDefined( player ) )
|
||||
{
|
||||
spawn_obj.origin = player getOrigin();
|
||||
spawn_obj.angles = player.angles;
|
||||
}
|
||||
else if ( isDefined( ally ) )
|
||||
{
|
||||
spawn_obj.origin = ally getOrigin();
|
||||
spawn_obj.angles = ally.angles;
|
||||
}
|
||||
else if ( isDefined( enemy ) )
|
||||
{
|
||||
spawn_obj.origin = enemy getOrigin();
|
||||
spawn_obj.angles = enemy.angles;
|
||||
}
|
||||
else
|
||||
{
|
||||
spawn_obj.origin = ( 0, 0, 0 );
|
||||
spawn_obj.angles = ( 0, 0, 0 );
|
||||
}
|
||||
|
||||
// check if custom logic for hotjoining
|
||||
if ( isDefined( level.customHotJoinPlayer ) )
|
||||
{
|
||||
temp_obj = self [[level.customHotJoinPlayer]]( spawn_obj );
|
||||
|
||||
// check if theres a spawn obj
|
||||
if ( isDefined( temp_obj ) )
|
||||
{
|
||||
// check if we should cancel spawning this player (maybe its already done)
|
||||
if ( isDefined( temp_obj.cancel ) && temp_obj.cancel )
|
||||
return;
|
||||
|
||||
// set our spawn location
|
||||
spawn_obj = temp_obj;
|
||||
}
|
||||
}
|
||||
|
||||
// set spawn params
|
||||
self setorigin( spawn_obj.origin );
|
||||
self setplayerangles( spawn_obj.angles );
|
||||
self.spectator_respawn = spawn_obj;
|
||||
self.respawn_point = spawn_obj;
|
||||
|
||||
// do the spawn
|
||||
println( "*************************Client hotjoin***" );
|
||||
|
||||
self unlink();
|
||||
|
||||
if ( isdefined( self.spectate_cam ) )
|
||||
self.spectate_cam delete ();
|
||||
|
||||
if ( isDefined( spawn_obj.force_spawn ) && spawn_obj.force_spawn )
|
||||
self thread [[level.spawnPlayer]]();
|
||||
else
|
||||
{
|
||||
self thread [[level.spawnSpectator]]();
|
||||
checkForAllDead( self );
|
||||
}
|
||||
}
|
||||
|
||||
onDisconnect()
|
||||
{
|
||||
lpselfnum = self getentitynumber();
|
||||
lpguid = self getguid();
|
||||
name = self.playername;
|
||||
|
||||
self waittill( "disconnect" );
|
||||
|
||||
logprint( "Q;" + lpguid + ";" + lpselfnum + ";" + name + "\n" );
|
||||
|
||||
// check if we need to end the game cause last person left alive left the game
|
||||
checkForAllDead( self );
|
||||
}
|
||||
|
||||
onConnect()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
logprint( "J;" + self getguid() + ";" + self getentitynumber() + ";" + self.playername + "\n" );
|
||||
|
||||
// this only happens on first connect, we need to do it for hot joiners...
|
||||
if ( flag( "all_players_spawned" ) )
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
wait 0.05;
|
||||
self freezecontrols( false );
|
||||
self setClientDvars( "ammoCounterHide", "0",
|
||||
"miniscoreboardhide", "0" );
|
||||
|
||||
if ( level.round_number > 6 )
|
||||
self.score = 1500;
|
||||
else
|
||||
self.score = 500;
|
||||
|
||||
self.score_total = self.score;
|
||||
self.old_score = self.score;
|
||||
}
|
||||
}
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
|
||||
iprintln( player.playername + " connected." );
|
||||
|
||||
player thread onDisconnect();
|
||||
player thread onConnect();
|
||||
}
|
||||
}
|
||||
|
||||
checkForAllDead( excluded_player )
|
||||
{
|
||||
players = get_players();
|
||||
count = 0;
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
player = players[ i ];
|
||||
|
||||
if ( isDefined( excluded_player ) && excluded_player == player )
|
||||
continue;
|
||||
|
||||
if ( !isDefined( player ) || !isDefined( player.sessionstate ) )
|
||||
continue;
|
||||
|
||||
if ( [[level.isPlayerDead]]( player ) )
|
||||
continue;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
if ( count == 0 )
|
||||
{
|
||||
printf( "Ending game as no players are left alive..." );
|
||||
level thread [[level.endGame]]();
|
||||
}
|
||||
}
|
||||
|
||||
endOfRoundSpectatorRespawnWatch()
|
||||
{
|
||||
flag_wait( "all_players_spawned" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill( "end_of_round" );
|
||||
level thread maps\_zombiemode::spectators_respawn();
|
||||
}
|
||||
}
|
||||
|
||||
vending_trigger_think()
|
||||
{
|
||||
perk = self.script_noteworthy;
|
||||
solo = false;
|
||||
flag_init( "_start_zm_pistol_rank" );
|
||||
|
||||
printf( "Replaced vending_trigger_think" );
|
||||
if ( IsDefined( perk ) &&
|
||||
( perk == "specialty_quickrevive" || perk == "specialty_quickrevive_upgrade" ) )
|
||||
{
|
||||
flag_wait( "all_players_connected" );
|
||||
/* players = GetPlayers();
|
||||
if ( players.size == 1 )
|
||||
{
|
||||
solo = true;
|
||||
flag_set( "solo_game" );
|
||||
level.solo_lives_given = 0;
|
||||
players[0].lives = 0;
|
||||
level maps\_zombiemode::zombiemode_solo_last_stand_pistol();
|
||||
}*/
|
||||
}
|
||||
|
||||
flag_set( "_start_zm_pistol_rank" );
|
||||
|
||||
if ( !solo )
|
||||
{
|
||||
self SetHintString( &"ZOMBIE_NEED_POWER" );
|
||||
}
|
||||
|
||||
self SetCursorHint( "HINT_NOICON" );
|
||||
self UseTriggerRequireLookAt();
|
||||
|
||||
if ( !solo )
|
||||
{
|
||||
notify_name = perk + "_power_on";
|
||||
level waittill( notify_name );
|
||||
}
|
||||
|
||||
if ( !IsDefined( level._perkmachinenetworkchoke ) )
|
||||
{
|
||||
level._perkmachinenetworkchoke = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
level._perkmachinenetworkchoke ++;
|
||||
}
|
||||
|
||||
for ( i = 0; i < level._perkmachinenetworkchoke; i ++ )
|
||||
{
|
||||
wait_network_frame();
|
||||
}
|
||||
|
||||
|
||||
self thread maps\_zombiemode_audio::perks_a_cola_jingle_timer();
|
||||
|
||||
perk_hum = spawn( "script_origin", self.origin );
|
||||
perk_hum playloopsound( "zmb_perks_machine_loop" );
|
||||
self thread maps\_zombiemode_perks::check_player_has_perk( perk );
|
||||
|
||||
cost = level.zombie_vars["zombie_perk_cost"];
|
||||
|
||||
switch ( perk )
|
||||
{
|
||||
case "specialty_armorvest_upgrade":
|
||||
case "specialty_armorvest":
|
||||
cost = 2500;
|
||||
self SetHintString( &"ZOMBIE_PERK_JUGGERNAUT", cost );
|
||||
break;
|
||||
|
||||
case "specialty_quickrevive_upgrade":
|
||||
case "specialty_quickrevive":
|
||||
if ( solo )
|
||||
{
|
||||
cost = 500;
|
||||
self SetHintString( &"ZOMBIE_PERK_QUICKREVIVE_SOLO", cost );
|
||||
}
|
||||
else
|
||||
{
|
||||
cost = 1500;
|
||||
self SetHintString( &"ZOMBIE_PERK_QUICKREVIVE", cost );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "specialty_fastreload_upgrade":
|
||||
case "specialty_fastreload":
|
||||
cost = 3000;
|
||||
self SetHintString( &"ZOMBIE_PERK_FASTRELOAD", cost );
|
||||
break;
|
||||
|
||||
case "specialty_rof_upgrade":
|
||||
case "specialty_rof":
|
||||
cost = 2000;
|
||||
self SetHintString( &"ZOMBIE_PERK_DOUBLETAP", cost );
|
||||
break;
|
||||
|
||||
case "specialty_longersprint_upgrade":
|
||||
case "specialty_longersprint":
|
||||
cost = 2000;
|
||||
self SetHintString( &"ZOMBIE_PERK_MARATHON", cost );
|
||||
break;
|
||||
|
||||
case "specialty_flakjacket_upgrade":
|
||||
case "specialty_flakjacket":
|
||||
cost = 2000;
|
||||
self SetHintString( &"ZOMBIE_PERK_DIVETONUKE", cost );
|
||||
break;
|
||||
|
||||
case "specialty_deadshot_upgrade":
|
||||
case "specialty_deadshot":
|
||||
cost = 1500;
|
||||
self SetHintString( &"ZOMBIE_PERK_DEADSHOT", cost );
|
||||
break;
|
||||
|
||||
default:
|
||||
self SetHintString( perk + " Cost: " + level.zombie_vars["zombie_perk_cost"] );
|
||||
}
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "trigger", player );
|
||||
|
||||
index = maps\_zombiemode_weapons::get_player_index( player );
|
||||
|
||||
if ( player maps\_laststand::player_is_in_laststand() || is_true( player.intermission ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( player in_revive_trigger() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( player isThrowingGrenade() )
|
||||
{
|
||||
wait( 0.1 );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( player isSwitchingWeapons() )
|
||||
{
|
||||
wait( 0.1 );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( player is_drinking() )
|
||||
{
|
||||
wait( 0.1 );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( player HasPerk( perk ) )
|
||||
{
|
||||
cheat = false;
|
||||
|
||||
if ( cheat != true )
|
||||
{
|
||||
|
||||
self playsound( "deny" );
|
||||
player maps\_zombiemode_audio::create_and_play_dialog( "general", "perk_deny", undefined, 1 );
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( player.score < cost )
|
||||
{
|
||||
|
||||
self playsound( "evt_perk_deny" );
|
||||
player maps\_zombiemode_audio::create_and_play_dialog( "general", "perk_deny", undefined, 0 );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( player.num_perks >= 4 )
|
||||
{
|
||||
|
||||
self playsound( "evt_perk_deny" );
|
||||
|
||||
player maps\_zombiemode_audio::create_and_play_dialog( "general", "sigh" );
|
||||
continue;
|
||||
}
|
||||
|
||||
sound = "evt_bottle_dispense";
|
||||
playsoundatposition( sound, self.origin );
|
||||
player maps\_zombiemode_score::minus_to_player_score( cost );
|
||||
player.perk_purchased = perk;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
switch ( perk )
|
||||
{
|
||||
case "specialty_armorvest_upgrade":
|
||||
case "specialty_armorvest":
|
||||
sound = "mus_perks_jugger_sting";
|
||||
break;
|
||||
|
||||
case "specialty_quickrevive_upgrade":
|
||||
case "specialty_quickrevive":
|
||||
sound = "mus_perks_revive_sting";
|
||||
break;
|
||||
|
||||
case "specialty_fastreload_upgrade":
|
||||
case "specialty_fastreload":
|
||||
sound = "mus_perks_speed_sting";
|
||||
break;
|
||||
|
||||
case "specialty_rof_upgrade":
|
||||
case "specialty_rof":
|
||||
sound = "mus_perks_doubletap_sting";
|
||||
break;
|
||||
|
||||
case "specialty_longersprint_upgrade":
|
||||
case "specialty_longersprint":
|
||||
sound = "mus_perks_phd_sting";
|
||||
break;
|
||||
|
||||
case "specialty_flakjacket_upgrade":
|
||||
case "specialty_flakjacket":
|
||||
sound = "mus_perks_stamin_sting";
|
||||
break;
|
||||
|
||||
case "specialty_deadshot_upgrade":
|
||||
case "specialty_deadshot":
|
||||
sound = "mus_perks_jugger_sting";
|
||||
break;
|
||||
|
||||
default:
|
||||
sound = "mus_perks_jugger_sting";
|
||||
break;
|
||||
}
|
||||
|
||||
self thread maps\_zombiemode_audio::play_jingle_or_stinger ( self.script_label );
|
||||
|
||||
|
||||
|
||||
|
||||
gun = player maps\_zombiemode_perks::perk_give_bottle_begin( perk );
|
||||
player waittill_any( "fake_death", "death", "player_downed", "weapon_change_complete" );
|
||||
|
||||
player maps\_zombiemode_perks::perk_give_bottle_end( gun, perk );
|
||||
|
||||
|
||||
if ( player maps\_laststand::player_is_in_laststand() || is_true( player.intermission ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isDefined( level.perk_bought_func ) )
|
||||
{
|
||||
player [[ level.perk_bought_func ]]( perk );
|
||||
}
|
||||
|
||||
player.perk_purchased = undefined;
|
||||
player maps\_zombiemode_perks::give_perk( perk, true );
|
||||
|
||||
bbPrint( "zombie_uses: playername %s playerscore %d teamscore %d round %d cost %d name %s x %f y %f z %f type perk",
|
||||
player.playername, player.score, level.team_pool[ player.team_num ].score, level.round_number, cost, perk, self.origin );
|
||||
}
|
||||
}
|
||||
|
||||
all_players_connected()
|
||||
{
|
||||
while ( get_players().size == 0 )
|
||||
{
|
||||
wait 0.05;
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
num_con = getnumconnectedplayers();
|
||||
num_exp = getnumexpectedplayers();
|
||||
println( "all_players_connected(): getnumconnectedplayers=", num_con, "getnumexpectedplayers=", num_exp );
|
||||
|
||||
if(num_con == num_exp && (num_exp != 0))
|
||||
{
|
||||
flag_set( "all_players_connected" );
|
||||
// CODER_MOD: GMJ (08/28/08): Setting dvar for use by code
|
||||
SetDvar( "all_players_are_connected", "1" );
|
||||
return;
|
||||
}
|
||||
|
||||
wait( 0.05 );
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user