mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-15 20:52:41 +00:00
[MIRROR] Refactors ghost query to not use sleep (#10399)
Co-authored-by: Cameron Lennox <killer65311@gmail.com>
This commit is contained in:
committed by
GitHub
parent
c5ad633a8a
commit
a078b5cf1b
@@ -31,6 +31,9 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Signal that gets sent when a ghost query is completed
|
||||
#define COMSIG_GHOST_QUERY_COMPLETE "ghost_query_complete"
|
||||
|
||||
// /datum signals
|
||||
/// when a component is added to a datum: (/datum/component)
|
||||
#define COMSIG_COMPONENT_ADDED "component_added"
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
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.
|
||||
|
||||
/datum/ghost_query/Destroy(force)
|
||||
candidates = null
|
||||
. = ..()
|
||||
|
||||
/// Begin the ghost asking
|
||||
/datum/ghost_query/proc/query()
|
||||
// First, ask all the ghosts who want to be asked.
|
||||
@@ -19,20 +23,21 @@
|
||||
ask_question(D)
|
||||
|
||||
// Then wait awhile.
|
||||
while(!finished)
|
||||
sleep(1 SECOND)
|
||||
wait_time -= 1 SECOND
|
||||
if(wait_time <= 0)
|
||||
finished = TRUE
|
||||
if(wait_time)
|
||||
our_timer(wait_time)
|
||||
return
|
||||
|
||||
// Prune the list after the wait, incase any candidates logged out.
|
||||
/datum/ghost_query/proc/our_timer(var/current_wait_time)
|
||||
if(current_wait_time)
|
||||
addtimer(CALLBACK(src, PROC_REF(our_timer), FALSE), current_wait_time, TIMER_DELETE_ME)
|
||||
else
|
||||
for(var/mob/observer/dead/D as anything in candidates)
|
||||
if(!evaluate_candidate(D))
|
||||
candidates -= D
|
||||
|
||||
// Now we're done.
|
||||
finished = TRUE
|
||||
return candidates
|
||||
SEND_SIGNAL(src, COMSIG_GHOST_QUERY_COMPLETE)
|
||||
|
||||
|
||||
|
||||
/// Test a candidate for allowance to join as this
|
||||
/datum/ghost_query/proc/evaluate_candidate(mob/observer/dead/candidate)
|
||||
@@ -52,10 +57,8 @@
|
||||
|
||||
/// 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)
|
||||
//VOREStation Add Start Check the ban status before we ask
|
||||
if(jobban_isbanned(D, JOB_GHOSTROLES))
|
||||
return
|
||||
//VOREStation Add End
|
||||
|
||||
var/client/C = D.client
|
||||
window_flash(C)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
var/ghost_query_type = null
|
||||
var/searching = FALSE
|
||||
var/datum/effect/effect/system/spark_spread/sparks
|
||||
var/datum/ghost_query/Q //This is used so we can unregister ourself.
|
||||
|
||||
/obj/item/antag_spawner/New()
|
||||
..()
|
||||
@@ -28,13 +29,18 @@
|
||||
return // Already searching.
|
||||
searching = TRUE
|
||||
|
||||
var/datum/ghost_query/Q = new ghost_query_type()
|
||||
var/list/winner = Q.query()
|
||||
if(winner.len)
|
||||
var/mob/observer/dead/D = winner[1]
|
||||
Q = new ghost_query_type()
|
||||
RegisterSignal(Q, COMSIG_GHOST_QUERY_COMPLETE, PROC_REF(get_winner))
|
||||
Q.query()
|
||||
|
||||
/obj/item/antag_spawner/proc/get_winner()
|
||||
if(Q && Q.candidates.len)
|
||||
var/mob/observer/dead/D = Q.candidates[1]
|
||||
spawn_antag(D.client, get_turf(src))
|
||||
else
|
||||
reset_search()
|
||||
UnregisterSignal(Q, COMSIG_GHOST_QUERY_COMPLETE)
|
||||
qdel_null(Q) //get rid of the query
|
||||
return
|
||||
|
||||
/obj/item/antag_spawner/proc/reset_search()
|
||||
|
||||
@@ -8,7 +8,10 @@
|
||||
var/used = FALSE
|
||||
var/busy = FALSE // Don't spam ghosts by spamclicking.
|
||||
var/needscharger //For drone pods that want their pod to turn into a charger.
|
||||
var/datum/ghost_query/Q //This is used so we can unregister ourself.
|
||||
unacidable = TRUE
|
||||
var/delay_to_self_open = 0 // How long to wait for first attempt. Note that the timer by default starts when the pod is created.
|
||||
var/delay_to_try_again = 0 // How long to wait if first attempt fails. Set to 0 to never try again.
|
||||
|
||||
// Call this to get a ghost volunteer.
|
||||
/obj/structure/ghost_pod/proc/trigger(var/alert, var/adminalert)
|
||||
@@ -22,19 +25,27 @@
|
||||
if(adminalert)
|
||||
log_and_message_admins(adminalert)
|
||||
busy = TRUE
|
||||
var/datum/ghost_query/Q = new ghost_query_type()
|
||||
var/list/winner = Q.query()
|
||||
Q = new ghost_query_type()
|
||||
RegisterSignal(Q, COMSIG_GHOST_QUERY_COMPLETE, PROC_REF(get_winner))
|
||||
Q.query()
|
||||
|
||||
/obj/structure/ghost_pod/proc/get_winner()
|
||||
busy = FALSE
|
||||
if(winner.len)
|
||||
var/mob/observer/dead/D = winner[1]
|
||||
var/deletion_candidate = FALSE
|
||||
if(Q && Q.candidates.len) //Q should NEVER get deleted but...whatever, sanity.
|
||||
var/mob/observer/dead/D = Q.candidates[1]
|
||||
create_occupant(D)
|
||||
icon_state = icon_state_opened
|
||||
if(needscharger)
|
||||
new /obj/machinery/recharge_station/ghost_pod_recharger(src.loc)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
deletion_candidate = TRUE
|
||||
else
|
||||
return FALSE
|
||||
if(delay_to_try_again)
|
||||
addtimer(CALLBACK(src, PROC_REF(trigger)), delay_to_try_again)
|
||||
UnregisterSignal(Q, COMSIG_GHOST_QUERY_COMPLETE)
|
||||
qdel_null(Q) //get rid of the query
|
||||
if(deletion_candidate)
|
||||
qdel(src)
|
||||
|
||||
// Override this to create whatever mob you need. Be sure to call ..() if you don't want it to make infinite mobs.
|
||||
/obj/structure/ghost_pod/proc/create_occupant(var/mob/M)
|
||||
@@ -68,8 +79,8 @@
|
||||
|
||||
// This type is triggered on a timer, as opposed to needing another player to 'open' the pod. Good for away missions.
|
||||
/obj/structure/ghost_pod/automatic
|
||||
var/delay_to_self_open = 10 MINUTES // How long to wait for first attempt. Note that the timer by default starts when the pod is created.
|
||||
var/delay_to_try_again = 20 MINUTES // How long to wait if first attempt fails. Set to 0 to never try again.
|
||||
delay_to_self_open = 10 MINUTES
|
||||
delay_to_try_again = 20 MINUTES
|
||||
|
||||
/obj/structure/ghost_pod/automatic/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
@@ -18,6 +18,7 @@ var/list/blob_cores = list()
|
||||
var/resource_delay = 0
|
||||
var/point_rate = 2
|
||||
var/ai_controlled = TRUE
|
||||
var/datum/ghost_query/Q //This is used so we can unregister ourself.
|
||||
|
||||
// Spawn this if you want a ghost to be able to play as the blob.
|
||||
/obj/structure/blob/core/player
|
||||
@@ -152,38 +153,8 @@ var/list/blob_cores = list()
|
||||
/obj/structure/blob/core/proc/create_overmind(client/new_overmind, override_delay)
|
||||
if(overmind_get_delay > world.time && !override_delay)
|
||||
return
|
||||
if(!ai_controlled) // Do we want a bona fide player blob?
|
||||
overmind_get_delay = world.time + 15 SECONDS //if this fails, we'll try again in 15 seconds
|
||||
|
||||
if(overmind)
|
||||
qdel(overmind)
|
||||
|
||||
|
||||
var/client/C = null
|
||||
if(!new_overmind)
|
||||
var/datum/ghost_query/Q = new /datum/ghost_query/blob()
|
||||
var/list/winner = Q.query()
|
||||
if(winner.len)
|
||||
var/mob/observer/dead/D = winner[1]
|
||||
C = D.client
|
||||
|
||||
else
|
||||
C = new_overmind
|
||||
|
||||
if(C)
|
||||
if(!desired_blob_type && !isnull(difficulty_threshold))
|
||||
desired_blob_type = get_random_blob_type()
|
||||
var/mob/observer/blob/B = new(loc, TRUE, 60, desired_blob_type)
|
||||
B.key = C.key
|
||||
B.blob_core = src
|
||||
src.overmind = B
|
||||
update_icon()
|
||||
if(B.mind && !B.mind.special_role)
|
||||
B.mind.special_role = "Blob Overmind"
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
else // An AI opponent.
|
||||
if(ai_controlled)
|
||||
if(!desired_blob_type && !isnull(difficulty_threshold))
|
||||
desired_blob_type = get_random_blob_type()
|
||||
var/mob/observer/blob/B = new(loc, TRUE, 60, desired_blob_type)
|
||||
@@ -193,6 +164,47 @@ var/list/blob_cores = list()
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
overmind_get_delay = world.time + 15 SECONDS //if this fails, we'll try again in 15 seconds
|
||||
|
||||
if(overmind)
|
||||
qdel(overmind)
|
||||
|
||||
|
||||
var/client/C = null
|
||||
if(!new_overmind)
|
||||
Q = new /datum/ghost_query/blob()
|
||||
RegisterSignal(Q, COMSIG_GHOST_QUERY_COMPLETE, PROC_REF(get_winner))
|
||||
Q.query()
|
||||
|
||||
else
|
||||
C = new_overmind
|
||||
overmind_creation(C)
|
||||
|
||||
/obj/structure/blob/core/proc/get_winner()
|
||||
if(Q && Q.candidates.len) //Q should NEVER get deleted but...whatever, sanity.
|
||||
var/mob/observer/dead/D = Q.candidates[1]
|
||||
var/client/C
|
||||
C = D.client
|
||||
overmind_creation(C)
|
||||
UnregisterSignal(Q, COMSIG_GHOST_QUERY_COMPLETE)
|
||||
qdel_null(Q) //get rid of the query
|
||||
|
||||
|
||||
|
||||
/obj/structure/blob/core/proc/overmind_creation(var/client/new_overmind)
|
||||
if(new_overmind)
|
||||
if(!desired_blob_type && !isnull(difficulty_threshold))
|
||||
desired_blob_type = get_random_blob_type()
|
||||
var/mob/observer/blob/B = new(loc, TRUE, 60, desired_blob_type)
|
||||
B.key = new_overmind.key
|
||||
B.blob_core = src
|
||||
src.overmind = B
|
||||
update_icon()
|
||||
if(B.mind && !B.mind.special_role)
|
||||
B.mind.special_role = "Blob Overmind"
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/structure/blob/core/proc/get_random_blob_type()
|
||||
if(!difficulty_threshold)
|
||||
return
|
||||
|
||||
@@ -180,6 +180,7 @@
|
||||
locked = 0
|
||||
mecha = null//This does not appear to be used outside of reference in mecha.dm.
|
||||
var/ghost_query_type = null
|
||||
var/datum/ghost_query/Q //This is used so we can unregister ourself.
|
||||
|
||||
/obj/item/mmi/digital/New()
|
||||
src.brainmob = new(src)
|
||||
@@ -245,13 +246,18 @@
|
||||
return
|
||||
searching = 1
|
||||
|
||||
var/datum/ghost_query/Q = new ghost_query_type()
|
||||
var/list/winner = Q.query()
|
||||
if(winner.len)
|
||||
var/mob/observer/dead/D = winner[1]
|
||||
Q = new ghost_query_type()
|
||||
RegisterSignal(Q, COMSIG_GHOST_QUERY_COMPLETE, PROC_REF(get_winner))
|
||||
Q.query()
|
||||
|
||||
/obj/item/mmi/digital/proc/get_winner()
|
||||
if(Q && Q.candidates.len) //Q should NEVER get deleted but...whatever, sanity.
|
||||
var/mob/observer/dead/D = Q.candidates[1]
|
||||
transfer_personality(D)
|
||||
else
|
||||
reset_search()
|
||||
UnregisterSignal(Q, COMSIG_GHOST_QUERY_COMPLETE)
|
||||
qdel_null(Q) //get rid of the query
|
||||
|
||||
/obj/item/mmi/digital/proc/reset_search() //We give the players sixty seconds to decide, then reset the timer.
|
||||
if(src.brainmob && src.brainmob.key)
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
var/has_reproduced = FALSE
|
||||
var/used_dominate // world.time when the dominate power was last used.
|
||||
var/datum/ghost_query/Q // Used to unregister our signal
|
||||
|
||||
can_be_drop_prey = FALSE //CHOMP Add
|
||||
|
||||
@@ -182,11 +183,16 @@
|
||||
host = null
|
||||
|
||||
/mob/living/simple_mob/animal/borer/proc/request_player()
|
||||
var/datum/ghost_query/Q = new /datum/ghost_query/borer()
|
||||
var/list/winner = Q.query() // This will sleep the proc for awhile.
|
||||
if(winner.len)
|
||||
var/mob/observer/dead/D = winner[1]
|
||||
Q = new /datum/ghost_query/borer()
|
||||
RegisterSignal(Q, COMSIG_GHOST_QUERY_COMPLETE, PROC_REF(get_winner))
|
||||
Q.query() // This will sleep the proc for awhile.
|
||||
|
||||
/mob/living/simple_mob/animal/borer/proc/get_winner()
|
||||
if(Q && Q.candidates.len) //Q should NEVER get deleted but...whatever, sanity.
|
||||
var/mob/observer/dead/D = Q.candidates[1]
|
||||
transfer_personality(D)
|
||||
UnregisterSignal(Q, COMSIG_GHOST_QUERY_COMPLETE)
|
||||
qdel_null(Q) //get rid of the query
|
||||
|
||||
/mob/living/simple_mob/animal/borer/proc/transfer_personality(mob/candidate)
|
||||
if(!candidate || !candidate.mind)
|
||||
|
||||
Reference in New Issue
Block a user