diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm
index f9c3653b35..8d5e216f9e 100644
--- a/_maps/map_files/generic/CentCom.dmm
+++ b/_maps/map_files/generic/CentCom.dmm
@@ -10005,6 +10005,12 @@
/obj/structure/chair/stool,
/turf/open/floor/plasteel,
/area/syndicate_mothership)
+"wZ" = (
+/obj/structure/bed,
+/obj/item/bedsheet/syndie,
+/obj/effect/landmark/holding_facility,
+/turf/open/indestructible/hotelwood,
+/area/centcom/holding)
"xa" = (
/obj/machinery/door/window/northright{
dir = 4;
@@ -12452,6 +12458,13 @@
},
/turf/open/floor/plasteel/dark,
/area/centcom/evac)
+"CQ" = (
+/obj/effect/landmark/holding_facility,
+/mob/living/simple_animal/bot/medbot{
+ name = "Syndicate Hospitality Drone"
+ },
+/turf/open/indestructible/hotelwood,
+/area/centcom/holding)
"CR" = (
/obj/machinery/computer/security{
dir = 8
@@ -17251,10 +17264,21 @@
/obj/structure/window/reinforced/fulltile,
/turf/open/indestructible/hotelwood,
/area/centcom/holding)
+"Ql" = (
+/obj/machinery/light,
+/obj/effect/landmark/holding_facility,
+/turf/open/indestructible/hotelwood,
+/area/centcom/holding)
"Qm" = (
/obj/singularity/wizard/mapped,
/turf/open/indestructible/binary,
/area/fabric_of_reality)
+"Qn" = (
+/obj/machinery/vr_sleeper/hugbox{
+ dir = 8
+ },
+/turf/open/indestructible/hotelwood,
+/area/centcom/holding)
"Qo" = (
/turf/open/floor/mineral/plastitanium/red,
/area/centcom/evac)
@@ -17794,7 +17818,7 @@
/area/syndicate_mothership)
"Tn" = (
/obj/structure/table/wood/fancy,
-/obj/item/candle/infinite{
+/obj/item/candle/infinite/hugbox{
pixel_y = 6
},
/turf/open/indestructible/hotelwood,
@@ -17820,7 +17844,6 @@
dir = 4
},
/obj/structure/window/reinforced/tinted{
- icon_state = "twindow";
dir = 1
},
/turf/open/floor/plasteel/white,
@@ -17897,7 +17920,6 @@
dir = 8
},
/obj/structure/window/reinforced/tinted{
- icon_state = "twindow";
dir = 1
},
/obj/machinery/washing_machine,
@@ -17939,10 +17961,13 @@
/obj/vehicle/ridden/janicart,
/turf/open/indestructible/hotelwood,
/area/centcom/holding)
-"Ud" = (
-/obj/effect/landmark/holding_facility,
+"Uc" = (
+/obj/machinery/vending/sustenance,
/turf/open/indestructible/hotelwood,
/area/centcom/holding)
+"Ud" = (
+/turf/closed/indestructible/wood,
+/area/centcom/holding)
"Ug" = (
/obj/machinery/door/poddoor/shuttledock{
checkdir = 1;
@@ -18844,6 +18869,10 @@
/obj/effect/landmark/start/nukeop_leader,
/turf/open/floor/wood,
/area/syndicate_mothership)
+"ZB" = (
+/obj/effect/landmark/holding_facility,
+/turf/open/indestructible/hotelwood,
+/area/centcom/holding)
"ZE" = (
/obj/structure/sink{
dir = 4;
@@ -43829,11 +43858,11 @@ aa
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
+Ud
+Ud
+Ud
+Ud
+Ud
aa
aa
aa
@@ -44086,11 +44115,11 @@ aa
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
+Ud
+Uc
+ZB
+ZB
+Ud
aa
aa
aa
@@ -44343,11 +44372,11 @@ aa
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
+Ud
+ZB
+CQ
+Ql
+Ud
aa
aa
aa
@@ -44600,11 +44629,11 @@ aa
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
+Ud
+wZ
+ZB
+Qn
+Ud
aa
aa
aa
@@ -44857,11 +44886,11 @@ aa
aa
aa
aa
-aa
-aa
-aa
-aa
-aa
+Ud
+Ud
+Ud
+Ud
+Ud
aa
aa
aa
@@ -46174,8 +46203,8 @@ Sd
HH
Nd
WM
-Ud
-Ud
+Sd
+Sd
NT
Nj
Po
@@ -46431,8 +46460,8 @@ Sd
XM
NT
Sd
-Ud
-Ud
+Sd
+Sd
NT
YU
zT
@@ -46688,8 +46717,8 @@ Sd
Tn
NT
Sd
-Ud
-Ud
+Sd
+Sd
NT
YU
zT
@@ -46945,8 +46974,8 @@ Sd
GY
NT
Sd
-Ud
-Ud
+Sd
+Sd
NT
YU
zT
@@ -47202,8 +47231,8 @@ Qk
Vu
Nd
Gs
-Ud
-Ud
+Sd
+Sd
NT
Mt
PA
diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index bd77e374aa..a088b0fc57 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -149,7 +149,9 @@
#define COMSIG_MOB_DEATH "mob_death" //from base of mob/death(): (gibbed)
#define COMPONENT_BLOCK_DEATH_BROADCAST 1 //stops the death from being broadcasted in deadchat.
#define COMSIG_MOB_GHOSTIZE "mob_ghostize" //from base of mob/Ghostize(): (can_reenter_corpse, special, penalize)
- #define COMPONENT_BLOCK_GHOSTING 1
+ #define COMPONENT_BLOCK_GHOSTING (1<<0)
+ #define COMPONENT_DO_NOT_PENALIZE_GHOSTING (1<<1)
+ #define COMPONENT_FREE_GHOSTING (1<<2)
#define COMSIG_MOB_ALLOWED "mob_allowed" //from base of obj/allowed(mob/M): (/obj) returns bool, if TRUE the mob has id access to the obj
#define COMSIG_MOB_RECEIVE_MAGIC "mob_receive_magic" //from base of mob/anti_magic_check(): (mob/user, magic, holy, tinfoil, chargecost, self, protection_sources)
#define COMPONENT_BLOCK_MAGIC 1
diff --git a/code/datums/elements/ghost_role_eligibility.dm b/code/datums/elements/ghost_role_eligibility.dm
index 28567c579b..519a34e01f 100644
--- a/code/datums/elements/ghost_role_eligibility.dm
+++ b/code/datums/elements/ghost_role_eligibility.dm
@@ -1,12 +1,17 @@
/datum/element/ghost_role_eligibility
- element_flags = ELEMENT_DETACH
+ element_flags = ELEMENT_DETACH | ELEMENT_BESPOKE
+ id_arg_index = 3
var/list/timeouts = list()
var/list/mob/eligible_mobs = list()
+ var/penalizing = FALSE
+ var/free_ghost = FALSE
-/datum/element/ghost_role_eligibility/Attach(datum/target,penalize = FALSE)
+/datum/element/ghost_role_eligibility/Attach(datum/target,penalize = FALSE,free_ghosting = FALSE, penalize_on_ghost = FALSE)
. = ..()
if(!ismob(target))
return ELEMENT_INCOMPATIBLE
+ penalizing = penalize_on_ghost
+ free_ghost = free_ghosting
var/mob/M = target
if(!(M in eligible_mobs))
eligible_mobs += M
@@ -27,6 +32,7 @@
else if(timeouts[M.ckey] == CANT_REENTER_ROUND)
return
timeouts[M.ckey] = max(timeouts[M.ckey],penalty)
+ RegisterSignal(M,COMSIG_MOB_GHOSTIZE,.proc/get_ghost_flags)
/datum/element/ghost_role_eligibility/Detach(mob/M)
. = ..()
@@ -56,3 +62,11 @@
if(!silent && M.client)
to_chat(M, "You are unable to reenter the round[timeout != CANT_REENTER_ROUND ? " yet. Your ghost role blacklist will expire in [DisplayTimeText(timeout - world.realtime)]" : ""].")
return FALSE
+
+/datum/element/ghost_role_eligibility/proc/get_ghost_flags()
+ . = 0
+ if(!penalizing)
+ . |= COMPONENT_DO_NOT_PENALIZE_GHOSTING
+ if(free_ghost)
+ . |= COMPONENT_FREE_GHOSTING
+ return .
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 57b9a25904..45a0f86a98 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -470,7 +470,6 @@
/datum/objective/steal,
/datum/objective/download,
/datum/objective/nuclear,
- /datum/objective/capture,
/datum/objective/absorb,
/datum/objective/custom
)
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index b42b41aba4..4497f9faef 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -663,7 +663,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
if(count)
target_amount = count
update_explanation_text()
-
+/*
/datum/objective/capture
name = "capture"
var/captured_amount = 0
@@ -709,7 +709,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
if(count)
target_amount = count
update_explanation_text()
-
+*/
//Changeling Objectives
/datum/objective/absorb
diff --git a/code/game/objects/items/candle.dm b/code/game/objects/items/candle.dm
index 11ab008c41..a3366e714e 100644
--- a/code/game/objects/items/candle.dm
+++ b/code/game/objects/items/candle.dm
@@ -13,6 +13,7 @@
var/lit = FALSE
var/infinite = FALSE
var/start_lit = FALSE
+ var/heats_space = TRUE
/obj/item/candle/Initialize()
. = ..()
@@ -35,7 +36,7 @@
return ..()
/obj/item/candle/get_temperature()
- return lit * heat
+ return lit * heat * heats_space
/obj/item/candle/proc/light(show_message)
if(!lit)
@@ -67,7 +68,8 @@
new /obj/item/trash/candle(loc)
qdel(src)
update_icon()
- open_flame()
+ if(heats_space)
+ open_flame()
/obj/item/candle/attack_self(mob/user)
if(put_out_candle())
@@ -77,4 +79,7 @@
infinite = TRUE
start_lit = TRUE
+/obj/item/candle/infinite/hugbox
+ heats_space = FALSE
+
#undef CANDLE_LUMINOSITY
diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm
index bd9ac276a2..b8f15ec295 100644
--- a/code/game/objects/items/holy_weapons.dm
+++ b/code/game/objects/items/holy_weapons.dm
@@ -494,7 +494,7 @@
S.ckey = C.ckey
S.status_flags |= GODMODE
S.language_holder = user.language_holder.copy(S)
- S.AddElement(/datum/element/ghost_role_eligibility)
+ S.AddElement(/datum/element/ghost_role_eligibility,penalize_on_ghost = TRUE)
START_PROCESSING(SSprocessing,src)
var/input = stripped_input(S,"What are you named?", ,"", MAX_NAME_LEN)
diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm
index 65145c0eed..c918e7b867 100644
--- a/code/game/objects/structures/ghost_role_spawners.dm
+++ b/code/game/objects/structures/ghost_role_spawners.dm
@@ -674,17 +674,14 @@
O.equip(new_spawn, FALSE, new_spawn.client)
SSjob.equip_loadout(null, new_spawn, FALSE)
SSquirks.AssignQuirks(new_spawn, new_spawn.client, TRUE, TRUE, null, FALSE, new_spawn)
- new_spawn.AddElement(/datum/element/ghost_role_eligibility)
+ new_spawn.AddElement(/datum/element/ghost_role_eligibility, free_ghosting = TRUE)
new_spawn.AddElement(/datum/element/dusts_on_catatonia)
new_spawn.AddElement(/datum/element/dusts_on_leaving_area,list(A.type,/area/hilbertshotel))
ADD_TRAIT(new_spawn, TRAIT_SIXTHSENSE, GHOSTROLE_TRAIT)
ADD_TRAIT(new_spawn, TRAIT_EXEMPT_HEALTH_EVENTS, GHOSTROLE_TRAIT)
- ADD_TRAIT(new_spawn, TRAIT_NO_MIDROUND_ANTAG, GHOSTROLE_TRAIT) //The mob can't be made into a random antag, they are still elegible for ghost roles popups.
+ ADD_TRAIT(new_spawn, TRAIT_NO_MIDROUND_ANTAG, GHOSTROLE_TRAIT) //The mob can't be made into a random antag, they are still eligible for ghost roles popups.
ADD_TRAIT(new_spawn, TRAIT_PACIFISM, GHOSTROLE_TRAIT)
- to_chat(new_spawn,"You may be sharing your cafe with some ninja-captured individuals, so make sure to only interact with the ghosts you hear as a ghost!")
- to_chat(new_spawn,"You can turn yourself into a ghost and freely reenter your body with the ghost action.")
- var/datum/action/ghost/G = new(new_spawn)
- G.Grant(new_spawn)
+ to_chat(new_spawn,"Ghosting is free!")
var/datum/action/toggle_dead_chat_mob/D = new(new_spawn)
D.Grant(new_spawn)
diff --git a/code/modules/events/sentience.dm b/code/modules/events/sentience.dm
index 1a303ec4bc..8fe68f509b 100644
--- a/code/modules/events/sentience.dm
+++ b/code/modules/events/sentience.dm
@@ -59,7 +59,7 @@
SA.del_on_death = FALSE
spawned_mobs += SA
- SA.AddElement(/datum/element/ghost_role_eligibility)
+ SA.AddElement(/datum/element/ghost_role_eligibility, penalize_on_ghost = TRUE)
to_chat(SA, "Hello world!")
to_chat(SA, "Due to freak radiation and/or chemicals \
and/or lucky chance, you have gained human level intelligence \
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 78e38c5b89..3023b93856 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -263,14 +263,15 @@ Works together with spawning an observer, noted above.
*/
/mob/proc/ghostize(can_reenter_corpse = TRUE, special = FALSE, penalize = FALSE, voluntary = FALSE)
- penalize = suiciding || penalize // suicide squad.
+ var/sig_flags = SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse, special, penalize)
+ penalize = !(sig_flags & COMPONENT_DO_NOT_PENALIZE_GHOSTING) && (suiciding || penalize) // suicide squad.
voluntary_ghosted = voluntary
- if(!key || key[1] == "@" || (SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse, special, penalize) & COMPONENT_BLOCK_GHOSTING))
+ if(!key || key[1] == "@" || (sig_flags & 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(get_turf(src), src) // Transfer safety to observer spawning proc.
SStgui.on_transfer(src, ghost) // Transfer NanoUIs.
- ghost.can_reenter_corpse = can_reenter_corpse
+ ghost.can_reenter_corpse = can_reenter_corpse || (sig_flags & COMPONENT_FREE_GHOSTING)
if (client && client.prefs && client.prefs.auto_ooc)
if (!(client.prefs.chat_toggles & CHAT_OOC))
client.prefs.chat_toggles ^= CHAT_OOC
@@ -297,12 +298,17 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(penalty - SSshuttle.realtimeofstart > maximumRoundEnd + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
penalty = CANT_REENTER_ROUND
- if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, (stat == DEAD) ? TRUE : FALSE, FALSE, (stat == DEAD)? penalty : 0, (stat == DEAD)? TRUE : FALSE) & COMPONENT_BLOCK_GHOSTING)
+ var/sig_flags = SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, (stat == DEAD) ? TRUE : FALSE, FALSE, (stat == DEAD)? penalty : 0, (stat == DEAD)? TRUE : FALSE)
+
+ if(sig_flags & COMPONENT_BLOCK_GHOSTING)
return
+ if(sig_flags & COMPONENT_DO_NOT_PENALIZE_GHOSTING)
+ penalty = 0
+
if(stat != DEAD)
succumb()
- if(stat == DEAD)
+ if(stat == DEAD || sig_flags & COMPONENT_FREE_GHOSTING)
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 [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")
@@ -321,7 +327,9 @@ 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."
- if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, FALSE, FALSE) & COMPONENT_BLOCK_GHOSTING)
+ var/sig_flags = SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, FALSE, FALSE)
+
+ if(sig_flags & COMPONENT_BLOCK_GHOSTING)
return
var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES
@@ -333,10 +341,16 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(penalty - SSshuttle.realtimeofstart > maximumRoundEnd + 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 [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)
+ if(sig_flags & COMPONENT_DO_NOT_PENALIZE_GHOSTING)
+ penalty = 0
+
+ if(sig_flags & COMPONENT_FREE_GHOSTING)
+ 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 [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)
@@ -670,7 +684,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return 0
transfer_ckey(target, FALSE)
- target.AddElement(/datum/element/ghost_role_eligibility)
+ target.AddElement(/datum/element/ghost_role_eligibility, penalize_on_ghost = FALSE, free_ghosting = TRUE)
target.faction = list("neutral")
return 1
diff --git a/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm b/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm
index b360a70775..c723f2cd7b 100644
--- a/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm
+++ b/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm
@@ -57,12 +57,12 @@ It is possible to destroy the net by the occupant or someone else.
continue//So all they're left with are shoes and uniform.
H.dropItemToGround(W)
H.dna.species.give_important_for_life(H) // After we remove items, at least give them what they need to live.
+/*
var/datum/antagonist/antag_datum
for(var/datum/antagonist/ninja/AD in GLOB.antagonists) //Because only ninjas get capture objectives; They're not doable without the suit.
if(AD.owner == master)
antag_datum = AD
break
-
for(var/datum/objective/capture/capture in antag_datum)
if(istype(affecting, /mob/living/carbon/human)) //Humans.
if(affecting.stat == DEAD)//Dead folks are worth less.
@@ -87,7 +87,7 @@ It is possible to destroy the net by the occupant or someone else.
capture.captured_amount+=1
continue
capture.captured_amount+=2
-
+*/
affecting.revive(1, 1) //Basically a revive and full heal, including limbs/organs
//In case people who have been captured dead want to hang out at the holding area
diff --git a/code/modules/ninja/suit/suit.dm b/code/modules/ninja/suit/suit.dm
index 01e6abaa6a..b46f30b4fb 100644
--- a/code/modules/ninja/suit/suit.dm
+++ b/code/modules/ninja/suit/suit.dm
@@ -22,7 +22,7 @@ Contents:
armor = list("melee" = 60, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 100, "acid" = 100)
strip_delay = 12
- actions_types = list(/datum/action/item_action/initialize_ninja_suit, /datum/action/item_action/ninjasmoke, /datum/action/item_action/ninjaboost, /datum/action/item_action/ninjapulse, /datum/action/item_action/ninjastar, /datum/action/item_action/ninjanet, /datum/action/item_action/ninja_sword_recall, /datum/action/item_action/ninja_stealth, /datum/action/item_action/toggle_glove)
+ actions_types = list(/datum/action/item_action/initialize_ninja_suit, /datum/action/item_action/ninjasmoke, /datum/action/item_action/ninjaboost, /datum/action/item_action/ninjapulse, /datum/action/item_action/ninjastar, /datum/action/item_action/ninja_sword_recall, /datum/action/item_action/ninja_stealth, /datum/action/item_action/toggle_glove)
//Important parts of the suit.
var/mob/living/carbon/human/affecting = null
@@ -175,9 +175,6 @@ Contents:
if(istype(action, /datum/action/item_action/ninjastar))
ninjastar()
return TRUE
- if(istype(action, /datum/action/item_action/ninjanet))
- ninjanet()
- return TRUE
if(istype(action, /datum/action/item_action/ninja_sword_recall))
ninja_sword_recall()
return TRUE