diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 220abd17f2c..75d9f5c79f4 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1867,6 +1867,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) #undef DELTA_CALC +// Should NEVER be used in a proc that has waitfor set to FALSE/0. #define UNTIL(X) while(!(X)) stoplag() /* diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index f6bf7f7b5eb..9bbf7bad193 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -66,9 +66,7 @@ var/timeout = timeout_override || alert.timeout if(timeout) - spawn(timeout) - if(alert.timeout && alerts[category] == alert && world.time >= alert.timeout) - clear_alert(category) + addtimer(CALLBACK(alert, /obj/screen/alert/.proc/do_timeout, src, category), timeout) alert.timeout = world.time + timeout - world.tick_lag return alert @@ -98,7 +96,6 @@ var/alerttooltipstyle = "" var/override_alerts = FALSE //If it is overriding other alerts of the same type - /obj/screen/alert/MouseEntered(location,control,params) openToolTip(usr, src, params, title = name, content = desc, theme = alerttooltipstyle) @@ -106,6 +103,12 @@ /obj/screen/alert/MouseExited() closeToolTip(usr) +/obj/screen/alert/proc/do_timeout(mob/M, category) + if(!M || !M.alerts) + return + + if(timeout && M.alerts[category] == src && world.time >= timeout) + M.clear_alert(category) //Gas alerts /obj/screen/alert/not_enough_oxy @@ -590,6 +593,8 @@ so as to remain in compliance with the most up-to-date laws." I.plane = FLOAT_PLANE + 1 overlays += I + qdel(O) + /obj/screen/alert/notify_soulstone name = "Soul Stone" desc = "Someone is trying to capture your soul in a soul stone. Click to allow it." diff --git a/code/controllers/subsystem/ghost_spawns.dm b/code/controllers/subsystem/ghost_spawns.dm index a2fbc36fe35..21088798a91 100644 --- a/code/controllers/subsystem/ghost_spawns.dm +++ b/code/controllers/subsystem/ghost_spawns.dm @@ -14,26 +14,27 @@ SUBSYSTEM_DEF(ghost_spawns) /datum/controller/subsystem/ghost_spawns/fire() if(!polls_active) return + if(!currently_polling) // if polls_active is TRUE then this shouldn't happen, but still.. + currently_polling = list() for(var/poll in currently_polling) var/datum/candidate_poll/P = poll if(P.time_left() <= 0) polling_finished(P) -/datum/controller/subsystem/ghost_spawns/Initialize(start_timeofday) - currently_polling = list() - return ..() - // Use this proc (SSghost_spawns.poll_candidates) instead of /proc/pollCandidates to poll for candidates! +// Should NEVER be used in a proc that has waitfor set to FALSE/0 (due to #define UNTIL) /datum/controller/subsystem/ghost_spawns/proc/poll_candidates(question = "Would you like to play a special role?", role, antag_age_check = FALSE, poll_time = 30 SECONDS, ignore_respawnability = FALSE, min_hours = 0, flash_window = TRUE, check_antaghud = TRUE, source) log_debug("Polling candidates [role ? "for [get_roletext(role)]" : "\"[question]\""] for [poll_time / 10] seconds") + // Start firing polls_active = TRUE total_polls++ var/datum/candidate_poll/P = new(role, question, poll_time) - currently_polling += P + LAZYADD(currently_polling, P) + // We're the poll closest to completion if(!next_poll_to_finish || poll_time < next_poll_to_finish.time_left()) next_poll_to_finish = P @@ -43,7 +44,7 @@ SUBSYSTEM_DEF(ghost_spawns) if(!is_eligible(M)) continue - M << 'sound/misc/notice2.ogg' + SEND_SOUND(M, 'sound/misc/notice2.ogg') if(flash_window) window_flash(M.client) @@ -67,6 +68,7 @@ SUBSYSTEM_DEF(ghost_spawns) A.show_time_left = TRUE A.poll = alert_poll + // Sign up inheritance and stacking var/inherited_sign_up = FALSE var/num_stack = 1 for(var/existing_poll in currently_polling) @@ -138,13 +140,15 @@ SUBSYSTEM_DEF(ghost_spawns) // Called when polling is finished for a /datum/candidate_poll /datum/controller/subsystem/ghost_spawns/proc/polling_finished(datum/candidate_poll/P) // Trim players who aren't eligible anymore - var/len_pre_trim = P.signed_up.len + var/len_pre_trim = length(P.signed_up) P.trim_candidates() - log_debug("Candidate poll [P.role ? "for [get_roletext(P.role)]" : "\"[P.question]\""] finished. [len_pre_trim] players signed up, [P.signed_up.len] after trimming") + log_debug("Candidate poll [P.role ? "for [get_roletext(P.role)]" : "\"[P.question]\""] finished. [len_pre_trim] players signed up, [length(P.signed_up)] after trimming") P.finished = TRUE currently_polling -= P - if(!currently_polling.len) + + // Determine which is the next poll closest the completion or "disable" firing if there's none + if(!length(currently_polling)) polls_active = FALSE next_poll_to_finish = null else if(P == next_poll_to_finish) @@ -155,9 +159,9 @@ SUBSYSTEM_DEF(ghost_spawns) next_poll_to_finish = P2 /datum/controller/subsystem/ghost_spawns/stat_entry(msg) - msg += "Active: [currently_polling.len] | Total: [total_polls]" + msg += "Active: [length(currently_polling)] | Total: [total_polls]" if(next_poll_to_finish) - msg += " | Next: [DisplayTimeText(next_poll_to_finish.time_left())] ([next_poll_to_finish.signed_up.len] candidates)" + msg += " | Next: [DisplayTimeText(next_poll_to_finish.time_left())] ([length(next_poll_to_finish.signed_up)] candidates)" ..(msg) // The datum that describes one instance of candidate polling @@ -190,7 +194,7 @@ SUBSYSTEM_DEF(ghost_spawns) if(time_left() <= 0) if(!silent) to_chat(M, "Sorry, you were too late for the consideration!") - M << 'sound/machines/buzz-sigh.ogg' + SEND_SOUND(M, 'sound/machines/buzz-sigh.ogg') return signed_up += M diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index fc3689a823d..3b78c9daf3e 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -423,7 +423,7 @@ proc/display_roundstart_logout_report() /datum/game_mode/proc/replace_jobbanned_player(mob/living/M, role_type) var/list/mob/dead/observer/candidates = SSghost_spawns.poll_candidates("Do you want to play as a [role_type]?", role_type, FALSE, 10 SECONDS) var/mob/dead/observer/theghost = null - if(candidates.len) + if(length(candidates)) theghost = pick(candidates) to_chat(M, "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!") message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(M)]) to replace a jobbanned player.") diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm index 75aeefa5d1a..de2da9fbf64 100644 --- a/code/modules/events/blob.dm +++ b/code/modules/events/blob.dm @@ -13,13 +13,13 @@ return kill() var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as a blob infested mouse?", ROLE_BLOB, TRUE, source = /mob/living/simple_animal/mouse/blobinfected) - if(!candidates.len) + if(!length(candidates)) return kill() var/list/vents = list() for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in GLOB.all_vent_pumps) if(is_station_level(temp_vent.loc.z) && !temp_vent.welded) - if(temp_vent.parent.other_atmosmch.len > 50) + if(length(temp_vent.parent.other_atmosmch) > 50) vents += temp_vent var/obj/vent = pick(vents)