diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index 222002f512..65c7145d8f 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -444,12 +444,8 @@
candidates -= M
/proc/pollGhostCandidates(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, ignore_category = null, flashwindow = TRUE)
- var/list/candidates = list()
-
- for(var/mob/dead/observer/G in GLOB.player_list)
- if(G.can_reenter_round(TRUE))
- candidates += G
-
+ var/datum/element/ghost_role_eligibility/eligibility = SSdcs.GetElement(/datum/element/ghost_role_eligibility)
+ var/list/candidates = eligibility.get_all_ghost_role_eligible()
return pollCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category, flashwindow, candidates)
/proc/pollCandidates(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, ignore_category = null, flashwindow = TRUE, list/group = null)
diff --git a/code/_globalvars/misc.dm b/code/_globalvars/misc.dm
index af31e2b5a5..ec3593ee9d 100644
--- a/code/_globalvars/misc.dm
+++ b/code/_globalvars/misc.dm
@@ -23,6 +23,8 @@ GLOBAL_VAR_INIT(bsa_unlock, FALSE) //BSA unlocked by head ID swipes
GLOBAL_LIST_EMPTY(player_details) // ckey -> /datum/player_details
+GLOBAL_LIST_EMPTY(clientless_round_timeouts) // ckey -> time that ckey can rejoin round
+
// All religion stuff
GLOBAL_VAR(religion)
GLOBAL_VAR(deity)
diff --git a/code/datums/elements/ghost_role_eligibility.dm b/code/datums/elements/ghost_role_eligibility.dm
new file mode 100644
index 0000000000..8ecb579bc8
--- /dev/null
+++ b/code/datums/elements/ghost_role_eligibility.dm
@@ -0,0 +1,54 @@
+/datum/element/ghost_role_eligibility
+ element_flags = ELEMENT_DETACH
+ var/list/timeouts = list()
+ var/list/mob/eligible_mobs = list()
+
+/datum/element/ghost_role_eligibility/Attach(datum/target,penalize = FALSE)
+ . = ..()
+ if(!ismob(target))
+ return ELEMENT_INCOMPATIBLE
+ var/mob/M = target
+ if(!(M in eligible_mobs))
+ eligible_mobs += M
+ if(penalize) //penalizing them from making a ghost role / midround antag comeback right away.
+ var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES
+ var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES
+ if(world.time < roundstart_quit_limit) //add up the time difference to their antag rolling penalty if they quit before half a (ingame) hour even passed.
+ penalty += roundstart_quit_limit - world.time
+ if(penalty)
+ penalty += world.realtime
+ if(penalty - SSshuttle.realtimeofstart > SSshuttle.auto_call + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
+ penalty = CANT_REENTER_ROUND
+ if(!(M.ckey in timeouts))
+ timeouts += M.ckey
+ timeouts[M.ckey] = 0
+ timeouts[M.ckey] = max(timeouts[M.ckey],penalty)
+
+/datum/element/ghost_role_eligibility/Detach(mob/M)
+ . = ..()
+ if(M in eligible_mobs)
+ eligible_mobs -= M
+
+/datum/element/ghost_role_eligibility/proc/get_all_ghost_role_eligible(silent = FALSE)
+ var/list/candidates = list()
+ for(var/m in eligible_mobs)
+ var/mob/M = m
+ if(M.can_reenter_round(TRUE))
+ candidates += M
+ return candidates
+
+/mob/proc/can_reenter_round(silent = FALSE)
+ var/datum/element/ghost_role_eligibility/eli = SSdcs.GetElement(/datum/element/ghost_role_eligibility)
+ return eli.can_reenter_round(src,silent)
+
+/datum/element/ghost_role_eligibility/proc/can_reenter_round(var/mob/M,silent = FALSE)
+ if(!(M in eligible_mobs))
+ return FALSE
+ if(!(M.ckey in timeouts))
+ return TRUE
+ var/timeout = timeouts[M.ckey]
+ if(timeout != CANT_REENTER_ROUND && timeout <= world.realtime)
+ return TRUE
+ if(!silent && M.client)
+ to_chat(M, "You are unable to reenter the round[timeout != CANT_REENTER_ROUND ? " yet. Your ghost role blacklist will expire in [DisplayTimeText(timeout - world.realtime)]" : ""].")
+ return FALSE
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
index 91ac73d142..32c076b69a 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
@@ -17,10 +17,10 @@
var/list/living_antags = list()
var/list/dead_players = list()
var/list/list_observers = list()
+ var/list/ghost_eligible = list()
/datum/dynamic_ruleset/midround/from_ghosts
weight = 0
- required_type = /mob/dead/observer
/// Whether the ruleset should call generate_ruleset_body or not.
var/makeBody = TRUE
@@ -34,6 +34,8 @@
living_players = trim_list(mode.current_players[CURRENT_LIVING_PLAYERS])
living_antags = trim_list(mode.current_players[CURRENT_LIVING_ANTAGS])
list_observers = trim_list(mode.current_players[CURRENT_OBSERVERS])
+ var/datum/element/ghost_role_eligibility/eligibility = SSdcs.GetElement(/datum/element/ghost_role_eligibility)
+ ghost_eligible = trim_list(eligibility.get_all_ghost_role_eligible())
/datum/dynamic_ruleset/midround/proc/trim_list(list/L = list())
var/list/trimmed_list = L.Copy()
@@ -70,6 +72,25 @@
continue
return trimmed_list
+/datum/dynamic_ruleset/midround/from_ghosts/trim_list(list/L = list())
+ var/list/trimmed_list = L.Copy()
+ for(var/mob/M in trimmed_list)
+ if (!M.client) // Are they connected?
+ trimmed_list.Remove(M)
+ continue
+ if(!mode.check_age(M.client, minimum_required_age))
+ trimmed_list.Remove(M)
+ continue
+ if(antag_flag_override)
+ if(!(antag_flag_override in M.client.prefs.be_special) || jobban_isbanned(M.ckey, antag_flag_override))
+ trimmed_list.Remove(M)
+ continue
+ else
+ if(!(antag_flag in M.client.prefs.be_special) || jobban_isbanned(M.ckey, antag_flag))
+ trimmed_list.Remove(M)
+ continue
+ return trimmed_list
+
// You can then for example prompt dead players in execute() to join as strike teams or whatever
// Or autotator someone
@@ -91,11 +112,15 @@
return FALSE
return TRUE
+/datum/dynamic_ruleset/midround/from_ghosts/ready(forced = FALSE)
+ if (required_candidates > ghost_eligible.len)
+ SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
+ return FALSE
+ return ..()
+
+
/datum/dynamic_ruleset/midround/from_ghosts/execute()
- var/list/possible_candidates = list()
- possible_candidates.Add(dead_players)
- possible_candidates.Add(list_observers)
- var/application_successful = send_applications(possible_candidates)
+ var/application_successful = send_applications(ghost_eligible)
return assigned.len > 0 && application_successful
/// This sends a poll to ghosts if they want to be a ghost spawn from a ruleset.
@@ -292,9 +317,6 @@
var/datum/mind/wizard
/datum/dynamic_ruleset/midround/from_ghosts/wizard/ready(forced = FALSE)
- if (required_candidates > (dead_players.len + list_observers.len))
- SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
- return FALSE
if(GLOB.wizardstart.len == 0)
log_admin("Cannot accept Wizard ruleset. Couldn't find any wizard spawn points.")
message_admins("Cannot accept Wizard ruleset. Couldn't find any wizard spawn points.")
@@ -354,12 +376,6 @@
required_candidates = operative_cap[indice_pop]
return ..()
-/datum/dynamic_ruleset/midround/from_ghosts/nuclear/ready(forced = FALSE)
- if (required_candidates > (dead_players.len + list_observers.len))
- SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
- return FALSE
- return ..()
-
/datum/dynamic_ruleset/midround/from_ghosts/nuclear/finish_setup(mob/new_character, index)
new_character.mind.special_role = "Nuclear Operative"
new_character.mind.assigned_role = "Nuclear Operative"
@@ -391,12 +407,6 @@
high_population_requirement = 50
repeatable = TRUE
-/datum/dynamic_ruleset/midround/from_ghosts/blob/ready(forced = FALSE)
- if (required_candidates > (dead_players.len + list_observers.len))
- SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
- return FALSE
- return ..()
-
/datum/dynamic_ruleset/midround/from_ghosts/blob/generate_ruleset_body(mob/applicant)
var/body = applicant.become_overmind()
return body
@@ -423,12 +433,6 @@
repeatable = TRUE
var/list/vents = list()
-/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/ready(forced = FALSE)
- if (required_candidates > (dead_players.len + list_observers.len))
- SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
- return FALSE
- return ..()
-
/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/execute()
// 50% chance of being incremented by one
required_candidates += prob(50)
@@ -523,12 +527,6 @@
requirements = list(30,30,20,20,15,10,10,10,10,5) // yes, it can even happen in "extended"!
high_population_requirement = 5
-/datum/dynamic_ruleset/midround/from_ghosts/sentient_disease/ready(forced = FALSE)
- if (required_candidates > (dead_players.len + list_observers.len))
- SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
- return FALSE
- return ..()
-
/datum/dynamic_ruleset/midround/from_ghosts/sentient_disease/generate_ruleset_body(mob/applicant)
var/mob/camera/disease/virus = new /mob/camera/disease(SSmapping.get_station_center())
applicant.transfer_ckey(virus, FALSE)
@@ -563,9 +561,6 @@
deadMobs++
if(deadMobs < REVENANT_SPAWN_THRESHOLD)
return FALSE
- if(required_candidates > (dead_players.len + list_observers.len))
- SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
- return FALSE
for(var/mob/living/L in GLOB.dead_mob_list) //look for any dead bodies
var/turf/T = get_turf(L)
if(T && is_station_level(T.z))
@@ -611,9 +606,6 @@
var/list/spawn_locs = list()
/datum/dynamic_ruleset/midround/from_ghosts/slaughter_demon/ready(forced = FALSE)
- if(required_candidates > (dead_players.len + list_observers.len))
- SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
- return FALSE
for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
if(isturf(L.loc))
spawn_locs += L.loc
@@ -663,9 +655,6 @@
repeatable = TRUE
/datum/dynamic_ruleset/midround/from_ghosts/abductors/ready(forced = FALSE)
- if(required_candidates > (dead_players.len + list_observers.len))
- SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
- return FALSE
team = new /datum/team/abductor_team
if(team.team_number > ABDUCTOR_MAX_TEAMS)
return FALSE
@@ -703,9 +692,6 @@
var/spawn_loc
/datum/dynamic_ruleset/midround/from_ghosts/ninja/ready(forced = FALSE)
- if(required_candidates > (dead_players.len + list_observers.len))
- SSblackbox.record_feedback("tally","dynamic",1,"Times rulesets rejected due to not enough ghosts")
- return FALSE
if(!spawn_loc)
var/list/spawn_locs = list()
for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm
index 7a83893f8b..c6c5547e54 100644
--- a/code/game/objects/items/holy_weapons.dm
+++ b/code/game/objects/items/holy_weapons.dm
@@ -479,10 +479,10 @@
possessed = TRUE
- var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as the spirit of [user.real_name]'s blade?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_POSSESSED_BLADE)
+ var/list/mob/candidates = pollGhostCandidates("Do you want to play as the spirit of [user.real_name]'s blade?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_POSSESSED_BLADE)
if(LAZYLEN(candidates))
- var/mob/dead/observer/C = pick(candidates)
+ var/mob/C = pick(candidates)
var/mob/living/simple_animal/shade/S = new(src)
S.real_name = name
S.name = name
diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm
index fdc85475fb..8ee6981fa4 100644
--- a/code/game/objects/structures/ghost_role_spawners.dm
+++ b/code/game/objects/structures/ghost_role_spawners.dm
@@ -618,6 +618,8 @@
O.equip(new_spawn, FALSE, new_spawn.client)
SSjob.equip_loadout(null, new_spawn, FALSE)
SSquirks.AssignQuirks(new_spawn, new_spawn.client, TRUE, TRUE, null, FALSE, new_spawn)
+ new_spawn.AddElement(/datum/element/ghost_role_eligibility)
+ ADD_TRAIT(new_spawn, TRAIT_SIXTHSENSE, "Ghost Cafe")
/datum/outfit/ghostcafe
name = "ID, jumpsuit and shoes"
diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm
index 09a8f692d8..7675f858ee 100644
--- a/code/modules/admin/verbs/one_click_antag.dm
+++ b/code/modules/admin/verbs/one_click_antag.dm
@@ -137,9 +137,9 @@
/datum/admins/proc/makeWizard()
- var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you wish to be considered for the position of a Wizard Foundation 'diplomat'?", ROLE_WIZARD, null)
+ var/list/mob/candidates = pollGhostCandidates("Do you wish to be considered for the position of a Wizard Foundation 'diplomat'?", ROLE_WIZARD, null)
- var/mob/dead/observer/selected = pick_n_take(candidates)
+ var/mob/selected = pick_n_take(candidates)
var/mob/living/carbon/human/new_character = makeBody(selected)
new_character.mind.make_Wizard()
@@ -214,9 +214,9 @@
/datum/admins/proc/makeNukeTeam()
var/datum/game_mode/nuclear/temp = new
- var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you wish to be considered for a nuke team being sent in?", ROLE_OPERATIVE, temp)
- var/list/mob/dead/observer/chosen = list()
- var/mob/dead/observer/theghost = null
+ var/list/mob/candidates = pollGhostCandidates("Do you wish to be considered for a nuke team being sent in?", ROLE_OPERATIVE, temp)
+ var/list/mob/chosen = list()
+ var/mob/theghost = null
if(candidates.len)
var/numagents = 5
@@ -378,7 +378,7 @@
ertemplate.enforce_human = prefs["enforce_human"]["value"] == "Yes" ? TRUE : FALSE
ertemplate.opendoors = prefs["open_armory"]["value"] == "Yes" ? TRUE : FALSE
- var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you wish to be considered for [ertemplate.polldesc] ?", "deathsquad", null)
+ var/list/mob/candidates = pollGhostCandidates("Do you wish to be considered for [ertemplate.polldesc] ?", "deathsquad", null)
var/teamSpawned = FALSE
if(candidates.len > 0)
@@ -404,7 +404,7 @@
numagents--
continue // This guy's unlucky, not enough spawn points, we skip him.
var/spawnloc = spawnpoints[numagents]
- var/mob/dead/observer/chosen_candidate = pick(candidates)
+ var/mob/chosen_candidate = pick(candidates)
candidates -= chosen_candidate
if(!chosen_candidate.key)
continue
diff --git a/code/modules/antagonists/blob/blob/powers.dm b/code/modules/antagonists/blob/blob/powers.dm
index e49d186362..76c9c6f482 100644
--- a/code/modules/antagonists/blob/blob/powers.dm
+++ b/code/modules/antagonists/blob/blob/powers.dm
@@ -156,7 +156,7 @@
if(!can_buy(40))
return
- var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as a [blob_reagent_datum.name] blobbernaut?", ROLE_BLOB, null, ROLE_BLOB, 50) //players must answer rapidly
+ var/list/mob/candidates = pollGhostCandidates("Do you want to play as a [blob_reagent_datum.name] blobbernaut?", ROLE_BLOB, null, ROLE_BLOB, 50) //players must answer rapidly
if(LAZYLEN(candidates)) //if we got at least one candidate, they're a blobbernaut now.
B.max_integrity = initial(B.max_integrity) * 0.25 //factories that produced a blobbernaut have much lower health
B.obj_integrity = min(B.obj_integrity, B.max_integrity)
@@ -171,7 +171,7 @@
blobber.update_icons()
blobber.adjustHealth(blobber.maxHealth * 0.5)
blob_mobs += blobber
- var/mob/dead/observer/C = pick(candidates)
+ var/mob/C = pick(candidates)
C.transfer_ckey(blobber)
SEND_SOUND(blobber, sound('sound/effects/blobattack.ogg'))
SEND_SOUND(blobber, sound('sound/effects/attackblob.ogg'))
diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm
index ae9932e96f..361b2a7517 100644
--- a/code/modules/client/client_defines.dm
+++ b/code/modules/client/client_defines.dm
@@ -80,7 +80,3 @@
var/next_keysend_reset = 0
var/next_keysend_trip_reset = 0
var/keysend_tripped = FALSE
-
- // stops players from coming back through ghost/midround roles after suicide/cryo
- // for a duration set by CONFIG_GET(number/suicide_reenter_round_timer) and CONFIG_GET(number/roundstart_suicide_time_limit)
- var/reenter_round_timeout = 0
diff --git a/code/modules/events/holiday/xmas.dm b/code/modules/events/holiday/xmas.dm
index 65d96ad150..ea63ee611f 100644
--- a/code/modules/events/holiday/xmas.dm
+++ b/code/modules/events/holiday/xmas.dm
@@ -75,7 +75,7 @@
/datum/round_event/santa/start()
var/list/candidates = pollGhostCandidates("Santa is coming to town! Do you want to be Santa?", poll_time=150)
if(LAZYLEN(candidates))
- var/mob/dead/observer/C = pick(candidates)
+ var/mob/C = pick(candidates)
santa = new /mob/living/carbon/human(pick(GLOB.blobstart))
C.transfer_ckey(santa, FALSE)
diff --git a/code/modules/mob/dead/observer/login.dm b/code/modules/mob/dead/observer/login.dm
index bf86a97574..1b328dbc69 100644
--- a/code/modules/mob/dead/observer/login.dm
+++ b/code/modules/mob/dead/observer/login.dm
@@ -18,6 +18,3 @@
update_icon(preferred_form)
updateghostimages()
-
- client.reenter_round_timeout = max(client.reenter_round_timeout, clientless_round_timeout)
- clientless_round_timeout = client.reenter_round_timeout
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 499236e8ac..72d68c6721 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -19,7 +19,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
hud_type = /datum/hud/ghost
movement_type = GROUND | FLYING
var/can_reenter_corpse
- var/clientless_round_timeout = 0 //mobs will lack a client as long as their player is disconnected. See client_defines.dm "reenter_round_timeout"
var/datum/hud/living/carbon/hud = null // hud
var/bootime = 0
var/started_as_observer //This variable is set to 1 when you enter the game as an observer.
@@ -135,7 +134,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
AA.onNewMob(src)
. = ..()
-
+ AddElement(/datum/element/ghost_role_eligibility)
grant_all_languages()
/mob/dead/observer/get_photo_description(obj/item/camera/camera)
@@ -270,20 +269,9 @@ Works together with spawning an observer, noted above.
var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc.
SStgui.on_transfer(src, ghost) // Transfer NanoUIs.
ghost.can_reenter_corpse = can_reenter_corpse
- if(penalize) //penalizing them from making a ghost role / midround antag comeback right away.
- var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES
- var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES
- if(world.time < roundstart_quit_limit) //add up the time difference to their antag rolling penalty if they quit before half a (ingame) hour even passed.
- penalty += roundstart_quit_limit - world.time
- if(penalty)
- penalty += world.realtime
- if(penalty - SSshuttle.realtimeofstart > SSshuttle.auto_call + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
- penalty = CANT_REENTER_ROUND
- if(client)
- client.reenter_round_timeout = penalty
- else //A disconnected player (quite likely for cryopods)
- ghost.clientless_round_timeout = penalty
transfer_ckey(ghost, FALSE)
+ ghost.AddElement(/datum/element/ghost_role_eligibility,penalize) // technically already run earlier, but this adds the penalty
+ // needs to be done AFTER the ckey transfer, too
return ghost
/*
@@ -340,15 +328,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return
ghostize(0, penalize = TRUE)
-/mob/dead/observer/proc/can_reenter_round(silent = FALSE)
- var/timeout = clientless_round_timeout
- if(client)
- timeout = client.reenter_round_timeout
- if(timeout != CANT_REENTER_ROUND && timeout <= world.realtime)
- return TRUE
- if(!silent && client)
- to_chat(src, "You are unable to reenter the round[timeout != CANT_REENTER_ROUND ? " yet. Your ghost role blacklist will expire in [DisplayTimeText(timeout - world.realtime)]" : ""].")
- return FALSE
+
/mob/dead/observer/Move(NewLoc, direct)
if(updatedir)
diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm
index 1bd434b233..62c8588ac8 100644
--- a/code/modules/mob/living/simple_animal/guardian/guardian.dm
+++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm
@@ -424,9 +424,9 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
var/mob/living/simple_animal/hostile/guardian/G = input(src, "Pick the guardian you wish to reset", "Guardian Reset") as null|anything in guardians
if(G)
to_chat(src, "You attempt to reset [G.real_name]'s personality...")
- var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as [src.real_name]'s [G.real_name]?", ROLE_PAI, null, FALSE, 100)
+ var/list/mob/candidates = pollGhostCandidates("Do you want to play as [src.real_name]'s [G.real_name]?", ROLE_PAI, null, FALSE, 100)
if(LAZYLEN(candidates))
- var/mob/dead/observer/C = pick(candidates)
+ var/mob/C = pick(candidates)
to_chat(G, "Your user reset you, and your body was taken over by a ghost. Looks like they weren't happy with your performance.")
to_chat(src, "Your [G.real_name] has been successfully reset.")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(G)])")
@@ -498,10 +498,10 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
return
used = TRUE
to_chat(user, "[use_message]")
- var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as the [mob_name] of [user.real_name]?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_HOLOPARASITE)
+ var/list/mob/candidates = pollGhostCandidates("Do you want to play as the [mob_name] of [user.real_name]?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_HOLOPARASITE)
if(LAZYLEN(candidates))
- var/mob/dead/observer/C = pick(candidates)
+ var/mob/C = pick(candidates)
spawn_guardian(user, C.key)
else
to_chat(user, "[failure_message]")
diff --git a/tgstation.dme b/tgstation.dme
index 5526e5eaf0..9348e2e131 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -467,6 +467,7 @@
#include "code\datums\elements\_element.dm"
#include "code\datums\elements\cleaning.dm"
#include "code\datums\elements\earhealing.dm"
+#include "code\datums\elements\ghost_role_eligibility.dm"
#include "code\datums\helper_datums\events.dm"
#include "code\datums\helper_datums\getrev.dm"
#include "code\datums\helper_datums\icon_snapshot.dm"