From b4e975ef75d231e892bb6053c750c41063831d38 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Wed, 9 Oct 2019 06:51:07 +0200 Subject: [PATCH 1/5] mitigates the ghost roles/mid-round antag lock out for suicide/cryo. And related fixes. --- code/__DEFINES/misc.dm | 3 +++ code/__HELPERS/game.dm | 2 +- code/controllers/subsystem/pai.dm | 5 +++++ code/game/machinery/cryopod.dm | 3 ++- .../clockcult/clock_items/construct_chassis.dm | 5 ++++- code/modules/awaymissions/corpse.dm | 4 ++-- code/modules/mob/dead/observer/observer.dm | 14 +++++++------- code/modules/mob/living/brain/posibrain.dm | 10 +++++++--- .../friendly/drone/drones_as_items.dm | 5 ++++- .../living/simple_animal/hostile/giant_spider.dm | 5 +++++ .../simple_animal/hostile/megafauna/colossus.dm | 3 +++ 11 files changed, 43 insertions(+), 16 deletions(-) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index ba5e105041..2823761444 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -221,6 +221,9 @@ GLOBAL_LIST_EMPTY(bloody_footprints_cache) //Same as above except gets the area instead #define get_area(A) (isarea(A) ? A : get_step(A, 0)?.loc) +//Used to prevent cryo/suicidees from coming back into the round as ghost roles or mid round antags before a given duration has passed. +#define SUICIDE_REENTER_ROUND_TIMER 40 MINUTES + //Ghost orbit types: #define GHOST_ORBIT_CIRCLE "circle" #define GHOST_ORBIT_TRIANGLE "triangle" diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index cc0bd3e0b4..00decafabd 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -446,7 +446,7 @@ var/list/candidates = list() for(var/mob/dead/observer/G in GLOB.player_list) - if(G.can_reenter_round) + if(G.reenter_round_timeout < world.realtime) candidates += G return pollCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category, flashwindow, candidates) diff --git a/code/controllers/subsystem/pai.dm b/code/controllers/subsystem/pai.dm index 2e2f7edd99..09087c8626 100644 --- a/code/controllers/subsystem/pai.dm +++ b/code/controllers/subsystem/pai.dm @@ -69,6 +69,11 @@ SUBSYSTEM_DEF(pai) candidate.comments = copytext(sanitize(candidate.comments),1,MAX_MESSAGE_LEN) if("submit") + if(isobserver(usr)) + var/mob/dead/observer/O = usr + if(O.reenter_round_timeout > world.realtime) + to_chat(O, "You are unable to reenter the round yet. Your ghost role blacklist will expire in [round((O.reenter_round_timeout - world.realtime)/600)] minutes.") + return if(candidate) candidate.ready = 1 for(var/obj/item/paicard/p in pai_card_list) diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index e358f10346..84cc27953a 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -411,7 +411,8 @@ // Ghost and delete the mob. if(!mob_occupant.get_ghost(1)) - mob_occupant.ghostize(0) // Players who cryo out may not re-enter the round + mob_occupant.suiciding = TRUE //to penalize them from making a ghost role / midround antag comeback right away. + mob_occupant.ghostize(0) QDEL_NULL(occupant) open_machine() diff --git a/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm b/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm index 12af249bee..fa15509c59 100644 --- a/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm +++ b/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm @@ -39,7 +39,10 @@ . = ..() //ATTACK GHOST IGNORING PARENT RETURN VALUE -/obj/item/clockwork/construct_chassis/attack_ghost(mob/user) +/obj/item/clockwork/construct_chassis/attack_ghost(mob/dead/observer/user) + if(user.reenter_round_timeout > world.realtime) + to_chat(user, "You are unable to reenter the round yet. Your ghost role blacklist will expire in [round((user.reenter_round_timeout - world.realtime)/600)] minutes.") + return if(!SSticker.mode) to_chat(user, "You cannot use that before the game has started.") return diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 74f81ec9a0..9d5c46fdf5 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -43,8 +43,8 @@ return if(isobserver(user)) var/mob/dead/observer/O = user - if(!O.can_reenter_round) - to_chat(user, "You are unable to reenter the round.") + if(O.reenter_round_timeout > world.realtime) + to_chat(user, "You are unable to reenter the round yet. Your ghost role blacklist will expire in [round((O.reenter_round_timeout - world.realtime)/600)] minutes.") return var/ghost_role = alert(latejoinercalling ? "Latejoin as [mob_name]? (This is a ghost role, and as such, it's very likely to be off-station.)" : "Become [mob_name]? (Warning, You can no longer be cloned!)",,"Yes","No") if(ghost_role == "No" || !loc) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index fefa032e4f..16fd99e9be 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -18,7 +18,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) invisibility = INVISIBILITY_OBSERVER hud_type = /datum/hud/ghost var/can_reenter_corpse - var/can_reenter_round = TRUE + var/reenter_round_timeout = 0 // used to prevent people from coming back through ghost roles/midround antags as they suicide/cryo for a duration set by SUICIDE_REENTER_ROUND_TIMER. var/datum/hud/living/carbon/hud = null // hud var/bootime = 0 var/started_as_observer //This variable is set to 1 when you enter the game as an observer. @@ -267,7 +267,7 @@ Works together with spawning an observer, noted above. var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc. SStgui.on_transfer(src, ghost) // Transfer NanoUIs. ghost.can_reenter_corpse = can_reenter_corpse - ghost.can_reenter_round = (can_reenter_corpse && !suiciding) + ghost.reenter_round_timeout = suiciding ? world.realtime + SUICIDE_REENTER_ROUND_TIMER : 0 ghost.key = key return ghost @@ -282,7 +282,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp // CITADEL EDIT if(istype(loc, /obj/machinery/cryopod)) - var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") + var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round for the next [SUICIDE_REENTER_ROUND_TIMER/600] minutes! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") if(response != "Ghost")//darn copypaste return var/obj/machinery/cryopod/C = loc @@ -295,7 +295,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(stat == DEAD) ghostize(1) else - var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") + var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round for the next [SUICIDE_REENTER_ROUND_TIMER/600] minutes! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") if(response != "Ghost") return //didn't want to ghost after-all ghostize(0) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3 @@ -306,7 +306,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp set name = "Ghost" set desc = "Relinquish your life and enter the land of the dead." - var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") + var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round for the next [SUICIDE_REENTER_ROUND_TIMER/600] minutes! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") if(response != "Ghost") return ghostize(0) @@ -617,8 +617,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp to_chat(src, "This isn't really a creature, now is it!") return 0 - if(!can_reenter_round) - to_chat(src, "You are unable to re-enter the round.") + if(reenter_round_timeout > world.realtime) + to_chat(src, "You are unable to re-enter the round yet. Your ghost role blacklist will expire in [round((reenter_round_timeout - world.realtime)/600)] minutes.") return FALSE if(can_reenter_corpse && mind && mind.current) diff --git a/code/modules/mob/living/brain/posibrain.dm b/code/modules/mob/living/brain/posibrain.dm index 9e0bb0428b..e52d53dca2 100644 --- a/code/modules/mob/living/brain/posibrain.dm +++ b/code/modules/mob/living/brain/posibrain.dm @@ -83,11 +83,15 @@ GLOBAL_VAR(posibrain_notify_cooldown) //Two ways to activate a positronic brain. A clickable link in the ghost notif, or simply clicking the object itself. /obj/item/mmi/posibrain/proc/activate(mob/user) - if(QDELETED(brainmob)) - return - if(is_occupied() || jobban_isbanned(user,"posibrain") || QDELETED(brainmob) || QDELETED(src) || QDELETED(user)) + if(QDELETED(brainmob) || is_occupied() || jobban_isbanned(user,"posibrain") || QDELETED(src) || QDELETED(user)) return + if(isobserver(user)) + var/mob/dead/observer/O = user + if(O.reenter_round_timeout > world.realtime) + to_chat(user, "You are unable to reenter the round yet. Your ghost role blacklist will expire in [round((O.reenter_round_timeout - world.realtime)/600)] minutes.") + return + var/posi_ask = alert("Become a [name]? (Warning, You can no longer be cloned, and all past lives will be forgotten!)","Are you positive?","Yes","No") if(posi_ask == "No" || QDELETED(src)) return diff --git a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm index a655bdf231..dd0b948299 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm @@ -40,7 +40,7 @@ . = ..() //ATTACK GHOST IGNORING PARENT RETURN VALUE -/obj/item/drone_shell/attack_ghost(mob/user) +/obj/item/drone_shell/attack_ghost(mob/dead/observer/user) if(jobban_isbanned(user,"drone") || QDELETED(src) || QDELETED(user)) return if(CONFIG_GET(flag/use_age_restriction_for_jobs)) @@ -49,6 +49,9 @@ if(user.client.player_age < DRONE_MINIMUM_AGE) to_chat(user, "You're too new to play as a drone! Please try again in [DRONE_MINIMUM_AGE - user.client.player_age] days.") return + if(user.reenter_round_timeout > world.realtime) + to_chat(user, "You are unable to reenter the round yet. Your ghost role blacklist will expire in [round((user.reenter_round_timeout - world.realtime)/600)] minutes.") + return if(!SSticker.mode) to_chat(user, "Can't become a drone before the game has started.") return diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm index cfdf302d6b..c851e50be7 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm @@ -84,6 +84,11 @@ /mob/living/simple_animal/hostile/poison/giant_spider/proc/humanize_spider(mob/user) if(key || !playable_spider || stat)//Someone is in it, it's dead, or the fun police are shutting it down return 0 + if(isobserver(user)) + var/mob/dead/observer/O = user + if(O.reenter_round_timeout > world.realtime) + to_chat(O, "You are unable to reenter the round yet. Your ghost role blacklist will expire in [round((O.reenter_round_timeout - world.realtime)/600)] minutes.") + return var/spider_ask = alert("Become a spider?", "Are you australian?", "Yes", "No") if(spider_ask == "No" || !src || QDELETED(src)) return 1 diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index b529d826c9..a9a49e3982 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -582,6 +582,9 @@ Difficulty: Very Hard if(.) return if(ready_to_deploy) + if(user.reenter_round_timeout > world.realtime) + to_chat(user, "You are unable to reenter the round yet. Your ghost role blacklist will expire in [round((user.reenter_round_timeout - world.realtime)/600)] minutes.") + return var/be_helper = alert("Become a Lightgeist? (Warning, You can no longer be cloned!)",,"Yes","No") if(be_helper == "Yes" && !QDELETED(src) && isobserver(user)) var/mob/living/simple_animal/hostile/lightgeist/W = new /mob/living/simple_animal/hostile/lightgeist(get_turf(loc)) From ac0b3629f1485e8463f5ad4dc04248fbf9905fae Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Wed, 9 Oct 2019 07:53:59 +0200 Subject: [PATCH 2/5] roundstart quitters --- code/__DEFINES/misc.dm | 3 ++- code/modules/mob/dead/observer/observer.dm | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 2823761444..9751030e8d 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -222,7 +222,8 @@ GLOBAL_LIST_EMPTY(bloody_footprints_cache) #define get_area(A) (isarea(A) ? A : get_step(A, 0)?.loc) //Used to prevent cryo/suicidees from coming back into the round as ghost roles or mid round antags before a given duration has passed. -#define SUICIDE_REENTER_ROUND_TIMER 40 MINUTES +#define SUICIDE_REENTER_ROUND_TIMER 30 MINUTES +#define ROUNDSTART_QUITTER_TIME_LIMIT 30 MINUTES //a game time threshold under which will be applied a proportional added penalty. //Ghost orbit types: #define GHOST_ORBIT_CIRCLE "circle" diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 16fd99e9be..f75d7016d3 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -267,7 +267,11 @@ Works together with spawning an observer, noted above. var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc. SStgui.on_transfer(src, ghost) // Transfer NanoUIs. ghost.can_reenter_corpse = can_reenter_corpse - ghost.reenter_round_timeout = suiciding ? world.realtime + SUICIDE_REENTER_ROUND_TIMER : 0 + if(suiciding) + var/penalty = SUICIDE_REENTER_ROUND_TIMER + if(world.time < ROUNDSTART_QUITTER_TIME_LIMIT) //add up the time difference to their antag rolling penalty if they quit before half a (ingame) hour even passed. + penalty += ROUNDSTART_QUITTER_TIME_LIMIT - world.time + ghost.reenter_round_timeout = world.realtime + penalty ghost.key = key return ghost @@ -280,9 +284,12 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp set name = "Ghost" set desc = "Relinquish your life and enter the land of the dead." + var/penalty = SUICIDE_REENTER_ROUND_TIMER + if(world.time < ROUNDSTART_QUITTER_TIME_LIMIT) + penalty += ROUNDSTART_QUITTER_TIME_LIMIT - world.time // CITADEL EDIT if(istype(loc, /obj/machinery/cryopod)) - var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round for the next [SUICIDE_REENTER_ROUND_TIMER/600] minutes! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") + var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round for the next [round(penalty/600, 600)] minutes! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") if(response != "Ghost")//darn copypaste return var/obj/machinery/cryopod/C = loc @@ -295,7 +302,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(stat == DEAD) ghostize(1) else - var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round for the next [SUICIDE_REENTER_ROUND_TIMER/600] minutes! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") + var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round for the next [round(penalty/600, 600)] minutes! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") if(response != "Ghost") return //didn't want to ghost after-all ghostize(0) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3 @@ -306,7 +313,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp set name = "Ghost" set desc = "Relinquish your life and enter the land of the dead." - var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round for the next [SUICIDE_REENTER_ROUND_TIMER/600] minutes! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") + var/penalty = SUICIDE_REENTER_ROUND_TIMER + if(world.time < ROUNDSTART_QUITTER_TIME_LIMIT) + penalty += ROUNDSTART_QUITTER_TIME_LIMIT - world.time + var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round for the next [round(penalty/600, 600)] minutes! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") if(response != "Ghost") return ghostize(0) From f73516a17f086888d34ab445453d5d4a269e2292 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Thu, 17 Oct 2019 04:44:30 +0200 Subject: [PATCH 3/5] made it into config. --- code/__DEFINES/misc.dm | 4 -- .../configuration/entries/game_options.dm | 8 +++ code/game/machinery/cryopod.dm | 3 +- code/modules/client/verbs/suicide.dm | 2 +- code/modules/mob/dead/observer/observer.dm | 55 +++++++++---------- config/game_options.txt | 12 ++++ 6 files changed, 49 insertions(+), 35 deletions(-) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index afa9071aae..bccf1f28dd 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -221,10 +221,6 @@ GLOBAL_LIST_EMPTY(bloody_footprints_cache) //Same as above except gets the area instead #define get_area(A) (isarea(A) ? A : get_step(A, 0)?.loc) -//Used to prevent cryo/suicidees from coming back into the round as ghost roles or mid round antags before a given duration has passed. -#define SUICIDE_REENTER_ROUND_TIMER 30 MINUTES -#define ROUNDSTART_QUITTER_TIME_LIMIT 30 MINUTES //a game time threshold under which will be applied a proportional added penalty. - //Ghost orbit types: #define GHOST_ORBIT_CIRCLE "circle" #define GHOST_ORBIT_TRIANGLE "triangle" diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index cfd57b4850..95935a7066 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -132,6 +132,14 @@ min_val = 0 max_val = 1 +/datum/config_entry/number/suicide_reenter_round_timer + config_entry_value = 30 + min_val = 0 + +/datum/config_entry/number/roundstart_suicide_time_limit + config_entry_value = 30 + min_val = 0 + /datum/config_entry/number/shuttle_refuel_delay config_entry_value = 12000 min_val = 0 diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 84cc27953a..b856ee4c94 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -411,8 +411,7 @@ // Ghost and delete the mob. if(!mob_occupant.get_ghost(1)) - mob_occupant.suiciding = TRUE //to penalize them from making a ghost role / midround antag comeback right away. - mob_occupant.ghostize(0) + mob_occupant.ghostize(FALSE, penalize = TRUE) QDEL_NULL(occupant) open_machine() diff --git a/code/modules/client/verbs/suicide.dm b/code/modules/client/verbs/suicide.dm index 2e643cc05d..90c692c60e 100644 --- a/code/modules/client/verbs/suicide.dm +++ b/code/modules/client/verbs/suicide.dm @@ -49,7 +49,7 @@ if(!(damagetype & (BRUTELOSS | FIRELOSS | TOXLOSS | OXYLOSS) )) adjustOxyLoss(max(200 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0)) - death(FALSE) + death(FALSE, penalize = TRUE) return diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 835dcab9e2..eb5c968bd2 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -18,7 +18,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) invisibility = INVISIBILITY_OBSERVER hud_type = /datum/hud/ghost var/can_reenter_corpse - var/reenter_round_timeout = 0 // used to prevent people from coming back through ghost roles/midround antags as they suicide/cryo for a duration set by SUICIDE_REENTER_ROUND_TIMER. + var/reenter_round_timeout = 0 // used to prevent people from coming back through ghost roles/midround antags as they suicide/cryo for a duration set by CONFIG_GET(number/suicide_reenter_round_timer) and CONFIG_GET(number/roundstart_suicide_time_limit) var/datum/hud/living/carbon/hud = null // hud var/bootime = 0 var/started_as_observer //This variable is set to 1 when you enter the game as an observer. @@ -260,18 +260,20 @@ Transfer_mind is there to check if mob is being deleted/not going to have a body Works together with spawning an observer, noted above. */ -/mob/proc/ghostize(can_reenter_corpse = TRUE, special = FALSE) - if(!key || cmptext(copytext(key,1,2),"@") || (!special && SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse, special) & COMPONENT_BLOCK_GHOSTING)) +/mob/proc/ghostize(can_reenter_corpse = TRUE, special = FALSE, penalize = FALSE) + if(!key || cmptext(copytext(key,1,2),"@") || (!special && SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse) & COMPONENT_BLOCK_GHOSTING)) return //mob has no key, is an aghost or some component hijacked. stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc. SStgui.on_transfer(src, ghost) // Transfer NanoUIs. ghost.can_reenter_corpse = can_reenter_corpse - if(suiciding) - var/penalty = SUICIDE_REENTER_ROUND_TIMER - if(world.time < ROUNDSTART_QUITTER_TIME_LIMIT) //add up the time difference to their antag rolling penalty if they quit before half a (ingame) hour even passed. - penalty += ROUNDSTART_QUITTER_TIME_LIMIT - world.time - ghost.reenter_round_timeout = world.realtime + penalty + if(penalize) //penalizing them from making a ghost role / midround antag comeback right away. + var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) + var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) + if(world.time < roundstart_quit_limit) //add up the time difference to their antag rolling penalty if they quit before half a (ingame) hour even passed. + penalty += roundstart_quit_limit - world.time + if(penalty) + ghost.reenter_round_timeout = world.realtime + penalty transfer_ckey(ghost, FALSE) return ghost @@ -287,29 +289,25 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, (stat == DEAD) ? TRUE : FALSE, FALSE) & COMPONENT_BLOCK_GHOSTING) return - var/penalty = SUICIDE_REENTER_ROUND_TIMER - if(world.time < ROUNDSTART_QUITTER_TIME_LIMIT) - penalty += ROUNDSTART_QUITTER_TIME_LIMIT - world.time -// CITADEL EDIT - if(istype(loc, /obj/machinery/cryopod)) - var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round for the next [round(penalty/600, 600)] minutes! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") - if(response != "Ghost")//darn copypaste - return - var/obj/machinery/cryopod/C = loc - C.despawn_occupant() - return -// END EDIT + var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) + var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) + if(world.time < roundstart_quit_limit) + penalty += roundstart_quit_limit - world.time if(stat != DEAD) succumb() if(stat == DEAD) ghostize(1) else - var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round for the next [round(penalty/600, 600)] minutes! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") + var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst alive you won't be able to re-enter this round [penalty ? "or play ghost roles for the next [round(penalty/600)] minutes" : ""]! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") if(response != "Ghost") return //didn't want to ghost after-all - ghostize(0) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3 - suicide_log(TRUE) + if(istype(loc, /obj/machinery/cryopod)) + var/obj/machinery/cryopod/C = loc + C.despawn_occupant() + else + ghostize(0, penalize = TRUE) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3 + suicide_log(TRUE) /mob/camera/verb/ghost() set category = "OOC" @@ -319,14 +317,15 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, FALSE, FALSE) & COMPONENT_BLOCK_GHOSTING) return - var/penalty = SUICIDE_REENTER_ROUND_TIMER - if(world.time < ROUNDSTART_QUITTER_TIME_LIMIT) - penalty += ROUNDSTART_QUITTER_TIME_LIMIT - world.time + var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) + var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) + if(world.time < roundstart_quit_limit) + penalty += roundstart_quit_limit - world.time - var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round for the next [round(penalty/600, 600)] minutes! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") + var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst alive you won't be able to re-enter this round [penalty ? "or play ghost roles for the next [round(penalty/600)] minutes" : ""]! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") if(response != "Ghost") return - ghostize(0) + ghostize(0, penalize = TRUE) /mob/dead/observer/Move(NewLoc, direct) if(updatedir) diff --git a/config/game_options.txt b/config/game_options.txt index 2e346ce0ac..ca07d4e744 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -471,6 +471,18 @@ MIDROUND_ANTAG_TIME_CHECK 60 ## A ratio of living to total crew members, the lower this is, the more people will have to die in order for midround antag to be skipped MIDROUND_ANTAG_LIFE_CHECK 0.7 +## A time, in real-time deciseconds, applied upon suicide, cryosleep or ghosting whilst alive +## during which the player shouldn't be able to come back through +## midround playable roles or mob spawners. +## Set to 0 to completely disable it. +SUICIDE_REENTER_ROUND_TIMER 18000 + +## A time, in real-time deciseconds, below which the player receives +## a timed penalty, for purposes similar to the aforementioned one (can also stack) +## and equal to this config difference with world.time. +## Both configs are indipendent from each other, disabling one won't affect the other. +ROUNDSTART_SUICIDE_TIME_LIMIT 18000 + ##Limit Spell Choices## ## Uncomment to disallow wizards from using certain spells that may be too chaotic/fun for your playerbase From ec22088534dc3c005922e11b8695aa09d0948843 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Sun, 20 Oct 2019 09:15:35 +0200 Subject: [PATCH 4/5] Complying with suggestions. Also stops dnr observers from getting ghost role notifications --- code/controllers/subsystem/pai.dm | 7 ++-- code/game/objects/effects/spiders.dm | 2 +- .../objects/structures/ghost_role_spawners.dm | 6 +-- .../clock_items/construct_chassis.dm | 7 ++-- code/modules/antagonists/cult/runes.dm | 4 +- code/modules/antagonists/swarmer/swarmer.dm | 2 +- code/modules/awaymissions/corpse.dm | 5 +-- code/modules/events/pirates.dm | 2 +- code/modules/mob/dead/observer/observer.dm | 37 ++++++++++++++----- code/modules/mob/living/brain/posibrain.dm | 7 ++-- .../friendly/drone/drones_as_items.dm | 7 ++-- .../simple_animal/hostile/giant_spider.dm | 13 +++---- .../hostile/megafauna/colossus.dm | 7 ++-- code/modules/mob/mob_helpers.dm | 4 +- .../mob/living/simple_animal/banana_spider.dm | 9 ++++- 15 files changed, 69 insertions(+), 50 deletions(-) diff --git a/code/controllers/subsystem/pai.dm b/code/controllers/subsystem/pai.dm index 09087c8626..18667053d4 100644 --- a/code/controllers/subsystem/pai.dm +++ b/code/controllers/subsystem/pai.dm @@ -71,9 +71,8 @@ SUBSYSTEM_DEF(pai) if("submit") if(isobserver(usr)) var/mob/dead/observer/O = usr - if(O.reenter_round_timeout > world.realtime) - to_chat(O, "You are unable to reenter the round yet. Your ghost role blacklist will expire in [round((O.reenter_round_timeout - world.realtime)/600)] minutes.") - return + if(!O.can_reenter_round()) + return FALSE if(candidate) candidate.ready = 1 for(var/obj/item/paicard/p in pai_card_list) @@ -153,6 +152,8 @@ SUBSYSTEM_DEF(pai) continue if(!(ROLE_PAI in G.client.prefs.be_special)) continue + if(!G.can_reenter_round()) // this should use notify_ghosts() instead one day. + return FALSE to_chat(G, "[user] is requesting a pAI personality! Use the pAI button to submit yourself as one.") addtimer(CALLBACK(src, .proc/spam_again), spam_delay) var/list/available = list() diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index c92721082c..08a3501be6 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -201,7 +201,7 @@ S.directive = directive if(player_spiders) S.playable_spider = TRUE - notify_ghosts("Spider [S.name] can be controlled", null, enter_link="(Click to play)", source=S, action=NOTIFY_ATTACK, ignore_key = POLL_IGNORE_SPIDER) + notify_ghosts("Spider [S.name] can be controlled", null, enter_link="(Click to play)", source=S, action=NOTIFY_ATTACK, ignore_key = POLL_IGNORE_SPIDER, ignore_dnr_observers = TRUE) qdel(src) diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index b820e93c7b..10f1f30e13 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -66,7 +66,7 @@ . = ..() var/area/A = get_area(src) if(A) - notify_ghosts("An ash walker egg is ready to hatch in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_ASHWALKER) + notify_ghosts("An ash walker egg is ready to hatch in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_ASHWALKER, ignore_dnr_observers = TRUE) /datum/outfit/ashwalker name ="Ashwalker" @@ -133,7 +133,7 @@ . = ..() var/area/A = get_area(src) if(!mapload && A) - notify_ghosts("\A [initial(species.prefix)] golem shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_GOLEM) + notify_ghosts("\A [initial(species.prefix)] golem shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_GOLEM, ignore_dnr_observers = TRUE) if(has_owner && creator) flavour_text = "You are a Golem. You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools. \ Serve [creator], and assist [creator.p_them()] in completing [creator.p_their()] goals at any cost." @@ -372,7 +372,7 @@ flavour_text = "You have been given a reprieve from your eternity of torment, to be [owner.name]'s friend for [owner.p_their()] short mortal coil. Be aware that if you do not live up to [owner.name]'s expectations, they can send you back to hell with a single thought. [owner.name]'s death will also return you to hell." var/area/A = get_area(src) if(!mapload && A) - notify_ghosts("\A friendship shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE) + notify_ghosts("\A friendship shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_dnr_observers = TRUE) objectives = "Be [owner.name]'s friend, and keep [owner.name] alive, so you don't get sent back to hell." spell = summoning_spell diff --git a/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm b/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm index 4519a2d6a2..f53796f02a 100644 --- a/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm +++ b/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm @@ -15,7 +15,7 @@ . = ..() var/area/A = get_area(src) if(A && construct_type) - notify_ghosts("A [construct_name] chassis has been created in [A.name]!", 'sound/magic/clockwork/fellowship_armory.ogg', source = src, action = NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_CONSTRUCT) + notify_ghosts("A [construct_name] chassis has been created in [A.name]!", 'sound/magic/clockwork/fellowship_armory.ogg', source = src, action = NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_CONSTRUCT, ignore_dnr_observers = TRUE) GLOB.poi_list += src LAZYADD(GLOB.mob_spawners[name], src) @@ -40,9 +40,8 @@ //ATTACK GHOST IGNORING PARENT RETURN VALUE /obj/item/clockwork/construct_chassis/attack_ghost(mob/dead/observer/user) - if(user.reenter_round_timeout > world.realtime) - to_chat(user, "You are unable to reenter the round yet. Your ghost role blacklist will expire in [round((user.reenter_round_timeout - world.realtime)/600)] minutes.") - return + if(!user.can_reenter_round()) + return FALSE if(!SSticker.mode) to_chat(user, "You cannot use that before the game has started.") return diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index 2e233d26e4..1eac059d36 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -848,10 +848,10 @@ structure_check() searches for nearby cultist structures required for the invoca fail_invoke() log_game("Manifest rune failed - too many summoned ghosts") return list() - notify_ghosts("Manifest rune invoked in [get_area(src)].", 'sound/effects/ghost2.ogg', source = src) + notify_ghosts("Manifest rune invoked in [get_area(src)].", 'sound/effects/ghost2.ogg', source = src, ignore_dnr_observers = TRUE) var/list/ghosts_on_rune = list() for(var/mob/dead/observer/O in T) - if(O.client && !jobban_isbanned(O, ROLE_CULTIST) && !QDELETED(src) && !QDELETED(O)) + if(!QDELETED(O) && O.client && !jobban_isbanned(O, ROLE_CULTIST) && !QDELETED(src) && O.can_reenter_round()) ghosts_on_rune += O if(!ghosts_on_rune.len) to_chat(user, "There are no spirits near [src]!") diff --git a/code/modules/antagonists/swarmer/swarmer.dm b/code/modules/antagonists/swarmer/swarmer.dm index 87cee7586d..ce455d9e67 100644 --- a/code/modules/antagonists/swarmer/swarmer.dm +++ b/code/modules/antagonists/swarmer/swarmer.dm @@ -33,7 +33,7 @@ . = ..() var/area/A = get_area(src) if(A) - notify_ghosts("A swarmer shell has been created in [A.name].", 'sound/effects/bin_close.ogg', source = src, action = NOTIFY_ATTACK, flashwindow = FALSE) + notify_ghosts("A swarmer shell has been created in [A.name].", 'sound/effects/bin_close.ogg', source = src, action = NOTIFY_ATTACK, flashwindow = FALSE, ignore_dnr_observers = TRUE) /obj/effect/mob_spawn/swarmer/attack_hand(mob/living/user) . = ..() diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 9d5c46fdf5..304d050630 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -43,9 +43,8 @@ return if(isobserver(user)) var/mob/dead/observer/O = user - if(O.reenter_round_timeout > world.realtime) - to_chat(user, "You are unable to reenter the round yet. Your ghost role blacklist will expire in [round((O.reenter_round_timeout - world.realtime)/600)] minutes.") - return + if(!O.can_reenter_round()) + return FALSE var/ghost_role = alert(latejoinercalling ? "Latejoin as [mob_name]? (This is a ghost role, and as such, it's very likely to be off-station.)" : "Become [mob_name]? (Warning, You can no longer be cloned!)",,"Yes","No") if(ghost_role == "No" || !loc) return diff --git a/code/modules/events/pirates.dm b/code/modules/events/pirates.dm index 7256ddb6ea..1a8501f179 100644 --- a/code/modules/events/pirates.dm +++ b/code/modules/events/pirates.dm @@ -75,7 +75,7 @@ spawner.create(M.ckey) candidates -= M else - notify_ghosts("Space pirates are waking up!", source = spawner, action=NOTIFY_ATTACK, flashwindow = FALSE) + notify_ghosts("Space pirates are waking up!", source = spawner, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_dnr_observers = TRUE) priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') //CITADEL EDIT also metabreak here too diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index eb5c968bd2..f2a24cd763 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -3,6 +3,8 @@ GLOBAL_LIST_EMPTY(ghost_images_simple) //this is a list of all ghost images as t GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) +#define CANT_REENTER_ROUND -1 + /mob/dead/observer name = "ghost" desc = "It's a g-g-g-g-ghooooost!" //jinkies! @@ -274,6 +276,8 @@ Works together with spawning an observer, noted above. penalty += roundstart_quit_limit - world.time if(penalty) ghost.reenter_round_timeout = world.realtime + penalty + if(ghost.reenter_round_timeout - SSshuttle.realtimeofstart > SSshuttle.auto_call + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime) + ghost.reenter_round_timeout = CANT_REENTER_ROUND transfer_ckey(ghost, FALSE) return ghost @@ -289,17 +293,19 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, (stat == DEAD) ? TRUE : FALSE, FALSE) & COMPONENT_BLOCK_GHOSTING) return - var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) - var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) + var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES + var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES if(world.time < roundstart_quit_limit) penalty += roundstart_quit_limit - world.time + if(penalty + world.realtime - SSshuttle.realtimeofstart > SSshuttle.auto_call + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime) + penalty = CANT_REENTER_ROUND if(stat != DEAD) succumb() if(stat == DEAD) ghostize(1) else - var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst alive you won't be able to re-enter this round [penalty ? "or play ghost roles for the next [round(penalty/600)] minutes" : ""]! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") + var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst alive you won't be able to re-enter this round [penalty ? "or play ghost roles [penalty != CANT_REENTER_ROUND ? "until the round is over" : "for the next [DisplayTimeText(penalty)]"]" : ""]! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") if(response != "Ghost") return //didn't want to ghost after-all if(istype(loc, /obj/machinery/cryopod)) @@ -317,16 +323,25 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, FALSE, FALSE) & COMPONENT_BLOCK_GHOSTING) return - var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) - var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) + var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES + var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES if(world.time < roundstart_quit_limit) penalty += roundstart_quit_limit - world.time + if(penalty + world.realtime - SSshuttle.realtimeofstart > SSshuttle.auto_call + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime) + penalty = CANT_REENTER_ROUND - var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst alive you won't be able to re-enter this round [penalty ? "or play ghost roles for the next [round(penalty/600)] minutes" : ""]! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") + var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst alive you won't be able to re-enter this round [penalty ? "or play ghost roles [penalty != CANT_REENTER_ROUND ? "until the round is over" : "for the next [DisplayTimeText(penalty)]"]" : ""]! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body") if(response != "Ghost") return ghostize(0, penalize = TRUE) +/mob/dead/observer/proc/can_reenter_round(silent = FALSE) + if(reenter_round_timeout != CANT_REENTER_ROUND && reenter_round_timeout <= world.realtime) + return TRUE + if(!silent) + to_chat(src, "You are unable to reenter the round[reenter_round_timeout != CANT_REENTER_ROUND ? " yet. Your ghost role blacklist will expire in [DisplayTimeText(reenter_round_timeout - world.realtime)]" : ""].") + return FALSE + /mob/dead/observer/Move(NewLoc, direct) if(updatedir) setDir(direct)//only update dir if we actually need it, so overlays won't spin on base sprites that don't have directions of their own @@ -613,6 +628,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp set name = "Possess!" set desc= "Take over the body of a mindless creature!" + if(reenter_round_timeout > world.realtime) + to_chat(src, "You are unable to re-enter the round yet. Your ghost role blacklist will expire in [DisplayTimeText(reenter_round_timeout - world.realtime)].") + return FALSE + var/list/possessible = list() for(var/mob/living/L in GLOB.alive_mob_list) if(istype(L,/mob/living/carbon/human/dummy) || !get_turf(L)) //Haha no. @@ -633,10 +652,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp to_chat(src, "This isn't really a creature, now is it!") return 0 - if(reenter_round_timeout > world.realtime) - to_chat(src, "You are unable to re-enter the round yet. Your ghost role blacklist will expire in [round((reenter_round_timeout - world.realtime)/600)] minutes.") - return FALSE - if(can_reenter_corpse && mind && mind.current) if(alert(src, "Your soul is still tied to your former life as [mind.current.name], if you go forward there is no going back to that life. Are you sure you wish to continue?", "Move On", "Yes", "No") == "No") return 0 @@ -881,3 +896,5 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp spawners_menu = new(src) spawners_menu.ui_interact(src) + +#undef CANT_REENTER_ROUND \ No newline at end of file diff --git a/code/modules/mob/living/brain/posibrain.dm b/code/modules/mob/living/brain/posibrain.dm index e52d53dca2..77af8d07d8 100644 --- a/code/modules/mob/living/brain/posibrain.dm +++ b/code/modules/mob/living/brain/posibrain.dm @@ -36,7 +36,7 @@ GLOBAL_VAR(posibrain_notify_cooldown) /obj/item/mmi/posibrain/proc/ping_ghosts(msg, newlymade) if(newlymade || GLOB.posibrain_notify_cooldown <= world.time) - notify_ghosts("[name] [msg] in [get_area(src)]!", ghost_sound = !newlymade ? 'sound/misc/server-ready.ogg':null, enter_link = "(Click to enter)", source = src, action = NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_POSIBRAIN) + notify_ghosts("[name] [msg] in [get_area(src)]!", ghost_sound = !newlymade ? 'sound/misc/server-ready.ogg':null, enter_link = "(Click to enter)", source = src, action = NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_POSIBRAIN, ignore_dnr_observers = TRUE) if(!newlymade) GLOB.posibrain_notify_cooldown = world.time + askDelay @@ -88,9 +88,8 @@ GLOBAL_VAR(posibrain_notify_cooldown) if(isobserver(user)) var/mob/dead/observer/O = user - if(O.reenter_round_timeout > world.realtime) - to_chat(user, "You are unable to reenter the round yet. Your ghost role blacklist will expire in [round((O.reenter_round_timeout - world.realtime)/600)] minutes.") - return + if(!O.can_reenter_round()) + return FALSE var/posi_ask = alert("Become a [name]? (Warning, You can no longer be cloned, and all past lives will be forgotten!)","Are you positive?","Yes","No") if(posi_ask == "No" || QDELETED(src)) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm index 7ac718ee6f..948be53abc 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm @@ -21,7 +21,7 @@ . = ..() var/area/A = get_area(src) if(A) - notify_ghosts("A drone shell has been created in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_DRONE) + notify_ghosts("A drone shell has been created in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_DRONE, ignore_dnr_observers = TRUE) GLOB.poi_list |= src if(isnull(possible_seasonal_hats)) build_seasonal_hats() @@ -49,9 +49,8 @@ if(user.client.player_age < DRONE_MINIMUM_AGE) to_chat(user, "You're too new to play as a drone! Please try again in [DRONE_MINIMUM_AGE - user.client.player_age] days.") return - if(user.reenter_round_timeout > world.realtime) - to_chat(user, "You are unable to reenter the round yet. Your ghost role blacklist will expire in [round((user.reenter_round_timeout - world.realtime)/600)] minutes.") - return + if(!user.can_reenter_round()) + return FALSE if(!SSticker.mode) to_chat(user, "Can't become a drone before the game has started.") return diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm index afe49e82dc..c780dd1e96 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm @@ -83,20 +83,19 @@ /mob/living/simple_animal/hostile/poison/giant_spider/proc/humanize_spider(mob/user) if(key || !playable_spider || stat)//Someone is in it, it's dead, or the fun police are shutting it down - return 0 + return FALSE if(isobserver(user)) var/mob/dead/observer/O = user - if(O.reenter_round_timeout > world.realtime) - to_chat(O, "You are unable to reenter the round yet. Your ghost role blacklist will expire in [round((O.reenter_round_timeout - world.realtime)/600)] minutes.") - return + if(!O.can_reenter_round()) + return FALSE var/spider_ask = alert("Become a spider?", "Are you australian?", "Yes", "No") if(spider_ask == "No" || !src || QDELETED(src)) - return 1 + return TRUE if(key) to_chat(user, "Someone else already took this spider.") - return 1 + return TRUE user.transfer_ckey(src, FALSE) - return 1 + return TRUE //nursemaids - these create webs and eggs /mob/living/simple_animal/hostile/poison/giant_spider/nurse diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index da8033205a..f45048632f 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -575,16 +575,15 @@ Difficulty: Very Hard if(..() && !ready_to_deploy) GLOB.poi_list |= src ready_to_deploy = TRUE - notify_ghosts("An anomalous crystal has been activated in [get_area(src)]! This crystal can always be used by ghosts hereafter.", enter_link = "(Click to enter)", ghost_sound = 'sound/effects/ghost2.ogg', source = src, action = NOTIFY_ATTACK) + notify_ghosts("An anomalous crystal has been activated in [get_area(src)]! This crystal can always be used by ghosts hereafter.", enter_link = "(Click to enter)", ghost_sound = 'sound/effects/ghost2.ogg', source = src, action = NOTIFY_ATTACK, ignore_dnr_observers = TRUE) /obj/machinery/anomalous_crystal/helpers/attack_ghost(mob/dead/observer/user) . = ..() if(.) return if(ready_to_deploy) - if(user.reenter_round_timeout > world.realtime) - to_chat(user, "You are unable to reenter the round yet. Your ghost role blacklist will expire in [round((user.reenter_round_timeout - world.realtime)/600)] minutes.") - return + if(!user.can_reenter_round()) + return FALSE var/be_helper = alert("Become a Lightgeist? (Warning, You can no longer be cloned!)",,"Yes","No") if(be_helper == "Yes" && !QDELETED(src) && isobserver(user)) var/mob/living/simple_animal/hostile/lightgeist/W = new /mob/living/simple_animal/hostile/lightgeist(get_turf(loc)) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 5519c9be95..c6c6cf3c09 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -352,12 +352,12 @@ It's fairly easy to fix if dealing with single letters but not so much with comp /mob/proc/reagent_check(datum/reagent/R) // utilized in the species code return 1 -/proc/notify_ghosts(var/message, var/ghost_sound = null, var/enter_link = null, var/atom/source = null, var/mutable_appearance/alert_overlay = null, var/action = NOTIFY_JUMP, flashwindow = TRUE, ignore_mapload = TRUE, ignore_key) //Easy notification of ghosts. +/proc/notify_ghosts(message, ghost_sound, enter_link, atom/source, mutable_appearance/alert_overlay, action = NOTIFY_JUMP, flashwindow = TRUE, ignore_mapload = TRUE, ignore_key, ignore_dnr_observers = FALSE) //Easy notification of ghosts. if(ignore_mapload && SSatoms.initialized != INITIALIZATION_INNEW_REGULAR) //don't notify for objects created during a map load return for(var/mob/dead/observer/O in GLOB.player_list) if(O.client) - if (ignore_key && O.ckey in GLOB.poll_ignore[ignore_key]) + if ((ignore_key && (O.ckey in GLOB.poll_ignore[ignore_key])) || (ignore_dnr_observers && !O.can_reenter_round(TRUE))) continue to_chat(O, "[message][(enter_link) ? " [enter_link]" : ""]") if(ghost_sound) diff --git a/modular_citadel/code/modules/mob/living/simple_animal/banana_spider.dm b/modular_citadel/code/modules/mob/living/simple_animal/banana_spider.dm index fdc271a158..b177687ab2 100644 --- a/modular_citadel/code/modules/mob/living/simple_animal/banana_spider.dm +++ b/modular_citadel/code/modules/mob/living/simple_animal/banana_spider.dm @@ -83,7 +83,7 @@ . = ..() var/area/A = get_area(src) if(A) - notify_ghosts("A banana spider has been created in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE) + notify_ghosts("A banana spider has been created in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_dnr_observers = TRUE) /mob/living/simple_animal/banana_spider/attack_ghost(mob/user) if(key) //please stop using src. without a good reason. @@ -91,12 +91,19 @@ if(CONFIG_GET(flag/use_age_restriction_for_jobs)) if(!isnum(user.client.player_age)) return + if(isobserver(user)) + var/mob/dead/observer/O = user + if(!O.can_reenter_round()) + return if(!SSticker.mode) to_chat(user, "Can't become a banana spider before the game has started.") return var/be_spider = alert("Become a banana spider? (Warning, You can no longer be cloned!)",,"Yes","No") if(be_spider == "No" || QDELETED(src) || !isobserver(user)) return + if(key) + to_chat(user, "Someone else already took this banana spider.") + return sentience_act() user.transfer_ckey(src, FALSE) density = TRUE From a5086d58131f43e17fae004f34e8edc88bf0ba0e Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Tue, 29 Oct 2019 13:16:36 +0100 Subject: [PATCH 5/5] 3 seconds penalties fix --- code/modules/mob/dead/observer/observer.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index f2a24cd763..93988cf0c4 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -270,8 +270,8 @@ Works together with spawning an observer, noted above. SStgui.on_transfer(src, ghost) // Transfer NanoUIs. ghost.can_reenter_corpse = can_reenter_corpse if(penalize) //penalizing them from making a ghost role / midround antag comeback right away. - var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) - var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) + var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES + var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES if(world.time < roundstart_quit_limit) //add up the time difference to their antag rolling penalty if they quit before half a (ingame) hour even passed. penalty += roundstart_quit_limit - world.time if(penalty)