From 3bc29a74e6d2dce78277df5257a2d4089d605c1a Mon Sep 17 00:00:00 2001 From: Ikarrus Date: Sat, 11 Jul 2015 22:57:08 -0600 Subject: [PATCH] Adds a Join Queue if the server exceeds its hard population cap Players can join a queue that will notify them with a message and sound when a slot becomes available. First come first serve. Players have approximately 20 seconds to join after the notification. Failure to join in that window removes them from the queue, to remove AFKers. I haven't tested the code yet but it's basically done. --- code/controllers/subsystem/ticker.dm | 24 +++++++++++++++++++++++ code/modules/mob/new_player/new_player.dm | 21 +++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 064f438da46..186d713c717 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -41,6 +41,9 @@ var/datum/subsystem/ticker/ticker var/totalPlayers = 0 //used for pregame stats on statpanel var/totalPlayersReady = 0 //used for pregame stats on statpanel + var/queue_delay = 0 + var/list/queued_players = list() //used for join queues when the server exceeds the hard population cap + var/obj/screen/cinematic = null //used for station explosion cinematic @@ -97,6 +100,7 @@ var/datum/subsystem/ticker/ticker if(GAME_STATE_PLAYING) mode.process(wait * 0.1) + check_queue() if(!mode.explosion_in_progress && mode.check_finished() || force_ending) current_state = GAME_STATE_FINISHED @@ -434,3 +438,23 @@ var/datum/subsystem/ticker/ticker if(randomtips.len) world << "Tip of the round: [html_encode(pick(randomtips))]" +/datum/subsystem/ticker/proc/check_queue() + if(!queued_players.len || !config.hard_popcap) + return + + queue_delay ++ + var/mob/new_player/next_in_line = queued_players[1] + + switch(queue_delay) + if(5) //every 5 ticks check if there is a slot available + if(living_player_count() < config.hard_popcap) + if(next_in_line && next_in_line.client) + next_in_line << "A slot has opened! You have approximately 20 seconds to join. \>\>Join Game\<\<." + next_in_line << sound('sound/misc/notice1.ogg') + return + queued_players -= next_in_line //Client disconnected, remove he + queue_delay = 0 //No vacancy: restart timer + if(20 to INFINITY) //No response from the next in line when a vacancy exists, remove he + next_in_line << "No response recieved. You have been removed from the line." + queued_players -= next_in_line + queue_delay = 0 \ No newline at end of file diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 009ecd8ab0f..6792cd67949 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -126,13 +126,28 @@ if(!ticker || ticker.current_state != GAME_STATE_PLAYING) usr << "The round is either not ready, or has already finished..." return + var/relevant_cap if(config.hard_popcap && config.extreme_popcap) relevant_cap = min(config.hard_popcap, config.extreme_popcap) else relevant_cap = max(config.hard_popcap, config.extreme_popcap) - if(relevant_cap && living_player_count() >= relevant_cap && !(ckey(key) in admin_datums)) + + if(ticker.queued_players.len || (relevant_cap && living_player_count() >= relevant_cap && !(ckey(key) in admin_datums))) + var/queue_position = ticker.queued_players.Find(usr) + + if(queue_position == 1 && living_player_count() < relevant_cap) //Let them join if there is a slot available and they are the next one in line + LateChoices() + return + usr << "[config.hard_popcap_message]" + if(queue_position == 1) + usr << "You are next in line to join the game. You will be notified when a slot opens up." + else if(queue_position) + usr << "There are [queue_position-1] players in front of you in the queue to join the game." + else + ticker.queued_players += usr + usr << "You have been added to the queue to join the game. Your position in queue is [ticker.queued_players.len]." return LateChoices() @@ -234,6 +249,10 @@ src << alert("[rank] is not available. Please try another.") return 0 + //Remove the player from the join queue if he was in one and reset the timer + ticker.queued_players -= src + ticker.queue_delay = 4 + SSjob.AssignRole(src, rank, 1) var/mob/living/carbon/human/character = create_character() //creates the human and transfers vars and mind