Players cannot observe before PREGAME is reached

Ready | Not Ready | Observe is now a three way toggle

The player ready status has been refactored into an ENUM of the three
states, READY, NOT_READY and OBSERVING

if the tickerstate is at least PREGAME they will spawn as observers,
before then you can only register your interest in observing.

All the observer code has been centralised into a single
make_me_an_observer proc on new_player mobs
This commit is contained in:
oranges
2017-06-09 13:14:11 +12:00
parent ee2e76d774
commit c866a77147
6 changed files with 93 additions and 70 deletions

View File

@@ -2,6 +2,11 @@
//Misc mob defines //Misc mob defines
//Ready states at roundstart for mob/dead/new_player
#define PLAYER_NOT_READY 0
#define PLAYER_READY_TO_PLAY 1
#define PLAYER_READY_TO_OBSERVE 2
//movement intent defines for the m_intent var //movement intent defines for the m_intent var
#define MOVE_INTENT_WALK "walk" #define MOVE_INTENT_WALK "walk"
#define MOVE_INTENT_RUN "run" #define MOVE_INTENT_RUN "run"
@@ -128,4 +133,4 @@
#define INCORPOREAL_MOVE_BASIC 1 #define INCORPOREAL_MOVE_BASIC 1
#define INCORPOREAL_MOVE_SHADOW 2 // leaves a trail of shadows #define INCORPOREAL_MOVE_SHADOW 2 // leaves a trail of shadows
#define INCORPOREAL_MOVE_JAUNT 3 // is blocked by holy water/salt #define INCORPOREAL_MOVE_JAUNT 3 // is blocked by holy water/salt

View File

@@ -224,7 +224,7 @@ SUBSYSTEM_DEF(job)
//Get the players who are ready //Get the players who are ready
for(var/mob/dead/new_player/player in GLOB.player_list) for(var/mob/dead/new_player/player in GLOB.player_list)
if(player.ready && player.mind && !player.mind.assigned_role) if(player.ready == PLAYER_READY_TO_PLAY && player.mind && !player.mind.assigned_role)
unassigned += player unassigned += player
initial_players_to_assign = unassigned.len initial_players_to_assign = unassigned.len
@@ -456,7 +456,7 @@ SUBSYSTEM_DEF(job)
var/level5 = 0 //banned var/level5 = 0 //banned
var/level6 = 0 //account too young var/level6 = 0 //account too young
for(var/mob/dead/new_player/player in GLOB.player_list) for(var/mob/dead/new_player/player in GLOB.player_list)
if(!(player.ready && player.mind && !player.mind.assigned_role)) if(!(player.ready == PLAYER_READY_TO_PLAY && player.mind && !player.mind.assigned_role))
continue //This player is not ready continue //This player is not ready
if(jobban_isbanned(player, job.title)) if(jobban_isbanned(player, job.title))
level5++ level5++
@@ -489,7 +489,7 @@ SUBSYSTEM_DEF(job)
Debug("Popcap overflow Check observer located, Player: [player]") Debug("Popcap overflow Check observer located, Player: [player]")
to_chat(player, "<b>You have failed to qualify for any job you desired.</b>") to_chat(player, "<b>You have failed to qualify for any job you desired.</b>")
unassigned -= player unassigned -= player
player.ready = 0 player.ready = PLAYER_NOT_READY
/datum/controller/subsystem/job/Recover() /datum/controller/subsystem/job/Recover()

View File

@@ -83,6 +83,8 @@ SUBSYSTEM_DEF(ticker)
window_flash(C, ignorepref = TRUE) //let them know lobby has opened up. window_flash(C, ignorepref = TRUE) //let them know lobby has opened up.
to_chat(world, "<span class='boldnotice'>Welcome to [station_name()]!</span>") to_chat(world, "<span class='boldnotice'>Welcome to [station_name()]!</span>")
current_state = GAME_STATE_PREGAME current_state = GAME_STATE_PREGAME
//Everyone who wants to be an observer is now spawned
create_observers()
fire() fire()
if(GAME_STATE_PREGAME) if(GAME_STATE_PREGAME)
//lobby stats for statpanels //lobby stats for statpanels
@@ -92,7 +94,7 @@ SUBSYSTEM_DEF(ticker)
totalPlayersReady = 0 totalPlayersReady = 0
for(var/mob/dead/new_player/player in GLOB.player_list) for(var/mob/dead/new_player/player in GLOB.player_list)
++totalPlayers ++totalPlayers
if(player.ready) if(player.ready == PLAYER_READY_TO_PLAY)
++totalPlayersReady ++totalPlayersReady
if(start_immediately) if(start_immediately)
@@ -131,6 +133,7 @@ SUBSYSTEM_DEF(ticker)
declare_completion(force_ending) declare_completion(force_ending)
Master.SetRunLevel(RUNLEVEL_POSTGAME) Master.SetRunLevel(RUNLEVEL_POSTGAME)
/datum/controller/subsystem/ticker/proc/setup() /datum/controller/subsystem/ticker/proc/setup()
to_chat(world, "<span class='boldannounce'>Starting game...</span>") to_chat(world, "<span class='boldannounce'>Starting game...</span>")
var/init_start = world.timeofday var/init_start = world.timeofday
@@ -402,7 +405,7 @@ SUBSYSTEM_DEF(ticker)
/datum/controller/subsystem/ticker/proc/create_characters() /datum/controller/subsystem/ticker/proc/create_characters()
for(var/mob/dead/new_player/player in GLOB.player_list) for(var/mob/dead/new_player/player in GLOB.player_list)
if(player.ready && player.mind) if(player.ready == PLAYER_READY_TO_PLAY && player.mind)
GLOB.joined_player_list += player.ckey GLOB.joined_player_list += player.ckey
player.create_character(FALSE) player.create_character(FALSE)
else else
@@ -793,6 +796,13 @@ SUBSYSTEM_DEF(ticker)
else else
timeLeft = newtime timeLeft = newtime
//Everyone who wanted to be an observer gets made one now
/datum/controller/subsystem/ticker/proc/create_observers()
for(var/mob/dead/new_player/player in GLOB.player_list)
if(player.ready == PLAYER_READY_TO_OBSERVE && player.mind)
//Break chain since this has a sleep input in it
addtimer(CALLBACK(player, /mob/dead/new_player.proc/make_me_an_observer), 1)
/datum/controller/subsystem/ticker/proc/load_mode() /datum/controller/subsystem/ticker/proc/load_mode()
var/mode = trim(file2text("data/mode.txt")) var/mode = trim(file2text("data/mode.txt"))
if(mode) if(mode)

View File

@@ -54,7 +54,7 @@
/datum/game_mode/proc/can_start() /datum/game_mode/proc/can_start()
var/playerC = 0 var/playerC = 0
for(var/mob/dead/new_player/player in GLOB.player_list) for(var/mob/dead/new_player/player in GLOB.player_list)
if((player.client)&&(player.ready)) if((player.client)&&(player.ready == PLAYER_READY_TO_PLAY))
playerC++ playerC++
if(!GLOB.Debug2) if(!GLOB.Debug2)
if(playerC < required_players || (maximum_players >= 0 && playerC > maximum_players)) if(playerC < required_players || (maximum_players >= 0 && playerC > maximum_players))
@@ -308,7 +308,7 @@
// Ultimate randomizing code right here // Ultimate randomizing code right here
for(var/mob/dead/new_player/player in GLOB.player_list) for(var/mob/dead/new_player/player in GLOB.player_list)
if(player.client && player.ready) if(player.client && player.ready == PLAYER_READY_TO_PLAY)
players += player players += player
// Shuffling, the players list is now ping-independent!!! // Shuffling, the players list is now ping-independent!!!
@@ -316,7 +316,7 @@
players = shuffle(players) players = shuffle(players)
for(var/mob/dead/new_player/player in players) for(var/mob/dead/new_player/player in players)
if(player.client && player.ready) if(player.client && player.ready == PLAYER_READY_TO_PLAY)
if(role in player.client.prefs.be_special) if(role in player.client.prefs.be_special)
if(!jobban_isbanned(player, "Syndicate") && !jobban_isbanned(player, role)) //Nodrak/Carn: Antag Job-bans if(!jobban_isbanned(player, "Syndicate") && !jobban_isbanned(player, role)) //Nodrak/Carn: Antag Job-bans
if(age_check(player.client)) //Must be older than the minimum age if(age_check(player.client)) //Must be older than the minimum age
@@ -330,7 +330,7 @@
if(candidates.len < recommended_enemies) if(candidates.len < recommended_enemies)
for(var/mob/dead/new_player/player in players) for(var/mob/dead/new_player/player in players)
if(player.client && player.ready) if(player.client && player.ready == PLAYER_READY_TO_PLAY)
if(!(role in player.client.prefs.be_special)) // We don't have enough people who want to be antagonist, make a seperate list of people who don't want to be one if(!(role in player.client.prefs.be_special)) // We don't have enough people who want to be antagonist, make a seperate list of people who don't want to be one
if(!jobban_isbanned(player, "Syndicate") && !jobban_isbanned(player, role)) //Nodrak/Carn: Antag Job-bans if(!jobban_isbanned(player, "Syndicate") && !jobban_isbanned(player, role)) //Nodrak/Carn: Antag Job-bans
drafted += player.mind drafted += player.mind
@@ -352,13 +352,7 @@
else // Not enough scrubs, ABORT ABORT ABORT else // Not enough scrubs, ABORT ABORT ABORT
break break
/*
if(candidates.len < recommended_enemies && override_jobbans) //If we still don't have enough people, we're going to start drafting banned people.
for(var/mob/dead/new_player/player in players)
if (player.client && player.ready)
if(jobban_isbanned(player, "Syndicate") || jobban_isbanned(player, roletext)) //Nodrak/Carn: Antag Job-bans
drafted += player.mind
*/
if(restricted_jobs) if(restricted_jobs)
for(var/datum/mind/player in drafted) // Remove people who can't be an antagonist for(var/datum/mind/player in drafted) // Remove people who can't be an antagonist
for(var/job in restricted_jobs) for(var/job in restricted_jobs)
@@ -381,17 +375,12 @@
// recommended_enemies if the number of people with that role set to yes is less than recomended_enemies, // recommended_enemies if the number of people with that role set to yes is less than recomended_enemies,
// Less if there are not enough valid players in the game entirely to make recommended_enemies. // Less if there are not enough valid players in the game entirely to make recommended_enemies.
/*
/datum/game_mode/proc/check_player_role_pref(var/role, var/mob/dead/new_player/player)
if(player.preferences.be_special & role)
return 1
return 0
*/
/datum/game_mode/proc/num_players() /datum/game_mode/proc/num_players()
. = 0 . = 0
for(var/mob/dead/new_player/P in GLOB.player_list) for(var/mob/dead/new_player/P in GLOB.player_list)
if(P.client && P.ready) if(P.client && P.ready == PLAYER_READY_TO_PLAY)
. ++ . ++
/////////////////////////////////// ///////////////////////////////////

View File

@@ -658,7 +658,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
var/n_p = 1 //autowin var/n_p = 1 //autowin
if (SSticker.current_state == GAME_STATE_SETTING_UP) if (SSticker.current_state == GAME_STATE_SETTING_UP)
for(var/mob/dead/new_player/P in GLOB.player_list) for(var/mob/dead/new_player/P in GLOB.player_list)
if(P.client && P.ready && P.mind!=owner) if(P.client && P.ready == PLAYER_READY_TO_PLAY && P.mind!=owner)
n_p ++ n_p ++
else if (SSticker.IsRoundInProgress()) else if (SSticker.IsRoundInProgress())
for(var/mob/living/carbon/human/P in GLOB.player_list) for(var/mob/living/carbon/human/P in GLOB.player_list)

View File

@@ -1,4 +1,4 @@
#define LINKIFY_READY(string, value) "<a href='byond://?src=\ref[src];ready=[value]'>[string]</a>"
/mob/dead/new_player /mob/dead/new_player
var/ready = 0 var/ready = 0
@@ -30,20 +30,20 @@
return return
/mob/dead/new_player/proc/new_player_panel() /mob/dead/new_player/proc/new_player_panel()
var/output = "<center><p><a href='byond://?src=\ref[src];show_preferences=1'>Setup Character</a></p>"
var/output = "<center><p><a href='byond://?src=\ref[src];show_preferences=1'>Setup Character</A></p>" if(SSticker && SSticker.current_state <= GAME_STATE_PREGAME)
switch(ready)
if(!SSticker || SSticker.current_state <= GAME_STATE_PREGAME) if(PLAYER_NOT_READY)
if(ready) output += "<p>\[ [LINKIFY_READY("Ready", PLAYER_READY_TO_PLAY)] | <b>Not Ready</b> | [LINKIFY_READY("Observe", PLAYER_READY_TO_OBSERVE)] \]</p>"
output += "<p>\[ <b>Ready</b> | <a href='byond://?src=\ref[src];ready=0'>Not Ready</a> \]</p>" if(PLAYER_READY_TO_PLAY)
else output += "<p>\[ <b>Ready</b> | [LINKIFY_READY("Not Ready", PLAYER_NOT_READY)] | [LINKIFY_READY("Observe", PLAYER_READY_TO_OBSERVE)] \]</p>"
output += "<p>\[ <a href='byond://?src=\ref[src];ready=1'>Ready</a> | <b>Not Ready</b> \]</p>" if(PLAYER_READY_TO_OBSERVE)
output += "<p>\[ [LINKIFY_READY("Ready", PLAYER_READY_TO_PLAY)] | [LINKIFY_READY("Not Ready", PLAYER_NOT_READY)] | <b> Observe </b> \]</p>"
else else
output += "<p><a href='byond://?src=\ref[src];manifest=1'>View the Crew Manifest</A></p>" output += "<p><a href='byond://?src=\ref[src];manifest=1'>View the Crew Manifest</a></p>"
output += "<p><a href='byond://?src=\ref[src];late_join=1'>Join Game!</A></p>" output += "<p><a href='byond://?src=\ref[src];late_join=1'>Join Game!</a></p>"
output += "<p>[LINKIFY_READY("Observe", PLAYER_READY_TO_OBSERVE)]</p>"
output += "<p><a href='byond://?src=\ref[src];observe=1'>Observe</A></p>"
if(!IsGuestKey(src.key)) if(!IsGuestKey(src.key))
if (SSdbcore.Connect()) if (SSdbcore.Connect())
@@ -65,7 +65,7 @@
output += "</center>" output += "</center>"
//src << browse(output,"window=playersetup;size=210x240;can_close=0") //src << browse(output,"window=playersetup;size=210x240;can_close=0")
var/datum/browser/popup = new(src, "playersetup", "<div align='center'>New Player Options</div>", 220, 265) var/datum/browser/popup = new(src, "playersetup", "<div align='center'>New Player Options</div>", 250, 265)
popup.set_window_options("can_close=0") popup.set_window_options("can_close=0")
popup.set_content(output) popup.set_content(output)
popup.open(0) popup.open(0)
@@ -108,42 +108,23 @@
return 1 return 1
if(href_list["ready"]) if(href_list["ready"])
if(!SSticker || SSticker.current_state <= GAME_STATE_PREGAME) // Make sure we don't ready up after the round has started if(SSticker)
ready = text2num(href_list["ready"]) var/tready = text2num(href_list["ready"])
//Avoid updating ready if we're after PREGAME (they should use latejoin instead)
//This is likely not an actual issue but I don't have time to prove that this
//no longer is required
if(SSticker.current_state <= GAME_STATE_PREGAME)
ready = tready
//if it's post initialisation and they're trying to observe we do the needful
if(!SSticker.current_state < GAME_STATE_PREGAME && tready == PLAYER_READY_TO_OBSERVE)
ready = tready
make_me_an_observer()
return
if(href_list["refresh"]) if(href_list["refresh"])
src << browse(null, "window=playersetup") //closes the player setup window src << browse(null, "window=playersetup") //closes the player setup window
new_player_panel() new_player_panel()
if(href_list["observe"])
if(alert(src,"Are you sure you wish to observe? You will not be able to play this round!","Player Setup","Yes","No") == "Yes")
if(!client)
return 1
var/mob/dead/observer/observer = new()
spawning = 1
observer.started_as_observer = 1
close_spawn_windows()
var/obj/O = locate("landmark*Observer-Start")
to_chat(src, "<span class='notice'>Now teleporting.</span>")
if (O)
observer.loc = O.loc
else
to_chat(src, "<span class='notice'>Teleporting failed. The map is probably still loading...</span>")
observer.key = key
observer.client = client
observer.set_ghost_appearance()
if(observer.client && observer.client.prefs)
observer.real_name = observer.client.prefs.real_name
observer.name = observer.real_name
observer.update_icon()
observer.stop_sound_channel(CHANNEL_LOBBYMUSIC)
QDEL_NULL(mind)
qdel(src)
return 1
if(href_list["late_join"]) if(href_list["late_join"])
if(!SSticker || !SSticker.IsRoundInProgress()) if(!SSticker || !SSticker.IsRoundInProgress())
to_chat(usr, "<span class='danger'>The round is either not ready, or has already finished...</span>") to_chat(usr, "<span class='danger'>The round is either not ready, or has already finished...</span>")
@@ -273,6 +254,44 @@
return return
to_chat(src, "<span class='notice'>Vote successful.</span>") to_chat(src, "<span class='notice'>Vote successful.</span>")
//When you cop out of the round (NB: this HAS A SLEEP FOR PLAYER INPUT IN IT)
/mob/dead/new_player/proc/make_me_an_observer()
if(QDELETED(src) || !src.client)
ready = PLAYER_NOT_READY
return FALSE
var/this_is_like_playing_right = alert(src,"Are you sure you wish to observe? You will not be able to play this round!","Player Setup","Yes","No")
if(QDELETED(src) || !src.client || this_is_like_playing_right != "Yes")
ready = PLAYER_NOT_READY
src << browse(null, "window=playersetup") //closes the player setup window
new_player_panel()
return FALSE
var/mob/dead/observer/observer = new()
spawning = TRUE
observer.started_as_observer = TRUE
close_spawn_windows()
var/obj/O = locate("landmark*Observer-Start")
to_chat(src, "<span class='notice'>Now teleporting.</span>")
if (O)
observer.loc = O.loc
else
to_chat(src, "<span class='notice'>Teleporting failed. Ahelp an admin please</span>")
stack_trace("There's no freaking observer landmark available on this map or you're making observers before the map is initialised")
observer.key = key
observer.client = client
observer.set_ghost_appearance()
if(observer.client && observer.client.prefs)
observer.real_name = observer.client.prefs.real_name
observer.name = observer.real_name
observer.update_icon()
observer.stop_sound_channel(CHANNEL_LOBBYMUSIC)
QDEL_NULL(mind)
qdel(src)
return TRUE
/mob/dead/new_player/proc/IsJobAvailable(rank) /mob/dead/new_player/proc/IsJobAvailable(rank)
var/datum/job/job = SSjob.GetJob(rank) var/datum/job/job = SSjob.GetJob(rank)
if(!job) if(!job)