diff --git a/MapRestartWorkaround/readme.md b/MapRestartWorkaround/readme.md index 1cf822f..5ee9b2c 100644 --- a/MapRestartWorkaround/readme.md +++ b/MapRestartWorkaround/readme.md @@ -1,33 +1,35 @@ -#**Map Restart Workaround** +## Map Restart Workaround This is a mod that gets around the clientside errors that happen after a zombies game ends. When a zombies game ends and the clients remain in the server after the intermission restart, clients may experience several different clientside only bugs. Some examples of these errors include: --No sound except music --Barriers are glitched --Mystery box is glitched --A few more minor bugs -These are only clientside so have no effect on the server itself and can be fixed by simply leaving and rejoining. +-No sound except music + +-Barriers are glitched + +-Mystery box is glitched + +-A few more minor bugs + +These are only clientside so have no effect on the server itself and can be fixed by simply leaving and rejoining. However, I created a workaround that allows players to remain in the lobby after it ends and not experience any of these clientside issues. -#**The Workaround** +## The Workaround Basically, what I did was utilize map_restart in the GSC and I call it around 20 seconds after level.intermission is set to 1. What happens is the game uses a map_restart instead of the normal method Plutonium servers use. There is a reason this is a workaround though. That is because when map_restart occurs the game reparses all the scripts its supposed to load in the first place, -and as a result it reads a certain function in _zm.gsc. - +and as a result it reads a certain function in _zm.gsc. This only a part of the function but its the only part that matters +to this fix. +``` onallplayersready() { timeout = getTime() + 5000; while ( getnumexpectedplayers() == 0 && getTime() < timeout ) { - wait 0,1; + wait 0.1; } -/# - println( "ZM >> player_count_expected=" + getnumexpectedplayers() ); -#/ player_count_actual = 0; while ( getnumconnectedplayers() < getnumexpectedplayers() || player_count_actual != getnumexpectedplayers() ) { @@ -43,43 +45,24 @@ onallplayersready() } i++; } -/# - println( "ZM >> Num Connected =" + getnumconnectedplayers() + " Expected : " + getnumexpectedplayers() ); -#/ - wait 0,1; + + wait 0.1; } - setinitialplayersconnected(); -/# - println( "ZM >> We have all players - START ZOMBIE LOGIC" ); -#/ - if ( getnumconnectedplayers() == 1 && getDvarInt( "scr_zm_enable_bots" ) == 1 ) - { - level thread add_bots(); - flag_set( "initial_players_connected" ); - } - else - { - players = get_players(); - if ( players.size == 1 ) - { - flag_set( "solo_game" ); - level.solo_lives_given = 0; - _a379 = players; - _k379 = getFirstArrayKey( _a379 ); - while ( isDefined( _k379 ) ) - { - player = _a379[ _k379 ]; - player.lives = 0; - _k379 = getNextArrayKey( _a379, _k379 ); - } - level maps/mp/zombies/_zm::set_default_laststand_pistol( 1 ); - } - flag_set( "initial_players_connected" ); - while ( !aretexturesloaded() ) - { - wait 0,05; - } - thread start_zombie_logic_in_x_sec( 3 ); - } - fade_out_intro_screen_zm( 5, 1,5, 1 ); -} +``` + +So in this function there is a while loop that has 2 potential conditions and it will end on either of them being met. getnumconnectedplayers() +outputs the current number of players in the lobby. getnumexpectedplayers() outputs the expected number of players to join the game, this is determined at +map launch. Servers always launch the map assuming only 1 player will join; which is why tombstone doesn't spawn in without mods, why players have 3 afterlives +on MoTD, and why doors are cheaper on Origins. Therefore, getnumexpectedplayers() will always output 1 since its value is predetermined and will not change. +The first condition in the while loop will terminate immediately as soon as there is more than 1 player in the lobby when the function is ran. The second condition +is based on a counter that counts the number of players currently in the sessionstate "playing". Since player_count_actual will exceed the value of getnumexpectedplayers() +it will never meet its end condition of player_count_actual being equal to getnumexpectedplayers(). This results in an infinite loop since as long as there are more than +1 player in the lobby the loop will ever end preventing the blackscreen from passing, and rendering map_restart useless. + +However, player_count_actual only counts players that are spawned in and in "playing" state so the solution is to kill all players except player[0], and respawn them after a short delay. +Not exactly ideal, but it does mean all players can remain in the lobby and all players can have sound. + +#### Extras +-Players keep all points + +-End game check is disabled just incase player[0] leaves during the respawn function its reenabled when players are respawned