diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index d30f388df39..1f71b4cdd1c 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -522,6 +522,7 @@ so as to remain in compliance with the most up-to-date laws." var/action = NOTIFY_JUMP var/show_time_left = FALSE // If true you need to call START_PROCESSING manually var/image/time_left_overlay // The last image showing the time left + var/image/signed_up_overlay // image showing that you're signed up var/datum/candidate_poll/poll // If set, on Click() it'll register the player as a candidate /obj/screen/alert/notify_action/process() @@ -551,6 +552,9 @@ so as to remain in compliance with the most up-to-date laws." /obj/screen/alert/notify_action/Destroy() target = null + if(signed_up_overlay) + overlays -= signed_up_overlay + qdel(signed_up_overlay) return ..() /obj/screen/alert/notify_action/Click() @@ -561,9 +565,14 @@ so as to remain in compliance with the most up-to-date laws." return if(poll) - if(poll.sign_up(G)) + var/success + if(G in poll.signed_up) + success = poll.remove_candidate(G) + else + success = poll.sign_up(G) + if(success) // Add a small overlay to indicate we've signed up - display_signed_up() + update_signed_up_alert() else if(target) switch(action) if(NOTIFY_ATTACK) @@ -576,14 +585,26 @@ so as to remain in compliance with the most up-to-date laws." G.ManualFollow(target) /obj/screen/alert/notify_action/Topic(href, href_list) - if(href_list["signup"] && poll?.sign_up(usr)) - display_signed_up() + if(!href_list["signup"]) + return + if(!poll) + return + var/mob/dead/observer/G = usr + if(G in poll.signed_up) + poll.remove_candidate(G) + else + poll.sign_up(G) + update_signed_up_alert() -/obj/screen/alert/notify_action/proc/display_signed_up() - var/image/I = image('icons/mob/screen_gen.dmi', icon_state = "selector") - I.layer = FLOAT_LAYER - I.plane = FLOAT_PLANE + 2 - overlays += I +/obj/screen/alert/notify_action/proc/update_signed_up_alert() + if(!signed_up_overlay) + signed_up_overlay = image('icons/mob/screen_gen.dmi', icon_state = "selector") + signed_up_overlay.layer = FLOAT_LAYER + signed_up_overlay.plane = FLOAT_PLANE + 2 + if(usr in poll.signed_up) + overlays += signed_up_overlay + else + overlays -= signed_up_overlay /obj/screen/alert/notify_action/proc/display_stacks(stacks = 1) if(stacks <= 1) diff --git a/code/controllers/subsystem/ghost_spawns.dm b/code/controllers/subsystem/ghost_spawns.dm index 0490e764685..e9b2c2a8809 100644 --- a/code/controllers/subsystem/ghost_spawns.dm +++ b/code/controllers/subsystem/ghost_spawns.dm @@ -96,7 +96,7 @@ SUBSYSTEM_DEF(ghost_spawns) if(P != P2 && P.hash == P2.hash) // If there's already a poll for an identical mob type ongoing and the client is signed up for it, sign them up for this one if(!inherited_sign_up && (M in P2.signed_up) && P.sign_up(M, TRUE)) - A.display_signed_up() + A.update_signed_up_alert() inherited_sign_up = TRUE // This number is used to display the number of polls the alert regroups num_stack++ @@ -243,6 +243,7 @@ SUBSYSTEM_DEF(ghost_spawns) if(!silent) to_chat(M, "You have already signed up for this!") return + if(time_left() <= 0) if(!silent) to_chat(M, "Sorry, you were too late for the consideration!") @@ -251,7 +252,7 @@ SUBSYSTEM_DEF(ghost_spawns) signed_up += M if(!silent) - to_chat(M, "You have signed up for this role! A candidate will be picked randomly soon..") + to_chat(M, "You have signed up for this role! A candidate will be picked randomly soon.") // Sign them up for any other polls with the same mob type for(var/existing_poll in SSghost_spawns.currently_polling) var/datum/candidate_poll/P = existing_poll @@ -260,6 +261,40 @@ SUBSYSTEM_DEF(ghost_spawns) return TRUE +/** + * Attempts to remove a signed-up mob from a poll. + * + * Arguments: + * * M - The mob to remove from the poll, if present. + * * silent - If TRUE, no messages will be sent to M about their removal. + */ +/datum/candidate_poll/proc/remove_candidate(mob/dead/observer/M, silent = FALSE) + . = FALSE + if(!istype(M) || !M.key || !M.client) + return + if(!(M in signed_up)) + if(!silent) + to_chat(M, "You aren't signed up for this!") + return + + if(time_left() <= 0) + if(!silent) + to_chat(M, "It's too late to unregister yourself, selection has already begun!") + return + + signed_up -= M + if(!silent) + to_chat(M, "You have been unregistered as a candidate for this role. You can freely sign up again before the poll ends.") + + for(var/existing_poll in SSghost_spawns.currently_polling) + var/datum/candidate_poll/P = existing_poll + if(src != P && hash == P.hash && (M in P.signed_up)) + P.remove_candidate(M, TRUE) + return TRUE + + + + /** * Deletes any candidates who may have disconnected from the list */