mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-27 02:23:47 +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
|
// /datum signals
|
||||||
/// when a component is added to a datum: (/datum/component)
|
/// when a component is added to a datum: (/datum/component)
|
||||||
#define COMSIG_COMPONENT_ADDED "component_added"
|
#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/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.
|
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
|
/// Begin the ghost asking
|
||||||
/datum/ghost_query/proc/query()
|
/datum/ghost_query/proc/query()
|
||||||
// First, ask all the ghosts who want to be asked.
|
// First, ask all the ghosts who want to be asked.
|
||||||
@@ -19,20 +23,21 @@
|
|||||||
ask_question(D)
|
ask_question(D)
|
||||||
|
|
||||||
// Then wait awhile.
|
// Then wait awhile.
|
||||||
while(!finished)
|
if(wait_time)
|
||||||
sleep(1 SECOND)
|
our_timer(wait_time)
|
||||||
wait_time -= 1 SECOND
|
return
|
||||||
if(wait_time <= 0)
|
|
||||||
finished = TRUE
|
/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
|
||||||
|
finished = TRUE
|
||||||
|
SEND_SIGNAL(src, COMSIG_GHOST_QUERY_COMPLETE)
|
||||||
|
|
||||||
// Prune the list after the wait, incase any candidates logged out.
|
|
||||||
for(var/mob/observer/dead/D as anything in candidates)
|
|
||||||
if(!evaluate_candidate(D))
|
|
||||||
candidates -= D
|
|
||||||
|
|
||||||
// Now we're done.
|
|
||||||
finished = TRUE
|
|
||||||
return candidates
|
|
||||||
|
|
||||||
/// Test a candidate for allowance to join as this
|
/// Test a candidate for allowance to join as this
|
||||||
/datum/ghost_query/proc/evaluate_candidate(mob/observer/dead/candidate)
|
/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
|
/// 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)
|
/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))
|
if(jobban_isbanned(D, JOB_GHOSTROLES))
|
||||||
return
|
return
|
||||||
//VOREStation Add End
|
|
||||||
|
|
||||||
var/client/C = D.client
|
var/client/C = D.client
|
||||||
window_flash(C)
|
window_flash(C)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
var/ghost_query_type = null
|
var/ghost_query_type = null
|
||||||
var/searching = FALSE
|
var/searching = FALSE
|
||||||
var/datum/effect/effect/system/spark_spread/sparks
|
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()
|
/obj/item/antag_spawner/New()
|
||||||
..()
|
..()
|
||||||
@@ -28,13 +29,18 @@
|
|||||||
return // Already searching.
|
return // Already searching.
|
||||||
searching = TRUE
|
searching = TRUE
|
||||||
|
|
||||||
var/datum/ghost_query/Q = new ghost_query_type()
|
Q = new ghost_query_type()
|
||||||
var/list/winner = Q.query()
|
RegisterSignal(Q, COMSIG_GHOST_QUERY_COMPLETE, PROC_REF(get_winner))
|
||||||
if(winner.len)
|
Q.query()
|
||||||
var/mob/observer/dead/D = winner[1]
|
|
||||||
|
/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))
|
spawn_antag(D.client, get_turf(src))
|
||||||
else
|
else
|
||||||
reset_search()
|
reset_search()
|
||||||
|
UnregisterSignal(Q, COMSIG_GHOST_QUERY_COMPLETE)
|
||||||
|
qdel_null(Q) //get rid of the query
|
||||||
return
|
return
|
||||||
|
|
||||||
/obj/item/antag_spawner/proc/reset_search()
|
/obj/item/antag_spawner/proc/reset_search()
|
||||||
|
|||||||
@@ -8,7 +8,10 @@
|
|||||||
var/used = FALSE
|
var/used = FALSE
|
||||||
var/busy = FALSE // Don't spam ghosts by spamclicking.
|
var/busy = FALSE // Don't spam ghosts by spamclicking.
|
||||||
var/needscharger //For drone pods that want their pod to turn into a charger.
|
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
|
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.
|
// Call this to get a ghost volunteer.
|
||||||
/obj/structure/ghost_pod/proc/trigger(var/alert, var/adminalert)
|
/obj/structure/ghost_pod/proc/trigger(var/alert, var/adminalert)
|
||||||
@@ -22,19 +25,27 @@
|
|||||||
if(adminalert)
|
if(adminalert)
|
||||||
log_and_message_admins(adminalert)
|
log_and_message_admins(adminalert)
|
||||||
busy = TRUE
|
busy = TRUE
|
||||||
var/datum/ghost_query/Q = new ghost_query_type()
|
Q = new ghost_query_type()
|
||||||
var/list/winner = Q.query()
|
RegisterSignal(Q, COMSIG_GHOST_QUERY_COMPLETE, PROC_REF(get_winner))
|
||||||
|
Q.query()
|
||||||
|
|
||||||
|
/obj/structure/ghost_pod/proc/get_winner()
|
||||||
busy = FALSE
|
busy = FALSE
|
||||||
if(winner.len)
|
var/deletion_candidate = FALSE
|
||||||
var/mob/observer/dead/D = winner[1]
|
if(Q && Q.candidates.len) //Q should NEVER get deleted but...whatever, sanity.
|
||||||
|
var/mob/observer/dead/D = Q.candidates[1]
|
||||||
create_occupant(D)
|
create_occupant(D)
|
||||||
icon_state = icon_state_opened
|
icon_state = icon_state_opened
|
||||||
if(needscharger)
|
if(needscharger)
|
||||||
new /obj/machinery/recharge_station/ghost_pod_recharger(src.loc)
|
new /obj/machinery/recharge_station/ghost_pod_recharger(src.loc)
|
||||||
qdel(src)
|
deletion_candidate = TRUE
|
||||||
return TRUE
|
|
||||||
else
|
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.
|
// 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)
|
/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.
|
// 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
|
/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.
|
delay_to_self_open = 10 MINUTES
|
||||||
var/delay_to_try_again = 20 MINUTES // How long to wait if first attempt fails. Set to 0 to never try again.
|
delay_to_try_again = 20 MINUTES
|
||||||
|
|
||||||
/obj/structure/ghost_pod/automatic/Initialize(mapload)
|
/obj/structure/ghost_pod/automatic/Initialize(mapload)
|
||||||
. = ..()
|
. = ..()
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ var/list/blob_cores = list()
|
|||||||
var/resource_delay = 0
|
var/resource_delay = 0
|
||||||
var/point_rate = 2
|
var/point_rate = 2
|
||||||
var/ai_controlled = TRUE
|
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.
|
// Spawn this if you want a ghost to be able to play as the blob.
|
||||||
/obj/structure/blob/core/player
|
/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)
|
/obj/structure/blob/core/proc/create_overmind(client/new_overmind, override_delay)
|
||||||
if(overmind_get_delay > world.time && !override_delay)
|
if(overmind_get_delay > world.time && !override_delay)
|
||||||
return
|
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)
|
if(ai_controlled)
|
||||||
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(!desired_blob_type && !isnull(difficulty_threshold))
|
if(!desired_blob_type && !isnull(difficulty_threshold))
|
||||||
desired_blob_type = get_random_blob_type()
|
desired_blob_type = get_random_blob_type()
|
||||||
var/mob/observer/blob/B = new(loc, TRUE, 60, desired_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()
|
update_icon()
|
||||||
return TRUE
|
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()
|
/obj/structure/blob/core/proc/get_random_blob_type()
|
||||||
if(!difficulty_threshold)
|
if(!difficulty_threshold)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -180,6 +180,7 @@
|
|||||||
locked = 0
|
locked = 0
|
||||||
mecha = null//This does not appear to be used outside of reference in mecha.dm.
|
mecha = null//This does not appear to be used outside of reference in mecha.dm.
|
||||||
var/ghost_query_type = null
|
var/ghost_query_type = null
|
||||||
|
var/datum/ghost_query/Q //This is used so we can unregister ourself.
|
||||||
|
|
||||||
/obj/item/mmi/digital/New()
|
/obj/item/mmi/digital/New()
|
||||||
src.brainmob = new(src)
|
src.brainmob = new(src)
|
||||||
@@ -245,13 +246,18 @@
|
|||||||
return
|
return
|
||||||
searching = 1
|
searching = 1
|
||||||
|
|
||||||
var/datum/ghost_query/Q = new ghost_query_type()
|
Q = new ghost_query_type()
|
||||||
var/list/winner = Q.query()
|
RegisterSignal(Q, COMSIG_GHOST_QUERY_COMPLETE, PROC_REF(get_winner))
|
||||||
if(winner.len)
|
Q.query()
|
||||||
var/mob/observer/dead/D = winner[1]
|
|
||||||
|
/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)
|
transfer_personality(D)
|
||||||
else
|
else
|
||||||
reset_search()
|
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.
|
/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)
|
if(src.brainmob && src.brainmob.key)
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
|
|
||||||
var/has_reproduced = FALSE
|
var/has_reproduced = FALSE
|
||||||
var/used_dominate // world.time when the dominate power was last used.
|
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
|
can_be_drop_prey = FALSE //CHOMP Add
|
||||||
|
|
||||||
@@ -182,11 +183,16 @@
|
|||||||
host = null
|
host = null
|
||||||
|
|
||||||
/mob/living/simple_mob/animal/borer/proc/request_player()
|
/mob/living/simple_mob/animal/borer/proc/request_player()
|
||||||
var/datum/ghost_query/Q = new /datum/ghost_query/borer()
|
Q = new /datum/ghost_query/borer()
|
||||||
var/list/winner = Q.query() // This will sleep the proc for awhile.
|
RegisterSignal(Q, COMSIG_GHOST_QUERY_COMPLETE, PROC_REF(get_winner))
|
||||||
if(winner.len)
|
Q.query() // This will sleep the proc for awhile.
|
||||||
var/mob/observer/dead/D = winner[1]
|
|
||||||
|
/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)
|
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)
|
/mob/living/simple_mob/animal/borer/proc/transfer_personality(mob/candidate)
|
||||||
if(!candidate || !candidate.mind)
|
if(!candidate || !candidate.mind)
|
||||||
|
|||||||
Reference in New Issue
Block a user