From 507ee7f223641edd61b644b9cd01a5c0e8bd40f9 Mon Sep 17 00:00:00 2001
From: oranges
Date: Wed, 7 Jun 2017 01:22:00 +0000
Subject: [PATCH] Players cannot observe before PREGAME is reached
Ready | Not Ready | Observe is now a three way toggle
The player ready status has been refatored 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
---
code/__DEFINES/mobs.dm | 7 +-
code/controllers/subsystem/job.dm | 6 +-
code/controllers/subsystem/ticker.dm | 14 ++-
code/game/gamemodes/game_mode.dm | 25 ++---
code/game/gamemodes/objective.dm | 2 +-
.../modules/mob/dead/new_player/new_player.dm | 99 +++++++++++--------
6 files changed, 89 insertions(+), 64 deletions(-)
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index e5d1f4c19e1..670a1778fb1 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -2,6 +2,11 @@
//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
#define MOVE_INTENT_WALK "walk"
#define MOVE_INTENT_RUN "run"
@@ -128,4 +133,4 @@
#define INCORPOREAL_MOVE_BASIC 1
#define INCORPOREAL_MOVE_SHADOW 2 // leaves a trail of shadows
-#define INCORPOREAL_MOVE_JAUNT 3 // is blocked by holy water/salt
\ No newline at end of file
+#define INCORPOREAL_MOVE_JAUNT 3 // is blocked by holy water/salt
diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm
index 05d8dbb5b7e..731166e0a9f 100644
--- a/code/controllers/subsystem/job.dm
+++ b/code/controllers/subsystem/job.dm
@@ -224,7 +224,7 @@ SUBSYSTEM_DEF(job)
//Get the players who are ready
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
initial_players_to_assign = unassigned.len
@@ -456,7 +456,7 @@ SUBSYSTEM_DEF(job)
var/level5 = 0 //banned
var/level6 = 0 //account too young
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
if(jobban_isbanned(player, job.title))
level5++
@@ -489,7 +489,7 @@ SUBSYSTEM_DEF(job)
Debug("Popcap overflow Check observer located, Player: [player]")
to_chat(player, "You have failed to qualify for any job you desired.")
unassigned -= player
- player.ready = 0
+ player.ready = PLAYER_NOT_READY
/datum/controller/subsystem/job/Recover()
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index 2d0bcf907cd..3ad9a7eeb7b 100644
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -83,6 +83,8 @@ SUBSYSTEM_DEF(ticker)
window_flash(C, ignorepref = TRUE) //let them know lobby has opened up.
to_chat(world, "Welcome to [station_name()]!")
current_state = GAME_STATE_PREGAME
+ //Everyone who wants to be an observer is now spawned
+ create_observers()
fire()
if(GAME_STATE_PREGAME)
//lobby stats for statpanels
@@ -92,7 +94,7 @@ SUBSYSTEM_DEF(ticker)
totalPlayersReady = 0
for(var/mob/dead/new_player/player in GLOB.player_list)
++totalPlayers
- if(player.ready)
+ if(player.ready == PLAYER_READY_TO_PLAY)
++totalPlayersReady
if(start_immediately)
@@ -131,6 +133,7 @@ SUBSYSTEM_DEF(ticker)
declare_completion(force_ending)
Master.SetRunLevel(RUNLEVEL_POSTGAME)
+
/datum/controller/subsystem/ticker/proc/setup()
to_chat(world, "Starting game...")
var/init_start = world.timeofday
@@ -400,7 +403,7 @@ SUBSYSTEM_DEF(ticker)
/datum/controller/subsystem/ticker/proc/create_characters()
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
player.create_character(FALSE)
else
@@ -791,6 +794,13 @@ SUBSYSTEM_DEF(ticker)
else
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()
var/mode = trim(file2text("data/mode.txt"))
if(mode)
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 0f7bb791f27..16571a873fb 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -54,7 +54,7 @@
/datum/game_mode/proc/can_start()
var/playerC = 0
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++
if(!GLOB.Debug2)
if(playerC < required_players || (maximum_players >= 0 && playerC > maximum_players))
@@ -310,7 +310,7 @@
// Ultimate randomizing code right here
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
// Shuffling, the players list is now ping-independent!!!
@@ -318,7 +318,7 @@
players = shuffle(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(!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
@@ -332,7 +332,7 @@
if(candidates.len < recommended_enemies)
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(!jobban_isbanned(player, "Syndicate") && !jobban_isbanned(player, role)) //Nodrak/Carn: Antag Job-bans
drafted += player.mind
@@ -354,13 +354,7 @@
else // Not enough scrubs, ABORT ABORT ABORT
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)
for(var/datum/mind/player in drafted) // Remove people who can't be an antagonist
for(var/job in restricted_jobs)
@@ -383,17 +377,12 @@
// 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.
-/*
-/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()
. = 0
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)
. ++
///////////////////////////////////
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 039b4cc3a45..21b1180b3d3 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -658,7 +658,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
var/n_p = 1 //autowin
if (SSticker.current_state == GAME_STATE_SETTING_UP)
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 ++
else if (SSticker.IsRoundInProgress())
for(var/mob/living/carbon/human/P in GLOB.player_list)
diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm
index c8bc7f4ff5b..c26c1089fc7 100644
--- a/code/modules/mob/dead/new_player/new_player.dm
+++ b/code/modules/mob/dead/new_player/new_player.dm
@@ -29,21 +29,25 @@
/mob/dead/new_player/prepare_huds()
return
-/mob/dead/new_player/proc/new_player_panel()
+/mob/dead/new_player/proc/linkify_ready(string, value)
+ return "Setup Character
"
+/mob/dead/new_player/proc/new_player_panel()
+ var/output = "< href='byond://?src=\ref[src];show_preferences=1'>Setup Character
"
if(!SSticker || SSticker.current_state <= GAME_STATE_PREGAME)
- if(ready)
- output += "\[ Ready | Not Ready \]
"
- else
- output += "\[ Ready | Not Ready \]
"
+ switch(ready)
+ if(PLAYER_NOT_READY)
+ output += "\[ [linkify_ready("Ready", PLAYER_READY_TO_PLAY)] | Not Ready | [linkify_ready("Observe", PLAYER_READY_TO_OBSERVE)] \]
"
+ if(PLAYER_READY_TO_PLAY)
+ output += "\[ Ready | [linkify_ready("Not Ready", PLAYER_NOT_READY)] | [linkify_ready("Observe", PLAYER_READY_TO_OBSERVE)] \]
"
+ if(PLAYER_READY_TO_OBSERVE)
+ output += "\[ [linkify_ready("Ready", PLAYER_READY_TO_PLAY)]] | [linkify_ready("Not Ready", PLAYER_NOT_READY)] | Observe \]
"
else
output += "View the Crew Manifest
"
output += "Join Game!
"
-
- output += "Observe
"
+ output += "[linkify_ready("Observe", 2)]
"
if(!IsGuestKey(src.key))
if (SSdbcore.Connect())
@@ -108,42 +112,23 @@
return 1
if(href_list["ready"])
- if(!SSticker || SSticker.current_state <= GAME_STATE_PREGAME) // Make sure we don't ready up after the round has started
- ready = text2num(href_list["ready"])
+ if(SSticker)
+ 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"])
src << browse(null, "window=playersetup") //closes the player setup window
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, "Now teleporting.")
- if (O)
- observer.loc = O.loc
- else
- to_chat(src, "Teleporting failed. The map is probably still loading...")
- 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(!SSticker || !SSticker.IsRoundInProgress())
to_chat(usr, "The round is either not ready, or has already finished...")
@@ -273,6 +258,42 @@
return
to_chat(src, "Vote successful.")
+//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
+ 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, "Now teleporting.")
+ if (O)
+ observer.loc = O.loc
+ else
+ to_chat(src, "Teleporting failed. Ahelp an admin please")
+ 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)
var/datum/job/job = SSjob.GetJob(rank)
if(!job)