Move some ghosty stuff to async

This commit is contained in:
Aronai Sieyes
2021-06-26 17:37:34 -04:00
parent ec09ddd547
commit faafdcfb5b
4 changed files with 115 additions and 50 deletions
+66 -34
View File
@@ -11,18 +11,13 @@
var/wait_time = 60 SECONDS // How long to wait until returning the list of candidates.
var/cutoff_number = 0 // If above 0, when candidates list reaches this number, further potential candidates are rejected.
/// Begin the ghost asking
/datum/ghost_query/proc/query()
// First, ask all the ghosts who want to be asked.
for(var/mob/observer/dead/D in player_list)
if(!D.MayRespawn())
continue // They can't respawn for whatever reason.
if(D.client)
if(be_special_flag && !(D.client.prefs.be_special & be_special_flag) )
continue // They don't want to see the prompt.
for(var/ban in check_bans)
if(jobban_isbanned(D, ban))
continue // They're banned from this role.
ask_question(D.client)
for(var/mob/observer/dead/D as anything in observer_mob_list)
if(evaluate_candidate(D))
ask_question(D)
// Then wait awhile.
while(!finished)
sleep(1 SECOND)
@@ -31,36 +26,73 @@
finished = TRUE
// Prune the list after the wait, incase any candidates logged out.
for(var/mob/observer/dead/D in candidates)
if(!D.client || !D.key)
candidates.Remove(D)
for(var/mob/observer/dead/D as anything in candidates)
if(!evaluate_candidate(D))
candidates -= D
// Now we're done.
finished = TRUE
return candidates
/datum/ghost_query/proc/ask_question(var/client/C)
spawn(0)
if(!C)
return
window_flash(C)
if(query_sound)
SEND_SOUND(C, sound(query_sound))
var/response = tgui_alert(C, question, "[role_name] request", list("Yes", "No", "Never for this round"))
if(response == "Yes")
response = tgui_alert(C, "Are you sure you want to play as a [role_name]?", "[role_name] request", list("Yes", "No")) // Protection from a misclick.
if(!C || !src)
return
if(response == "Yes")
if(finished || (cutoff_number && candidates.len >= cutoff_number) )
to_chat(C, "<span class='warning'>Unfortunately, you were not fast enough, and there are no more available roles. Sorry.</span>")
return
candidates.Add(C.mob)
if(cutoff_number && candidates.len >= cutoff_number)
finished = TRUE // Finish now if we're full.
else if(response == "Never for this round")
/// Test a candidate for allowance to join as this
/datum/ghost_query/proc/evaluate_candidate(mob/observer/dead/candidate)
if(!istype(candidate))
return FALSE // Changed mobs or something who knows
if(!candidate.client)
return FALSE // No client to ask
if(!candidate.MayRespawn())
return FALSE // They can't respawn for whatever reason.
if(be_special_flag && !(candidate.client.prefs.be_special & be_special_flag) )
return FALSE // They don't want to see the prompt.
for(var/ban in check_bans)
if(jobban_isbanned(candidate, ban))
return FALSE // They're banned from this role.
return TRUE
/// Send async alerts and ask for responses. Expects you to have tested D for client and type already
/datum/ghost_query/proc/ask_question(var/mob/observer/dead/D)
var/client/C = D.client
window_flash(C)
if(query_sound)
SEND_SOUND(C, sound(query_sound))
tgui_alert_async(D, question, "[role_name] request", list("Yes", "No", "Never for this round"), CALLBACK(src, .proc/get_reply), wait_time SECONDS)
/// Process an async alert response
/datum/ghost_query/proc/get_reply(response)
var/mob/observer/dead/D = usr
if(!D?.client)
return
// Unhandled are "No" and "Nevermind" responses, which should just do nothing
// This response is always fine, doesn't warrant retesting
switch(response)
if("Never for this round")
if(be_special_flag)
C.prefs.be_special ^= be_special_flag
D.client.prefs.be_special ^= be_special_flag
to_chat(D, "<span class='notice'>You will not be prompted to join similar roles to [role_name] for the rest of this round. Note: If you save your character now, it will save this permanently.</span>")
else
to_chat(D, "<span class='warning'>This type of ghost-joinable role doesn't have a role type flag associated with it, so I can't prevent future requests, sorry. Bug a dev!</span>")
if("Yes")
if(!evaluate_candidate(D)) // Failed revalidation
to_chat(D, "<span class='warning'>Unfortunately, you no longer qualify for this role. Sorry.</span>")
else if(finished) // Already finished candidate list
to_chat(D, "<span class='warning'>Unfortunately, you were not fast enough, and there are no more available roles. Sorry.</span>")
else // Prompt a second time
tgui_alert_async(D, "Are you sure you want to play as a [role_name]?", "[role_name] request", list("I'm Sure", "Nevermind"), CALLBACK(src, .proc/get_reply), wait_time SECONDS)
if("I'm Sure")
if(!evaluate_candidate(D)) // Failed revalidation
to_chat(D, "<span class='warning'>Unfortunately, you no longer qualify for this role. Sorry.</span>")
else if(finished) // Already finished candidate list
to_chat(D, "<span class='warning'>Unfortunately, you were not fast enough, and there are no more available roles. Sorry.</span>")
else // Accept their nomination
candidates.Add(D)
if(cutoff_number && candidates.len >= cutoff_number)
finished = TRUE // Finish now if we're full.
// Normal things.
/datum/ghost_query/promethean