diff --git a/modular_citadel/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
similarity index 69%
rename from modular_citadel/code/game/machinery/cryopod.dm
rename to code/game/machinery/cryopod.dm
index 15e7d34c65..e358f10346 100644
--- a/modular_citadel/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -20,105 +20,146 @@
req_one_access = list(ACCESS_HEADS, ACCESS_ARMORY) //Heads of staff or the warden can go here to claim recover items from their department that people went were cryodormed with.
var/mode = null
+ var/menu = 1 //Which menu screen to display
+
//Used for logging people entering cryosleep and important items they are carrying.
var/list/frozen_crew = list()
var/list/frozen_items = list()
- var/storage_type = "crewmembers"
- var/storage_name = "Cryogenic Oversight Control"
+ // Used for containing rare items traitors need to steal, so it's not
+ // game-over if they get iced
+ var/list/objective_items = list()
+ // A cache of theft datums so you don't have to re-create them for
+ // each item check
+ var/list/theft_cache = list()
+
var/allow_items = TRUE
+/obj/machinery/computer/cryopod/attack_ai()
+ attack_hand()
+
/obj/machinery/computer/cryopod/ui_interact(mob/user = usr)
- . = ..()
+ if(!is_operational())
+ return
user.set_machine(src)
add_fingerprint(user)
- var/dat
+ var/dat = ""
- dat += "
[storage_name]
"
- dat += "Welcome, [user.real_name].
"
- dat += "View storage log.
"
- if(allow_items)
- dat += "View objects.
"
- dat += "Recover object.
"
- dat += "Recover all objects.
"
+ dat += "Welcome, [user.real_name].
"
+ dat += "
"
- user << browse(dat, "window=cryopod_console")
- onclose(user, "cryopod_console")
+ switch(src.menu)
+ if(1)
+ dat += "View crew storage log
"
+ if(allow_items)
+ dat += "View objects storage log
"
+ dat += "Recover object
"
+ dat += "Recover all objects
"
+ if(2)
+ dat += "<< Back
"
+ dat += "Recently stored Crew
"
+ if(!frozen_crew.len)
+ dat += "There has been no storage usage at this terminal.
"
+ else
+ for(var/person in frozen_crew)
+ dat += "[person]
"
+ dat += "
"
+ if(3)
+ dat += "<< Back
"
+ dat += "Recently stored objects
"
+ if(!frozen_items.len)
+ dat += "There has been no storage usage at this terminal.
"
+ else
+ for(var/obj/item/I in frozen_items)
+ dat += "[I.name]
"
+ dat += "
"
+
+ var/datum/browser/popup = new(user, "cryopod_console", "Cryogenic System Control")
+ popup.set_content(dat)
+ popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
+ popup.open()
/obj/machinery/computer/cryopod/Topic(href, href_list)
if(..())
- return 1
+ return TRUE
var/mob/user = usr
add_fingerprint(user)
- if(href_list["log"])
-
- var/dat = "Recently stored [storage_type]
"
- for(var/person in frozen_crew)
- dat += "[person]
"
- dat += "
"
-
- user << browse(dat, "window=cryolog")
-
- if(href_list["view"])
- if(!allow_items) return
-
- var/dat = "Recently stored objects
"
- for(var/obj/item/I in frozen_items)
- dat += "[I.name]
"
- dat += "
"
-
- user << browse(dat, "window=cryoitems")
-
- else if(href_list["item"])
+ if(href_list["item"])
if(!allowed(user))
to_chat(user, "Access Denied.")
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+ updateUsrDialog()
return
if(!allow_items) return
if(frozen_items.len == 0)
to_chat(user, "There is nothing to recover from storage.")
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+ updateUsrDialog()
return
var/obj/item/I = input(user, "Please choose which object to retrieve.","Object recovery",null) as null|anything in frozen_items
+ playsound(src, "terminal_type", 25, 0)
if(!I)
return
if(!(I in frozen_items))
to_chat(user, "\The [I] is no longer in storage.")
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+ updateUsrDialog()
return
visible_message("The console beeps happily as it disgorges \the [I].")
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
- I.forceMove(get_turf(src))
+ I.forceMove(drop_location())
+ if(user && Adjacent(user) && !issiliconoradminghost(user))
+ user.put_in_hands(I)
frozen_items -= I
+ updateUsrDialog()
else if(href_list["allitems"])
+ playsound(src, "terminal_type", 25, 0)
if(!allowed(user))
to_chat(user, "Access Denied.")
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+ updateUsrDialog()
return
if(!allow_items) return
if(frozen_items.len == 0)
to_chat(user, "There is nothing to recover from storage.")
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
visible_message("The console beeps happily as it disgorges the desired objects.")
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
for(var/obj/item/I in frozen_items)
- I.forceMove(get_turf(src))
+ I.forceMove(drop_location())
frozen_items -= I
+ updateUsrDialog()
+ else if (href_list["menu"])
+ src.menu = text2num(href_list["menu"])
+ playsound(src, "terminal_type", 25, 0)
+ updateUsrDialog()
+
+ ui_interact(usr)
updateUsrDialog()
+ return
/obj/item/circuitboard/cryopodcontrol
name = "Circuit board (Cryogenic Oversight Console)"
build_path = "/obj/machinery/computer/cryopod"
+/obj/machinery/computer/cryopod/contents_explosion()
+ return
//Cryopods themselves.
/obj/machinery/cryopod
@@ -176,16 +217,17 @@
/obj/item/gun/energy/laser/cyborg
)
-/obj/machinery/cryopod/Initialize()
+/obj/machinery/cryopod/Initialize(mapload)
. = ..()
update_icon()
- find_control_computer(TRUE)
+ find_control_computer(mapload)
/obj/machinery/cryopod/proc/find_control_computer(urgent = FALSE)
for(var/obj/machinery/computer/cryopod/C in get_area(src))
control_computer = C
if(C)
return C
+ break
// Don't send messages unless we *need* the computer, and less than five minutes have passed since last time we messaged
if(!control_computer && urgent && last_no_computer_message + 5*60*10 < world.time)
@@ -193,7 +235,7 @@
message_admins("Cryopod in [get_area(src)] could not find control computer!")
last_no_computer_message = world.time
- return null
+ return control_computer != null
/obj/machinery/cryopod/close_machine(mob/user)
if(!control_computer)
@@ -242,10 +284,75 @@
despawn_occupant()
+#define CRYO_DESTROY 0
+#define CRYO_PRESERVE 1
+#define CRYO_OBJECTIVE 2
+
+/obj/machinery/cryopod/proc/should_preserve_item(obj/item/I)
+ for(var/datum/objective_item/steal/T in control_computer.theft_cache)
+ if(istype(I, T.targetitem) && T.check_special_completion(I))
+ return CRYO_OBJECTIVE
+ for(var/T in preserve_items)
+ if(istype(I, T) && !(I.type in do_not_preserve_items))
+ return CRYO_PRESERVE
+ return CRYO_DESTROY
+
// This function can not be undone; do not call this unless you are sure
/obj/machinery/cryopod/proc/despawn_occupant()
+ if(!control_computer)
+ find_control_computer()
+
var/mob/living/mob_occupant = occupant
+ //Handle Borg stuff first
+ if(iscyborg(mob_occupant))
+ var/mob/living/silicon/robot/R = mob_occupant
+ if(!istype(R)) return ..()
+
+ R.contents -= R.mmi
+ qdel(R.mmi)
+ for(var/obj/item/I in R.module) // the tools the borg has; metal, glass, guns etc
+ for(var/obj/item/O in I) // the things inside the tools, if anything; mainly for janiborg trash bags
+ if(should_preserve_item(O) != CRYO_DESTROY) // Preserve important things inside the item
+ continue
+ O.forceMove(src)
+ R.module.remove_module(I, TRUE) //delete the module itself so it doesn't transfer over.
+
+ //Drop all items into the pod.
+ for(var/obj/item/I in mob_occupant)
+ mob_occupant.doUnEquip(I)
+ I.forceMove(src)
+
+ if(I.contents.len) //Make sure we catch anything not handled by qdel() on the items.
+ if(should_preserve_item(I) != CRYO_DESTROY) // Don't remove the contents of things that need preservation
+ continue
+ for(var/obj/item/O in I.contents)
+ if(istype(O, /obj/item/tank)) //Stop eating pockets, you fuck!
+ continue
+ O.forceMove(src)
+
+ //Delete all items not on the preservation list.
+ var/list/items = contents
+ items -= mob_occupant // Don't delete the occupant
+
+ for(var/obj/item/I in items)
+ if(istype(I, /obj/item/pda))
+ var/obj/item/pda/P = I
+ QDEL_NULL(P.id)
+ qdel(P)
+ continue
+
+ var/preserve = should_preserve_item(I)
+ if(preserve == CRYO_DESTROY)
+ qdel(I)
+ else if(control_computer && control_computer.allow_items)
+ control_computer.frozen_items += I
+ if(preserve == CRYO_OBJECTIVE)
+ control_computer.objective_items += I
+ I.loc = null
+ else
+ I.forceMove(loc)
+
//Update any existing objectives involving this mob.
for(var/datum/objective/O in GLOB.objectives)
// We don't want revs to get objectives that aren't for heads of staff. Letting
@@ -302,30 +409,6 @@
announcer.announce("CRYOSTORAGE", mob_occupant.real_name, announce_rank, list())
visible_message("\The [src] hums and hisses as it moves [mob_occupant.real_name] into storage.")
-
- for(var/obj/item/W in mob_occupant.GetAllContents())
- if(W.loc.loc && (( W.loc.loc == loc ) || (W.loc.loc == control_computer)))
- continue//means we already moved whatever this thing was in
- //I'm a professional, okay
- for(var/T in preserve_items)
- if(istype(W, T))
- if(control_computer && control_computer.allow_items)
- control_computer.frozen_items += W
- mob_occupant.transferItemToLoc(W, control_computer, TRUE)
- else
- mob_occupant.transferItemToLoc(W, loc, TRUE)
-
- for(var/obj/item/W in mob_occupant.GetAllContents())
- qdel(W)//because we moved all items to preserve away
- //and yes, this totally deletes their bodyparts one by one, I just couldn't bother
-
- if(iscyborg(mob_occupant))
- var/mob/living/silicon/robot/R = occupant
- if(!istype(R)) return ..()
-
- R.contents -= R.mmi
- qdel(R.mmi)
-
// 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
@@ -334,6 +417,10 @@
open_machine()
name = initial(name)
+#undef CRYO_DESTROY
+#undef CRYO_PRESERVE
+#undef CRYO_OBJECTIVE
+
/obj/machinery/cryopod/MouseDrop_T(mob/living/target, mob/user)
if(!istype(target) || user.incapacitated() || !target.Adjacent(user) || !Adjacent(user) || !ismob(target) || (!ishuman(user) && !iscyborg(user)) || !istype(user.loc, /turf) || target.buckled)
return
@@ -358,7 +445,7 @@
var/generic_plsnoleave_message = " Please adminhelp before leaving the round, even if there are no administrators online!"
- if(target == user && world.time - target.client.cryo_warned > 5 * 600)//if we haven't warned them in the last 5 minutes
+ if(target == user && world.time - target.client.cryo_warned > 5 MINUTES)//if we haven't warned them in the last 5 minutes
var/caught = FALSE
if(target.mind.assigned_role in GLOB.command_positions)
alert("You're a Head of Staff![generic_plsnoleave_message] Be sure to put your locker items back into your locker!")
@@ -366,13 +453,13 @@
if(iscultist(target) || is_servant_of_ratvar(target))
to_chat(target, "You're a Cultist![generic_plsnoleave_message]")
caught = TRUE
- if(istype(SSticker.mode, /datum/antagonist/blob))
- if(target.mind in GLOB.overminds)
- alert("You're a Blob![generic_plsnoleave_message]")
- caught = TRUE
if(is_devil(target))
alert("You're a Devil![generic_plsnoleave_message]")
caught = TRUE
+ if(istype(SSticker.mode, /datum/antagonist/gang))
+ if(target.mind.has_antag_datum(/datum/antagonist/gang))
+ alert("You're a Gangster![generic_plsnoleave_message]")
+ caught = TRUE
if(istype(SSticker.mode, /datum/antagonist/rev))
if(target.mind.has_antag_datum(/datum/antagonist/rev/head))
alert("You're a Head Revolutionary![generic_plsnoleave_message]")
@@ -385,8 +472,9 @@
target.client.cryo_warned = world.time
return
- if(!Adjacent(user))
+ if(!target || user.incapacitated() || !target.Adjacent(user) || !Adjacent(user) || (!ishuman(user) && !iscyborg(user)) || !istype(user.loc, /turf) || target.buckled)
return
+ //rerun the checks in case of shenanigans
if(target == user)
visible_message("[user] starts climbing into the cryo pod.")
@@ -396,7 +484,6 @@
if(occupant)
to_chat(user, "\The [src] is in use.")
return
-
close_machine(target)
to_chat(target, "If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.")
@@ -407,4 +494,4 @@
//Attacks/effects.
/obj/machinery/cryopod/blob_act()
- return //Sorta gamey, but we don't really want these to be destroyed.
+ return //Sorta gamey, but we don't really want these to be destroyed.
\ No newline at end of file
diff --git a/tgstation.dme b/tgstation.dme
index cceeb1f915..be270841a4 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -581,6 +581,7 @@
#include "code\game\machinery\cell_charger.dm"
#include "code\game\machinery\cloning.dm"
#include "code\game\machinery\constructable_frame.dm"
+#include "code\game\machinery\cryopod.dm"
#include "code\game\machinery\dance_machine.dm"
#include "code\game\machinery\defibrillator_mount.dm"
#include "code\game\machinery\deployable.dm"
@@ -2922,7 +2923,6 @@
#include "modular_citadel\code\game\gamemodes\gangs\implant_gang.dm"
#include "modular_citadel\code\game\gamemodes\miniantags\bot_swarm\swarmer_event.dm"
#include "modular_citadel\code\game\gamemodes\revolution\revolution.dm"
-#include "modular_citadel\code\game\machinery\cryopod.dm"
#include "modular_citadel\code\game\machinery\displaycases.dm"
#include "modular_citadel\code\game\machinery\firealarm.dm"
#include "modular_citadel\code\game\machinery\Sleeper.dm"