diff --git a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm
index 4511f8bd5a7..865490aef28 100644
--- a/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/vent_pump.dm
@@ -381,6 +381,8 @@
if(!welded)
if(open)
for(var/obj/item/W in src)
+ if(istype(W, /obj/item/pipe))
+ continue
W.forceMove(get_turf(src))
diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm
index 6f14b75b2ec..967749a55a7 100644
--- a/code/__DEFINES/components.dm
+++ b/code/__DEFINES/components.dm
@@ -17,7 +17,8 @@
// /datum signals
#define COMSIG_COMPONENT_ADDED "component_added" //when a component is added to a datum: (/datum/component)
#define COMSIG_COMPONENT_REMOVING "component_removing" //before a component is removed from a datum because of RemoveComponent: (/datum/component)
-#define COMSIG_PARENT_QDELETED "parent_qdeleted" //before a datum's Destroy() is called: ()
+#define COMSIG_PARENT_PREQDELETED "parent_preqdeleted" //before a datum's Destroy() is called: (force), returning a nonzero value will cancel the qdel operation
+#define COMSIG_PARENT_QDELETED "parent_qdeleted" //after a datum's Destroy() is called: (force, qdel_hint), at this point none of the other components chose to interrupt qdel and Destroy has been called
// /atom signals
#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params)
diff --git a/code/__DEFINES/qdel.dm b/code/__DEFINES/qdel.dm
index 8d504edaf41..6adb876da8d 100644
--- a/code/__DEFINES/qdel.dm
+++ b/code/__DEFINES/qdel.dm
@@ -11,14 +11,12 @@
#define QDEL_HINT_IFFAIL_FINDREFERENCE 6 //Above but only if gc fails.
//defines for the gc_destroyed var
-#define GC_QUEUE_PREQUEUE 1
-#define GC_QUEUE_CHECK 2
-#define GC_QUEUE_HARDDELETE 3
-#define GC_QUEUE_COUNT 3 //increase this when adding more steps.
+#define GC_QUEUE_CHECK 1
+#define GC_QUEUE_HARDDELETE 2
+#define GC_QUEUE_COUNT 2 //increase this when adding more steps.
#define GC_QUEUED_FOR_QUEUING -1
-#define GC_QUEUED_FOR_HARD_DEL -2
-#define GC_CURRENTLY_BEING_QDELETED -3
+#define GC_CURRENTLY_BEING_QDELETED -2
#define QDELING(X) (X.gc_destroyed)
#define QDELETED(X) (!X || QDELING(X))
diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm
index 7c38ee1072a..623d1bb5dd6 100644
--- a/code/_onclick/hud/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects.dm
@@ -175,66 +175,111 @@
icon_state = "zone_sel"
screen_loc = ui_zonesel
var/selecting = "chest"
+ var/static/list/hover_overlays_cache = list()
+ var/hovering
/obj/screen/zone_sel/Click(location, control,params)
+ if(isobserver(usr))
+ return
+
var/list/PL = params2list(params)
var/icon_x = text2num(PL["icon-x"])
var/icon_y = text2num(PL["icon-y"])
- var/old_selecting = selecting //We're only going to update_icon() if there's been a change
+ var/choice = get_zone_at(icon_x, icon_y)
+ if(!choice)
+ return 1
+ return set_selected_zone(choice, usr)
+
+/obj/screen/zone_sel/MouseEntered(location, control, params)
+ MouseMove(location, control, params)
+
+/obj/screen/zone_sel/MouseMove(location, control, params)
+ if(isobserver(usr))
+ return
+
+ var/list/PL = params2list(params)
+ var/icon_x = text2num(PL["icon-x"])
+ var/icon_y = text2num(PL["icon-y"])
+ var/choice = get_zone_at(icon_x, icon_y)
+
+ if(hovering == choice)
+ return
+ cut_overlay(hover_overlays_cache[hovering])
+ hovering = choice
+
+ var/obj/effect/overlay/zone_sel/overlay_object = hover_overlays_cache[choice]
+ if(!overlay_object)
+ overlay_object = new
+ overlay_object.icon_state = "[choice]"
+ hover_overlays_cache[choice] = overlay_object
+ add_overlay(overlay_object)
+
+
+/obj/effect/overlay/zone_sel
+ icon = 'icons/mob/zone_sel.dmi'
+ mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ alpha = 128
+ anchored = TRUE
+ layer = ABOVE_HUD_LAYER
+ plane = ABOVE_HUD_PLANE
+
+/obj/screen/zone_sel/MouseExited(location, control, params)
+ if(!isobserver(usr) && hovering)
+ cut_overlay(hover_overlays_cache[hovering])
+ hovering = null
+
+/obj/screen/zone_sel/proc/get_zone_at(icon_x, icon_y)
switch(icon_y)
if(1 to 3) //Feet
switch(icon_x)
if(10 to 15)
- selecting = "r_foot"
+ return "r_foot"
if(17 to 22)
- selecting = "l_foot"
- else
- return 1
+ return "l_foot"
if(4 to 9) //Legs
switch(icon_x)
if(10 to 15)
- selecting = "r_leg"
+ return "r_leg"
if(17 to 22)
- selecting = "l_leg"
- else
- return 1
+ return "l_leg"
if(10 to 13) //Hands and groin
switch(icon_x)
if(8 to 11)
- selecting = "r_hand"
+ return "r_hand"
if(12 to 20)
- selecting = "groin"
+ return "groin"
if(21 to 24)
- selecting = "l_hand"
- else
- return 1
+ return "l_hand"
if(14 to 22) //Chest and arms to shoulders
switch(icon_x)
if(8 to 11)
- selecting = "r_arm"
+ return "r_arm"
if(12 to 20)
- selecting = "chest"
+ return "chest"
if(21 to 24)
- selecting = "l_arm"
- else
- return 1
+ return "l_arm"
if(23 to 30) //Head, but we need to check for eye or mouth
if(icon_x in 12 to 20)
- selecting = "head"
switch(icon_y)
if(23 to 24)
if(icon_x in 15 to 17)
- selecting = "mouth"
+ return "mouth"
if(26) //Eyeline, eyes are on 15 and 17
if(icon_x in 14 to 18)
- selecting = "eyes"
+ return "eyes"
if(25 to 27)
if(icon_x in 15 to 17)
- selecting = "eyes"
+ return "eyes"
+ return "head"
- if(old_selecting != selecting)
- update_icon()
+/obj/screen/zone_sel/proc/set_selected_zone(choice, mob/user)
+ if(isobserver(user))
+ return
+
+ if(choice != selecting)
+ selecting = choice
+ update_icon(usr)
return 1
/obj/screen/zone_sel/update_icon()
diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm
index 97dd02838d0..c1cb90919f5 100644
--- a/code/controllers/subsystem/garbage.dm
+++ b/code/controllers/subsystem/garbage.dm
@@ -59,7 +59,6 @@ SUBSYSTEM_DEF(garbage)
msg += " | Fail:[fail_counts.Join(",")]"
..(msg)
-
/datum/controller/subsystem/garbage/Shutdown()
//Adds the del() log to the qdel log file
var/list/dellog = list()
@@ -86,41 +85,21 @@ SUBSYSTEM_DEF(garbage)
/datum/controller/subsystem/garbage/fire()
//the fact that this resets its processing each fire (rather then resume where it left off) is intentional.
- var/queue = GC_QUEUE_PREQUEUE
+ var/queue = GC_QUEUE_CHECK
while(state == SS_RUNNING)
switch(queue)
- if(GC_QUEUE_PREQUEUE)
- HandlePreQueue()
- queue = GC_QUEUE_PREQUEUE + 1
if(GC_QUEUE_CHECK)
HandleQueue(GC_QUEUE_CHECK)
queue = GC_QUEUE_CHECK + 1
if(GC_QUEUE_HARDDELETE)
HandleQueue(GC_QUEUE_HARDDELETE)
+ if(state == SS_PAUSED) //make us wait again before the next run.
+ state = SS_RUNNING
break
- if(state == SS_PAUSED) //make us wait again before the next run.
- state = SS_RUNNING
-//If you see this proc high on the profile, what you are really seeing is the garbage collection/soft delete overhead in byond.
-//Don't attempt to optimize, not worth the effort.
-/datum/controller/subsystem/garbage/proc/HandlePreQueue()
- var/list/tobequeued = queues[GC_QUEUE_PREQUEUE]
- var/static/count = 0
- if(count)
- var/c = count
- count = 0 //so if we runtime on the Cut, we don't try again.
- tobequeued.Cut(1, c + 1)
- for(var/ref in tobequeued)
- count++
- Queue(ref, GC_QUEUE_PREQUEUE + 1)
- if(MC_TICK_CHECK)
- break
- if(count)
- tobequeued.Cut(1, count + 1)
- count = 0
/datum/controller/subsystem/garbage/proc/HandleQueue(level = GC_QUEUE_CHECK)
if(level == GC_QUEUE_CHECK)
@@ -142,7 +121,7 @@ SUBSYSTEM_DEF(garbage)
if(!refID)
count++
if(MC_TICK_CHECK)
- break
+ return
continue
var/GCd_at_time = queue[refID]
@@ -161,7 +140,7 @@ SUBSYSTEM_DEF(garbage)
reference_find_on_fail -= refID //It's deleted we don't care anymore.
#endif
if(MC_TICK_CHECK)
- break
+ return
continue
// Something's still referring to the qdel'd object.
@@ -184,27 +163,20 @@ SUBSYSTEM_DEF(garbage)
if(GC_QUEUE_HARDDELETE)
HardDelete(D)
if(MC_TICK_CHECK)
- break
+ return
continue
Queue(D, level + 1)
if(MC_TICK_CHECK)
- break
+ return
if(count)
queue.Cut(1, count + 1)
count = 0
-/datum/controller/subsystem/garbage/proc/PreQueue(datum/D)
- if(D.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
- queues[GC_QUEUE_PREQUEUE] += D
- D.gc_destroyed = GC_QUEUED_FOR_QUEUING
-
/datum/controller/subsystem/garbage/proc/Queue(datum/D, level = GC_QUEUE_CHECK)
if(isnull(D))
return
- if(D.gc_destroyed == GC_QUEUED_FOR_HARD_DEL)
- level = GC_QUEUE_HARDDELETE
if(level > GC_QUEUE_COUNT)
HardDelete(D)
return
@@ -250,11 +222,6 @@ SUBSYSTEM_DEF(garbage)
message_admins("Error: [type]([refID]) took longer than 1 second to delete (took [time / 10] seconds to delete).")
postpone(time)
-/datum/controller/subsystem/garbage/proc/HardQueue(datum/D)
- if(D.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
- queues[GC_QUEUE_PREQUEUE] += D
- D.gc_destroyed = GC_QUEUED_FOR_HARD_DEL
-
/datum/controller/subsystem/garbage/Recover()
if(istype(SSgarbage.queues))
for(var/i in 1 to SSgarbage.queues.len)
@@ -294,11 +261,13 @@ SUBSYSTEM_DEF(garbage)
if(isnull(D.gc_destroyed))
- D.SendSignal(COMSIG_PARENT_QDELETED)
+ if(D.SendSignal(COMSIG_PARENT_PREQDELETED, force)) // Give the components a chance to prevent their parent from being deleted
+ return
D.gc_destroyed = GC_CURRENTLY_BEING_QDELETED
var/start_time = world.time
var/start_tick = world.tick_usage
var/hint = D.Destroy(arglist(args.Copy(2))) // Let our friend know they're about to get fucked up.
+ D.SendSignal(COMSIG_PARENT_QDELETED, force, hint) // Let the (remaining) components know about the result of Destroy
if(world.time != start_time)
I.slept_destroy++
else
@@ -307,7 +276,7 @@ SUBSYSTEM_DEF(garbage)
return
switch(hint)
if(QDEL_HINT_QUEUE) //qdel should queue the object for deletion.
- SSgarbage.PreQueue(D)
+ SSgarbage.Queue(D)
if(QDEL_HINT_IWILLGC)
D.gc_destroyed = world.time
return
@@ -327,18 +296,18 @@ SUBSYSTEM_DEF(garbage)
#endif
I.no_respect_force++
- SSgarbage.PreQueue(D)
- if(QDEL_HINT_HARDDEL) //qdel should assume this object won't gc, and queue a hard delete using a hard reference to save time from the locate()
- SSgarbage.HardQueue(D)
+ SSgarbage.Queue(D)
+ if(QDEL_HINT_HARDDEL) //qdel should assume this object won't gc, and queue a hard delete
+ SSgarbage.Queue(D, GC_QUEUE_HARDDELETE)
if(QDEL_HINT_HARDDEL_NOW) //qdel should assume this object won't gc, and hard del it post haste.
SSgarbage.HardDelete(D)
if(QDEL_HINT_FINDREFERENCE)//qdel will, if TESTING is enabled, display all references to this object, then queue the object for deletion.
- SSgarbage.PreQueue(D)
+ SSgarbage.Queue(D)
#ifdef TESTING
D.find_references()
#endif
if(QDEL_HINT_IFFAIL_FINDREFERENCE)
- SSgarbage.PreQueue(D)
+ SSgarbage.Queue(D)
#ifdef TESTING
SSgarbage.reference_find_on_fail["\ref[D]"] = TRUE
#endif
@@ -348,7 +317,7 @@ SUBSYSTEM_DEF(garbage)
testing("WARNING: [D.type] is not returning a qdel hint. It is being placed in the queue. Further instances of this type will also be queued.")
#endif
I.no_hint++
- SSgarbage.PreQueue(D)
+ SSgarbage.Queue(D)
else if(D.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
CRASH("[D.type] destroy proc was called multiple times, likely due to a qdel loop in the Destroy logic")
@@ -463,4 +432,4 @@ SUBSYSTEM_DEF(garbage)
CHECK_TICK
#endif
-#endif
+#endif
\ No newline at end of file
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index 05eaae1a9d9..d0abd774e6f 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -391,6 +391,9 @@ Class Procs:
return ..()
+/obj/machinery/proc/is_operational()
+ return !(stat & (NOPOWER|BROKEN|MAINT))
+
/obj/machinery/CheckParts(list/parts_list)
..()
RefreshParts()
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index 370cef73559..2d395da0dd0 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -1,128 +1,353 @@
-//////////////////////////////////////
// SUIT STORAGE UNIT /////////////////
-//////////////////////////////////////
-
-
/obj/machinery/suit_storage_unit
- name = "Suit Storage Unit"
+ name = "suit storage unit"
desc = "An industrial U-Stor-It Storage unit designed to accomodate all kinds of space suits. Its on-board equipment also allows the user to decontaminate the contents through a UV-ray purging cycle. There's a warning label dangling from the control pad, reading \"STRICTLY NO BIOLOGICALS IN THE CONFINES OF THE UNIT\"."
- icon = 'icons/obj/suitstorage.dmi'
- icon_state = "suitstorage000000100" //order is: [has helmet][has suit][has human][is open][is locked][is UV cycling][is powered][is dirty/broken] [is superUVcycling]
- anchored = 1
- density = 1
- var/mob/living/carbon/human/OCCUPANT = null
- var/obj/item/clothing/suit/space/SUIT = null
- var/SUIT_TYPE = null
- var/obj/item/clothing/head/helmet/space/HELMET = null
- var/HELMET_TYPE = null
- var/obj/item/clothing/mask/MASK = null //All the stuff that's gonna be stored insiiiiiiiiiiiiiiiiiiide, nyoro~n
- var/MASK_TYPE = null //Erro's idea on standarising SSUs whle keeping creation of other SSU types easy: Make a child SSU, name it something then set the TYPE vars to your desired suit output. New() should take it from there by itself.
- var/isopen = 0
- var/islocked = 0
- var/isUV = 0
- var/ispowered = 1 //starts powered
- var/isbroken = 0
- var/issuperUV = 0
- var/panelopen = 0
- var/safetieson = 1
- var/cycletime_left = 0
+ icon = 'icons/obj/machines/suit_storage.dmi'
+ icon_state = "close"
+ anchored = TRUE
+ density = TRUE
+ max_integrity = 250
+ var/obj/item/clothing/suit/space/suit = null
+ var/obj/item/clothing/head/helmet/space/helmet = null
+ var/obj/item/clothing/mask/mask = null
+ var/obj/item/storage = null
+
+ var/helmet_type = null
+ var/suit_type = null
+ var/mask_type = null
+ var/storage_type = null
+
+ var/locked = FALSE
+ var/safeties = TRUE
+ var/broken = FALSE
+
+ var/uv = FALSE
+ var/uv_super = FALSE
+ var/uv_cycles = 6
+ var/message_cooldown
+ var/breakout_time = 300
+
+ //abstract these onto machinery eventually
+ var/state_open = FALSE
+ var/list/occupant_typecache //if set, turned into typecache in Initialize, other wise, defaults to mob/living typecache
+ var/atom/movable/occupant = null
-//The units themselves/////////////////
/obj/machinery/suit_storage_unit/standard_unit
- SUIT_TYPE = /obj/item/clothing/suit/space/eva
- HELMET_TYPE = /obj/item/clothing/head/helmet/space/eva
- MASK_TYPE = /obj/item/clothing/mask/breath
+ suit_type = /obj/item/clothing/suit/space/eva
+ helmet_type = /obj/item/clothing/head/helmet/space/eva
+ mask_type = /obj/item/clothing/mask/breath
/obj/machinery/suit_storage_unit/captain
- SUIT_TYPE = /obj/item/clothing/suit/space/captain
- HELMET_TYPE = /obj/item/clothing/head/helmet/space/capspace
- MASK_TYPE = /obj/item/clothing/mask/gas
+ suit_type = /obj/item/clothing/suit/space/captain
+ helmet_type = /obj/item/clothing/head/helmet/space/capspace
+ mask_type = /obj/item/clothing/mask/gas
+ storage_type = /obj/item/tank/jetpack/oxygen/captain
/obj/machinery/suit_storage_unit/engine
- SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit/engineering
- HELMET_TYPE = /obj/item/clothing/head/helmet/space/hardsuit/engineering
- MASK_TYPE = /obj/item/clothing/mask/breath
+ suit_type = /obj/item/clothing/suit/space/hardsuit/engineering
+ helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/engineering
+ mask_type = /obj/item/clothing/mask/breath
+ storage_type = /obj/item/clothing/shoes/magboots
/obj/machinery/suit_storage_unit/ce
- SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit/elite
- HELMET_TYPE = /obj/item/clothing/head/helmet/space/hardsuit/elite
- MASK_TYPE = /obj/item/clothing/mask/breath
+ suit_type = /obj/item/clothing/suit/space/hardsuit/elite
+ helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/elite
+ mask_type = /obj/item/clothing/mask/gas
+ storage_type = /obj/item/clothing/shoes/magboots/advance
/obj/machinery/suit_storage_unit/security
- SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit/security
- HELMET_TYPE = /obj/item/clothing/head/helmet/space/hardsuit/security
- MASK_TYPE = /obj/item/clothing/mask/gas/sechailer
+ suit_type = /obj/item/clothing/suit/space/hardsuit/security
+ helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/security
+ mask_type = /obj/item/clothing/mask/gas/sechailer
/obj/machinery/suit_storage_unit/atmos
- SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit/atmos
- HELMET_TYPE = /obj/item/clothing/head/helmet/space/hardsuit/atmos
- MASK_TYPE = /obj/item/clothing/mask/gas
+ suit_type = /obj/item/clothing/suit/space/hardsuit/atmos
+ helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/atmos
+ mask_type = /obj/item/clothing/mask/gas
+ storage_type = /obj/item/clothing/shoes/magboots
/obj/machinery/suit_storage_unit/mining
- SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit/mining
- HELMET_TYPE = /obj/item/clothing/head/helmet/space/hardsuit/mining
- MASK_TYPE = /obj/item/clothing/mask/breath
+ suit_type = /obj/item/clothing/suit/space/hardsuit/mining
+ helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/mining
+ mask_type = /obj/item/clothing/mask/breath
/obj/machinery/suit_storage_unit/cmo
- SUIT_TYPE = /obj/item/clothing/suit/space/hardsuit/medical
- HELMET_TYPE = /obj/item/clothing/head/helmet/space/hardsuit/medical
- MASK_TYPE = /obj/item/clothing/mask/breath
+ suit_type = /obj/item/clothing/suit/space/hardsuit/medical
+ helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/medical
+ mask_type = /obj/item/clothing/mask/breath
-/obj/machinery/suit_storage_unit/New()
- src.update_icon()
- if(SUIT_TYPE)
- SUIT = new SUIT_TYPE(src)
- if(HELMET_TYPE)
- HELMET = new HELMET_TYPE(src)
- if(MASK_TYPE)
- MASK = new MASK_TYPE(src)
+/obj/machinery/suit_storage_unit/syndicate
+ suit_type = /obj/item/clothing/suit/space/hardsuit/syndi
+ helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/syndi
+ mask_type = /obj/item/clothing/mask/gas/syndicate
+ storage_type = /obj/item/tank/jetpack/oxygen/harness
+
+/obj/machinery/suit_storage_unit/ert/command
+ suit_type = /obj/item/clothing/suit/space/hardsuit/ert/commander
+ helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/ert/commander
+ mask_type = /obj/item/clothing/mask/breath
+ storage_type = /obj/item/tank/emergency_oxygen/double
+
+/obj/machinery/suit_storage_unit/ert/security
+ suit_type = /obj/item/clothing/suit/space/hardsuit/ert/security
+ helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/ert/security
+ mask_type = /obj/item/clothing/mask/breath
+ storage_type = /obj/item/tank/emergency_oxygen/double
+
+/obj/machinery/suit_storage_unit/ert/engineer
+ suit_type = /obj/item/clothing/suit/space/hardsuit/ert/engineer
+ helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/ert/engineer
+ mask_type = /obj/item/clothing/mask/breath
+ storage_type = /obj/item/tank/emergency_oxygen/double
+
+/obj/machinery/suit_storage_unit/ert/medical
+ suit_type = /obj/item/clothing/suit/space/hardsuit/ert/medical
+ helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/ert/medical
+ mask_type = /obj/item/clothing/mask/breath
+ storage_type = /obj/item/tank/emergency_oxygen/double
+
+
+
+/obj/machinery/suit_storage_unit/Initialize()
+ . = ..()
+ if(suit_type)
+ suit = new suit_type(src)
+ if(helmet_type)
+ helmet = new helmet_type(src)
+ if(mask_type)
+ mask = new mask_type(src)
+ if(storage_type)
+ storage = new storage_type(src)
+ update_icon()
+
+ //move this into machinery eventually...
+ if(occupant_typecache)
+ occupant_typecache = typecacheof(occupant_typecache)
+
+/obj/machinery/suit_storage_unit/Destroy()
+ QDEL_NULL(suit)
+ QDEL_NULL(helmet)
+ QDEL_NULL(mask)
+ QDEL_NULL(storage)
+ return ..()
/obj/machinery/suit_storage_unit/update_icon()
- var/hashelmet = 0
- var/hassuit = 0
- var/hashuman = 0
- if(HELMET)
- hashelmet = 1
- if(SUIT)
- hassuit = 1
- if(OCCUPANT)
- hashuman = 1
- icon_state = text("suitstorage[][][][][][][][][]",hashelmet,hassuit,hashuman,src.isopen,src.islocked,src.isUV,src.ispowered,src.isbroken,src.issuperUV)
+ cut_overlays()
+ if(uv)
+ if(uv_super)
+ add_overlay("super")
+ else if(occupant)
+ add_overlay("uvhuman")
+ else
+ add_overlay("uv")
+ else if(state_open)
+ if(stat & BROKEN)
+ add_overlay("broken")
+ else
+ add_overlay("open")
+ if(suit)
+ add_overlay("suit")
+ if(helmet)
+ add_overlay("helm")
+ if(storage)
+ add_overlay("storage")
+ else if(occupant)
+ add_overlay("human")
+
+/obj/machinery/suit_storage_unit/attackby(obj/item/I as obj, mob/user as mob, params)
+ if(!is_operational())
+ return
+ if(isscrewdriver(I))
+ panel_open = !panel_open
+ playsound(loc, I.usesound, 100, 1)
+ to_chat(user, text("You [panel_open ? "open up" : "close"] the unit's maintenance panel."))
+ updateUsrDialog()
/obj/machinery/suit_storage_unit/power_change()
- if( powered() )
- src.ispowered = 1
- stat &= ~NOPOWER
- src.update_icon()
+ ..()
+ if(!is_operational() && state_open)
+ open_machine()
+ dump_contents()
+ update_icon()
+
+
+/obj/machinery/suit_storage_unit/proc/dump_contents()
+ dropContents()
+ helmet = null
+ suit = null
+ mask = null
+ storage = null
+ occupant = null
+
+/obj/machinery/suit_storage_unit/deconstruct(disassembled = TRUE)
+ open_machine()
+ dump_contents()
+ new /obj/item/stack/sheet/metal (loc, 2)
+ qdel(src)
+
+/obj/machinery/suit_storage_unit/MouseDrop_T(atom/A, mob/user)
+ if(user.stat || user.lying || !Adjacent(user) || !Adjacent(A) || !isliving(A))
+ return
+ var/mob/living/target = A
+ if(!state_open)
+ to_chat(user, "The [src]'s doors are shut!")
+ return
+ if(!is_operational())
+ to_chat(user, "The [src] is not operational!")
+ return
+ if(occupant || helmet || suit || storage)
+ to_chat(user, "It's too cluttered inside to fit in!")
+ return
+
+ if(target == user)
+ user.visible_message("[user] starts squeezing into [src]!", "You start working your way into [src]...")
else
- spawn(rand(0, 15))
- src.ispowered = 0
- stat |= NOPOWER
- src.islocked = 0
- src.isopen = 1
- src.dump_everything()
- src.update_icon()
+ target.visible_message("[user] starts shoving [target] into [src]!", "[user] starts shoving you into [src]!")
-
-/obj/machinery/suit_storage_unit/ex_act(severity)
- switch(severity)
- if(1.0)
- if(prob(50))
- src.dump_everything() //So suits dont survive all the time
- qdel(src)
- return
- if(2.0)
- if(prob(50))
- src.dump_everything()
- qdel(src)
+ if(do_mob(user, target, 30))
+ if(occupant || helmet || suit || storage)
return
+ if(target == user)
+ user.visible_message("[user] slips into [src] and closes the door behind [user.p_them()]!", "You slip into [src]'s cramped space and shut its door.")
else
- return
- return
+ target.visible_message("[user] pushes [target] into [src] and shuts its door!", "[user] shoves you into [src] and shuts the door!")
+ close_machine(target)
+ add_fingerprint(user)
+/obj/machinery/suit_storage_unit/proc/cook()
+ if(uv_cycles)
+ uv_cycles--
+ uv = TRUE
+ locked = TRUE
+ update_icon()
+ if(occupant)
+ var/mob/living/mob_occupant = occupant
+ if(uv_super)
+ mob_occupant.adjustFireLoss(rand(20, 36))
+ else
+ mob_occupant.adjustFireLoss(rand(10, 16))
+ mob_occupant.emote("scream")
+ addtimer(CALLBACK(src, .proc/cook), 50)
+ else
+ uv_cycles = initial(uv_cycles)
+ uv = FALSE
+ locked = FALSE
+ if(uv_super)
+ visible_message("[src]'s door creaks open with a loud whining noise. A cloud of foul black smoke escapes from its chamber.")
+ playsound(src, 'sound/machines/airlock_alien_prying.ogg', 50, 1)
+ helmet = null
+ qdel(helmet)
+ suit = null
+ qdel(suit) // Delete everything but the occupant.
+ mask = null
+ qdel(mask)
+ storage = null
+ qdel(storage)
+ else
+ if(!occupant)
+ visible_message("[src]'s door slides open. The glowing yellow lights dim to a gentle green.")
+ else
+ visible_message("[src]'s door slides open, barraging you with the nauseating smell of charred flesh.")
+ playsound(src, 'sound/machines/airlock_close.ogg', 25, 1)
+ open_machine(FALSE)
+ if(occupant)
+ dump_contents()
+
+/obj/machinery/suit_storage_unit/shock(mob/user, prb)
+ if(!prob(prb))
+ var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
+ s.set_up(5, 1, src)
+ s.start()
+ if(electrocute_mob(user, src, src, 1, TRUE))
+ return 1
+
+/obj/machinery/suit_storage_unit/relaymove(mob/user)
+ if(locked)
+ if(message_cooldown <= world.time)
+ message_cooldown = world.time + 50
+ to_chat(user, "[src]'s door won't budge!")
+ return
+ open_machine()
+ dump_contents()
+
+/obj/machinery/suit_storage_unit/container_resist(mob/living/user)
+ if(!locked)
+ open_machine()
+ dump_contents()
+ return
+ user.changeNext_move(CLICK_CD_BREAKOUT)
+ user.last_special = world.time + CLICK_CD_BREAKOUT
+ user.visible_message("You see [user] kicking against the doors of [src]!", \
+ "You start kicking against the doors... (this will take about [DisplayTimeText(breakout_time)].)", \
+ "You hear a thump from [src].")
+ if(do_after(user,(breakout_time), target = src))
+ if(!user || user.stat != CONSCIOUS || user.loc != src )
+ return
+ user.visible_message("[user] successfully broke out of [src]!", \
+ "You successfully break out of [src]!")
+ open_machine()
+ dump_contents()
+
+ add_fingerprint(user)
+ if(locked)
+ visible_message("You see [user] kicking against the doors of [src]!", \
+ "You start kicking against the doors...")
+ addtimer(CALLBACK(src, .proc/resist_open, user), 300)
+ else
+ open_machine()
+ dump_contents()
+
+/obj/machinery/suit_storage_unit/proc/resist_open(mob/user)
+ if(!state_open && occupant && (user in src) && !user.stat) // Check they're still here.
+ visible_message("You see [user] burst out of [src]!", \
+ "You escape the cramped confines of [src]!")
+ open_machine()
+
+//eventually move these onto the parent....
+
+/obj/machinery/suit_storage_unit/proc/open_machine(drop = TRUE)
+ state_open = TRUE
+ if(drop)
+ dropContents()
+ update_icon()
+ updateUsrDialog()
+
+/obj/machinery/suit_storage_unit/dropContents()
+ var/turf/T = get_turf(src)
+ for(var/atom/movable/A in contents)
+ A.forceMove(T)
+ if(isliving(A))
+ var/mob/living/L = A
+ L.update_canmove()
+ occupant = null
+
+/obj/machinery/suit_storage_unit/proc/close_machine(atom/movable/target = null)
+ state_open = FALSE
+ if(!target)
+ for(var/am in loc)
+ if(!(occupant_typecache ? is_type_in_typecache(am, occupant_typecache) : isliving(am)))
+ continue
+ var/atom/movable/AM = am
+ if(AM.has_buckled_mobs())
+ continue
+ if(isliving(AM))
+ var/mob/living/L = am
+ if(L.buckled || L.mob_size >= MOB_SIZE_LARGE)
+ continue
+ target = am
+
+ var/mob/living/mobtarget = target
+ if(target && !target.has_buckled_mobs() && (!isliving(target) || !mobtarget.buckled))
+ occupant = target
+ target.forceMove(src)
+ updateUsrDialog()
+ update_icon()
+
+
+////////
/obj/machinery/suit_storage_unit/attack_hand(mob/user as mob)
var/dat
@@ -131,54 +356,49 @@
if(stat & NOPOWER)
return
if(!user.IsAdvancedToolUser())
- return 0
- if(src.panelopen) //The maintenance panel is open. Time for some shady stuff
+ return FALSE
+ if(panel_open) //The maintenance panel is open. Time for some shady stuff
dat+= "Suit storage unit: Maintenance panel"
dat+= "Maintenance panel controls
"
dat+= "The panel is ridden with controls, button and meters, labeled in strange signs and symbols that
you cannot understand. Probably the manufactoring world's language.
Among other things, a few controls catch your eye.
"
- dat+= text("A small dial with a \"�\" symbol embroidded on it. It's pointing towards a gauge that reads [].
Turn towards []
",(src.issuperUV ? "15nm" : "185nm"),(src.issuperUV ? "185nm" : "15nm") )
- dat+= text("A thick old-style button, with 2 grimy LED lights next to it. The [] LED is on.
Press button",(src.safetieson? "GREEN" : "RED"))
+ dat+= text("A small dial with a arrow embroidered on it. It's pointing towards a gauge that reads [].
Turn towards []
",(uv_super ? "15nm" : "185nm"),(uv_super ? "185nm" : "15nm") )
+ dat+= text("A thick old-style button, with 2 grimy LED lights next to it. The [] LED is on.
Press button",(safeties ? "GREEN" : "RED"))
dat+= "
Close panel"
- //user << browse(dat, "window=ssu_m_panel;size=400x500")
- //onclose(user, "ssu_m_panel")
- else if(src.isUV) //The thing is running its cauterisation cycle. You have to wait.
+ else if(uv) //The thing is running its cauterisation cycle. You have to wait.
dat += "Suit storage unit"
dat+= "Unit is cauterising contents with selected UV ray intensity. Please wait.
"
- //dat+= "Cycle end in: [src.cycletimeleft()] seconds. "
- //user << browse(dat, "window=ssu_cycling_panel;size=400x500")
- //onclose(user, "ssu_cycling_panel")
else
- if(!src.isbroken)
+ if(!broken)
dat+= "Welcome to the Unit control panel.
"
- dat+= text("Helmet storage compartment: []
",(src.HELMET ? HELMET.name : "No helmet detected.") )
- if(HELMET && src.isopen)
+ dat+= text("Helmet storage compartment: []
",(helmet ? helmet.name : "No helmet detected.") )
+ if(helmet && state_open)
dat+="Dispense helmet
"
- dat+= text("Suit storage compartment: []
",(src.SUIT ? SUIT.name : "No exosuit detected.") )
- if(SUIT && src.isopen)
+ dat+= text("Suit storage compartment: []
",(suit ? suit.name : "No exosuit detected.") )
+ if(suit && state_open)
dat+="Dispense suit
"
- dat+= text("Breathmask storage compartment: []
",(src.MASK ? MASK.name : "No breathmask detected.") )
- if(MASK && src.isopen)
+ dat+= text("Breathmask storage compartment: []
",(mask ? mask.name : "No breathmask detected.") )
+ if(mask && state_open)
dat+="Dispense mask
"
- if(src.OCCUPANT)
+ dat+= text("Breathmask storage compartment: []
",(storage ? storage.name : "No storage item detected.") )
+ if(storage && state_open)
+ dat+="Dispense storage item
"
+ if(occupant)
dat+= "
WARNING: Biological entity detected inside the Unit's storage. Please remove.
"
dat+= "Eject extra load"
- dat+= text("
Unit is: [] - [] Unit ",(src.isopen ? "Open" : "Closed"),(src.isopen ? "Close" : "Open"))
- if(src.isopen)
+ dat+= text("
Unit is: [] - [] Unit ",(state_open ? "Open" : "Closed"),(state_open ? "Close" : "Open"))
+ if(state_open)
dat+="
"
else
- dat+= text(" - *[] Unit*
",(src.islocked ? "Unlock" : "Lock") )
- dat+= text("Unit status: []",(src.islocked? "**LOCKED**
" : "**UNLOCKED**
") )
- dat+= "Start Disinfection cycle
"
+ dat+= text(" - *[] Unit*
",(locked ? "Unlock" : "Lock") )
+ dat+= text("Unit status: []",(locked? "**LOCKED**
" : "**UNLOCKED**
") )
+ dat+= "Start Disinfection cycle
"
dat += "
Close control panel"
- //user << browse(dat, "window=Suit Storage Unit;size=400x500")
- //onclose(user, "Suit Storage Unit")
else //Ohhhh shit it's dirty or broken! Let's inform the guy.
dat+= "Suit storage unit"
dat+= "Unit chamber is too contaminated to continue usage. Please call for a qualified individual to perform maintenance.
"
dat+= "
Close control panel"
- //user << browse(dat, "window=suit_storage_unit;size=400x500")
- //onclose(user, "suit_storage_unit")
+
var/datum/browser/popup = new(user, "suit_storage_unit", name, 400, 500)
popup.set_content(dat)
@@ -187,263 +407,134 @@
return
-/obj/machinery/suit_storage_unit/Topic(href, href_list) //I fucking HATE this proc
+/obj/machinery/suit_storage_unit/Topic(href, href_list)
if(..())
return 1
if((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon/ai)))
usr.set_machine(src)
if(href_list["toggleUV"])
- src.toggleUV(usr)
- src.updateUsrDialog()
- src.update_icon()
+ toggleUV(usr)
+ updateUsrDialog()
+ update_icon()
if(href_list["togglesafeties"])
- src.togglesafeties(usr)
- src.updateUsrDialog()
- src.update_icon()
+ togglesafeties(usr)
+ updateUsrDialog()
+ update_icon()
if(href_list["dispense_helmet"])
- src.dispense_helmet(usr)
- src.updateUsrDialog()
- src.update_icon()
+ dispense_helmet(usr)
+ updateUsrDialog()
+ update_icon()
if(href_list["dispense_suit"])
- src.dispense_suit(usr)
- src.updateUsrDialog()
- src.update_icon()
+ dispense_suit(usr)
+ updateUsrDialog()
+ update_icon()
if(href_list["dispense_mask"])
- src.dispense_mask(usr)
- src.updateUsrDialog()
- src.update_icon()
+ dispense_mask(usr)
+ updateUsrDialog()
+ update_icon()
+ if(href_list["dispense_storage"])
+ dispense_storage(usr)
+ updateUsrDialog()
+ update_icon()
if(href_list["toggle_open"])
- src.toggle_open(usr)
- src.updateUsrDialog()
- src.update_icon()
+ toggle_open(usr)
+ updateUsrDialog()
+ update_icon()
if(href_list["toggle_lock"])
- src.toggle_lock(usr)
- src.updateUsrDialog()
- src.update_icon()
- if(href_list["start_UV"])
- src.start_UV(usr)
- src.updateUsrDialog()
- src.update_icon()
+ toggle_lock(usr)
+ updateUsrDialog()
+ update_icon()
+ if(href_list["cook"])
+ cook(usr)
+ updateUsrDialog()
+ update_icon()
if(href_list["eject_guy"])
- src.eject_occupant(usr)
- src.updateUsrDialog()
- src.update_icon()
- /*if(href_list["refresh"])
- src.updateUsrDialog()*/
- src.add_fingerprint(usr)
+ eject_occupant(usr)
+ updateUsrDialog()
+ update_icon()
+ add_fingerprint(usr)
return
/obj/machinery/suit_storage_unit/proc/toggleUV(mob/user as mob)
-// var/protected = 0
-// var/mob/living/carbon/human/H = user
- if(!src.panelopen)
+
+ if(!panel_open)
return
-
- /*if(istype(H)) //Let's check if the guy's wearing electrically insulated gloves
- if(H.gloves)
- var/obj/item/clothing/gloves/G = H.gloves
- if(istype(G,/obj/item/clothing/gloves/color/yellow))
- protected = 1
-
- if(!protected)
- playsound(src.loc, "sparks", 75, 1, -1)
- to_chat(user, "You try to touch the controls but you get zapped. There must be a short circuit somewhere.")
- return*/
- else //welp, the guy is protected, we can continue
- if(src.issuperUV)
- to_chat(user, "You slide the dial back towards \"185nm\".")
- src.issuperUV = 0
+ else
+ if(uv_super)
+ to_chat(user, "You slide the dial back towards \"185nm\".")
+ uv_super = FALSE
else
- to_chat(user, "You crank the dial all the way up to \"15nm\".")
- src.issuperUV = 1
- return
-
+ to_chat(user, "You crank the dial all the way up to \"15nm\".")
+ uv_super = TRUE
/obj/machinery/suit_storage_unit/proc/togglesafeties(mob/user as mob)
-// var/protected = 0
-// var/mob/living/carbon/human/H = user
- if(!src.panelopen) //Needed check due to bugs
+ if(!panel_open)
return
-
- /*if(istype(H)) //Let's check if the guy's wearing electrically insulated gloves
- if(H.gloves)
- var/obj/item/clothing/gloves/G = H.gloves
- if(istype(G,/obj/item/clothing/gloves/color/yellow) )
- protected = 1
-
- if(!protected)
- playsound(src.loc, "sparks", 75, 1, -1)
- to_chat(user, "You try to touch the controls but you get zapped. There must be a short circuit somewhere.")
- return*/
else
- to_chat(user, "You push the button. The coloured LED next to it changes.")
- src.safetieson = !src.safetieson
-
+ to_chat(user, "You push the button. The coloured LED next to it changes.")
+ safeties = !safeties
/obj/machinery/suit_storage_unit/proc/dispense_helmet(mob/user as mob)
- if(!src.HELMET)
- return //Do I even need this sanity check? Nyoro~n
- else
- src.HELMET.loc = src.loc
- src.HELMET = null
+ if(!helmet)
return
-
+ else
+ helmet.forceMove(loc)
+ helmet = null
/obj/machinery/suit_storage_unit/proc/dispense_suit(mob/user as mob)
- if(!src.SUIT)
+ if(!suit)
return
else
- src.SUIT.loc = src.loc
- src.SUIT = null
- return
-
+ suit.forceMove(loc)
+ suit = null
/obj/machinery/suit_storage_unit/proc/dispense_mask(mob/user as mob)
- if(!src.MASK)
+ if(!mask)
return
else
- src.MASK.loc = src.loc
- src.MASK = null
+ mask.forceMove(loc)
+ mask = null
+
+/obj/machinery/suit_storage_unit/proc/dispense_storage(mob/user as mob)
+ if(!storage)
return
-
-
-/obj/machinery/suit_storage_unit/proc/dump_everything()
- src.islocked = 0 //locks go free
- if(src.SUIT)
- src.SUIT.loc = src.loc
- src.SUIT = null
- if(src.HELMET)
- src.HELMET.loc = src.loc
- src.HELMET = null
- if(src.MASK)
- src.MASK.loc = src.loc
- src.MASK = null
- if(src.OCCUPANT)
- src.eject_occupant(OCCUPANT)
- return
-
+ else
+ storage.forceMove(loc)
+ storage = null
/obj/machinery/suit_storage_unit/proc/toggle_open(mob/user as mob)
- if(src.islocked || src.isUV)
- to_chat(user, "Unable to open unit.")
+ if(locked || uv)
+ to_chat(user, "Unable to open unit.")
return
- if(src.OCCUPANT)
- src.eject_occupant(user)
- return // eject_occupant opens the door, so we need to return
- src.isopen = !src.isopen
- return
-
+ if(occupant)
+ eject_occupant(user)
+ return
+ state_open = !state_open
/obj/machinery/suit_storage_unit/proc/toggle_lock(mob/user as mob)
- if(src.OCCUPANT && src.safetieson)
- to_chat(user, "The Unit's safety protocols disallow locking when a biological form is detected inside its compartments.")
+ if(occupant && safeties)
+ to_chat(user, "The unit's safety protocols disallow locking when a biological form is detected inside its compartments.")
return
- if(src.isopen)
+ if(state_open)
return
- src.islocked = !src.islocked
- return
-
-
-/obj/machinery/suit_storage_unit/proc/start_UV(mob/user as mob)
- if(src.isUV || src.isopen) //I'm bored of all these sanity checks
- return
- if(src.OCCUPANT && src.safetieson)
- to_chat(user, "WARNING: Biological entity detected in the confines of the Unit's storage. Cannot initiate cycle.")
- return
- if(!src.HELMET && !src.MASK && !src.SUIT && !src.OCCUPANT ) //shit's empty yo
- to_chat(user, "Unit storage bays empty. Nothing to disinfect -- Aborting.")
- return
- to_chat(user, "You start the Unit's cauterisation cycle.")
- src.cycletime_left = 20
- src.isUV = 1
- if(src.OCCUPANT && !src.islocked)
- src.islocked = 1 //Let's lock it for good measure
- src.update_icon()
- src.updateUsrDialog()
-
- var/i //our counter
- for(i=0,i<4,i++)
- sleep(50)
- if(src.OCCUPANT)
- if(src.issuperUV)
- var/burndamage = rand(35,45)
- OCCUPANT.take_organ_damage(0,burndamage)
- OCCUPANT.emote("scream")
- else
- var/burndamage = rand(10,15)
- OCCUPANT.take_organ_damage(0,burndamage)
- OCCUPANT.emote("scream")
- if(i==3) //End of the cycle
- if(!src.issuperUV)
- if(src.HELMET)
- HELMET.clean_blood()
- if(src.SUIT)
- SUIT.clean_blood()
- if(src.MASK)
- MASK.clean_blood()
- else //It was supercycling, destroy everything
- if(src.HELMET)
- src.HELMET = null
- if(src.SUIT)
- src.SUIT = null
- if(src.MASK)
- src.MASK = null
- visible_message("With a loud whining noise, the Suit Storage Unit's door grinds open. Puffs of ashen smoke come out of its chamber.")
- src.isbroken = 1
- src.isopen = 1
- src.islocked = 0
- src.eject_occupant(OCCUPANT) //Mixing up these two lines causes bug. DO NOT DO IT.
- src.isUV = 0 //Cycle ends
- src.update_icon()
- src.updateUsrDialog()
- return
-
-/* spawn(200) //Let's clean dat shit after 20 secs //Eh, this doesn't work
- if(src.HELMET)
- HELMET.clean_blood()
- if(src.SUIT)
- SUIT.clean_blood()
- if(src.MASK)
- MASK.clean_blood()
- src.isUV = 0 //Cycle ends
- src.update_icon()
- src.updateUsrDialog()
-
- var/i
- for(i=0,i<4,i++) //Gradually give the guy inside some damaged based on the intensity
- spawn(50)
- if(OCCUPANT)
- if(issuperUV)
- OCCUPANT.take_organ_damage(0,40)
- to_chat(user, "Test. You gave [OCCUPANT.p_them()] 40 damage")
- else
- OCCUPANT.take_organ_damage(0,8)
- to_chat(user, "Test. You gave [OCCUPANT.p_them()] 8 damage")
- return*/
-
-
-/obj/machinery/suit_storage_unit/proc/cycletimeleft()
- if(src.cycletime_left >= 1)
- src.cycletime_left--
- return src.cycletime_left
-
+ locked = !locked
/obj/machinery/suit_storage_unit/proc/eject_occupant(mob/user as mob)
- if(islocked)
+ if(locked)
return
- if(!OCCUPANT)
+ if(!occupant)
return
- if(user != OCCUPANT)
- to_chat(OCCUPANT, "The machine kicks you out!")
+ if(user != occupant)
+ to_chat(occupant, "The machine kicks you out!")
if(user.loc != loc)
- to_chat(OCCUPANT, "You leave the not-so-cozy confines of the SSU.")
- OCCUPANT.forceMove(loc)
- OCCUPANT = null
- if(!isopen)
- isopen = 1
+ to_chat(occupant, "You leave the not-so-cozy confines of the SSU.")
+ occupant.forceMove(loc)
+ occupant = null
+ if(!state_open)
+ state_open = 1
update_icon()
return
@@ -455,13 +546,12 @@
if(usr.stat != 0)
return
- src.eject_occupant(usr)
+ eject_occupant(usr)
add_fingerprint(usr)
- src.updateUsrDialog()
- src.update_icon()
+ updateUsrDialog()
+ update_icon()
return
-
/obj/machinery/suit_storage_unit/verb/move_inside()
set name = "Hide in Suit Storage Unit"
set category = "Object"
@@ -469,640 +559,28 @@
if(usr.stat != 0)
return
- if(!src.isopen)
- to_chat(usr, "The unit's doors are shut.")
+ if(!state_open)
+ to_chat(usr, "The unit's doors are shut.")
return
- if(!src.ispowered || src.isbroken)
- to_chat(usr, "The unit is not operational.")
+ if(broken)
+ to_chat(usr, "The unit is not operational.")
return
- if( (src.OCCUPANT) || (src.HELMET) || (src.SUIT) )
- to_chat(usr, "It's too cluttered inside for you to fit in!")
+ if((occupant) || (helmet) || (suit) || (storage))
+ to_chat(usr, "It's too cluttered inside for you to fit in!")
return
visible_message("[usr] starts squeezing into the suit storage unit!")
if(do_after(usr, 10, target = usr))
usr.stop_pulling()
usr.forceMove(src)
-// usr.metabslow = 1
- src.OCCUPANT = usr
- src.isopen = 0 //Close the thing after the guy gets inside
- src.update_icon()
+ occupant = usr
+ state_open = FALSE //Close the thing after the guy gets inside
+ update_icon()
-// for(var/obj/O in src)
-// qdel(O)
-
- src.add_fingerprint(usr)
- src.updateUsrDialog()
+ add_fingerprint(usr)
+ updateUsrDialog()
return
else
- src.OCCUPANT = null //Testing this as a backup sanity test
- return
-
-
-/obj/machinery/suit_storage_unit/attackby(obj/item/I as obj, mob/user as mob, params)
- if(!src.ispowered)
- return
- if(istype(I, /obj/item/screwdriver))
- src.panelopen = !src.panelopen
- playsound(src.loc, I.usesound, 100, 1)
- to_chat(user, text("You [] the unit's maintenance panel.",(src.panelopen ? "open up" : "close") ))
- src.updateUsrDialog()
- return
- if( istype(I, /obj/item/grab) )
- var/obj/item/grab/G = I
- if( !(ismob(G.affecting)) )
- return
- if(!src.isopen)
- to_chat(usr, "The unit's doors are shut.")
- return
- if(!src.ispowered || src.isbroken)
- to_chat(usr, "The unit is not operational.")
- return
- if( (src.OCCUPANT) || (src.HELMET) || (src.SUIT) ) //Unit needs to be absolutely empty
- to_chat(user, "The unit's storage area is too cluttered.")
- return
- visible_message("[user] starts putting [G.affecting.name] into the Suit Storage Unit.")
- if(do_after(user, 20, target = G:affecting))
- if(!G || !G.affecting) return //derpcheck
- var/mob/M = G.affecting
- M.forceMove(src)
- src.OCCUPANT = M
- src.isopen = 0 //close ittt
-
- //for(var/obj/O in src)
- // O.loc = src.loc
- src.add_fingerprint(user)
- qdel(G)
- src.updateUsrDialog()
- src.update_icon()
- return
- return
- if( istype(I,/obj/item/clothing/suit/space) )
- if(!src.isopen)
- return
- var/obj/item/clothing/suit/space/S = I
- if(src.SUIT)
- to_chat(user, "The unit already contains a suit.")
- return
- to_chat(user, "You load the [S.name] into the storage compartment.")
- user.drop_item()
- S.loc = src
- src.SUIT = S
- src.update_icon()
- src.updateUsrDialog()
- return
- if( istype(I,/obj/item/clothing/head/helmet) )
- if(!src.isopen)
- return
- var/obj/item/clothing/head/helmet/H = I
- if(src.HELMET)
- to_chat(user, "The unit already contains a helmet.")
- return
- to_chat(user, "You load the [H.name] into the storage compartment.")
- user.drop_item()
- H.loc = src
- src.HELMET = H
- src.update_icon()
- src.updateUsrDialog()
- return
- if( istype(I,/obj/item/clothing/mask) )
- if(!src.isopen)
- return
- var/obj/item/clothing/mask/M = I
- if(src.MASK)
- to_chat(user, "The unit already contains a mask.")
- return
- to_chat(user, "You load the [M.name] into the storage compartment.")
- user.drop_item()
- M.loc = src
- src.MASK = M
- src.update_icon()
- src.updateUsrDialog()
- return
- src.update_icon()
- src.updateUsrDialog()
- return
-
+ occupant = null
/obj/machinery/suit_storage_unit/attack_ai(mob/user as mob)
- return src.attack_hand(user)
-
-
-
-//////////////////////////////REMINDER: Make it lock once you place some fucker inside.
-
-//God this entire file is fucking awful
-//Suit painter for Bay's special snowflake aliums.
-
-/obj/machinery/suit_cycler
-
- name = "suit cycler"
- desc = "An industrial machine for repairing, painting and equipping hardsuits."
- anchored = 1
- density = 1
-
- icon = 'icons/obj/suitstorage.dmi'
- icon_state = "suitstorage000000100"
-
- req_access = list(access_captain,access_heads)
-
- var/active = 0 // PLEASE HOLD.
- var/safeties = 1 // The cycler won't start with a living thing inside it unless safeties are off.
- var/irradiating = 0 // If this is > 0, the cycler is decontaminating whatever is inside it.
- var/radiation_level = 2 // 1 is removing germs, 2 is removing blood, 3 is removing plasma.
- var/model_text = "" // Some flavour text for the topic box.
- var/locked = 1 // If locked, nothing can be taken from or added to the cycler.
-
- // Wiring bollocks.
- var/wires = 15
- var/electrified = 0
- var/const/WIRE_EXTEND = 1 // Safeties
- var/const/WIRE_SCANID = 2 // Locked status
- var/const/WIRE_SHOCK = 3 // What it says on the tin.
-
- //Departments that the cycler can paint suits to look like.
- var/list/departments = list("Engineering","Mining","Medical","Security","Atmos")
- //Species that the suits can be configured to fit.
- var/list/species = list("Human","Skrell","Unathi","Tajaran")
-
- var/target_department = "Engineering"
- var/target_species = "Human"
-
- var/mob/living/carbon/human/occupant = null
- var/obj/item/clothing/suit/space/hardsuit/suit = null
- var/obj/item/clothing/head/helmet/space/helmet = null
-
-/obj/machinery/suit_cycler/engineering
- name = "Engineering suit cycler"
- model_text = "Engineering"
- req_access = list(access_construction)
- departments = list("Engineering","Atmos")
- species = list("Human","Unathi","Tajaran")
-
-/obj/machinery/suit_cycler/mining
- name = "Mining suit cycler"
- model_text = "Mining"
- req_access = list(access_mining)
- departments = list("Mining")
- species = list("Human","Unathi","Tajaran")
-
-/obj/machinery/suit_cycler/attack_ai(mob/user as mob)
- return src.attack_hand(user)
-
-/obj/machinery/suit_cycler/attackby(obj/item/I as obj, mob/user as mob, params)
-
- if(electrified != 0)
- if(src.shock(user, 100))
- return
-
- //Hacking init.
- if(istype(I, /obj/item/multitool) || istype(I, /obj/item/wirecutters))
- if(panel_open)
- attack_hand(user)
- return
- //Other interface stuff.
- if(istype(I, /obj/item/grab))
- var/obj/item/grab/G = I
-
- if(!(ismob(G.affecting)))
- return
-
- if(locked)
- to_chat(user, "The suit cycler is locked.")
- return
-
- if(src.contents.len > 0)
- to_chat(user, "There is no room inside the cycler for [G.affecting.name].")
- return
-
- visible_message("[user] starts putting [G.affecting.name] into the suit cycler.")
-
- if(do_after(user, 20, target = G:affecting))
- if(!G || !G.affecting) return
- var/mob/M = G.affecting
- M.forceMove(src)
- src.occupant = M
-
- src.add_fingerprint(user)
- qdel(G)
-
- src.updateUsrDialog()
-
- return
- else if(istype(I,/obj/item/screwdriver))
-
- panel_open = !panel_open
- to_chat(user, "You [panel_open ? "open" : "close"] the maintenance panel.")
- src.updateUsrDialog()
- return
-
- else if(istype(I,/obj/item/clothing/head/helmet/space))
-
- if(locked)
- to_chat(user, "The suit cycler is locked.")
- return
-
- if(helmet)
- to_chat(user, "The cycler already contains a helmet.")
- return
-
- to_chat(user, "You fit \the [I] into the suit cycler.")
- user.drop_item()
- I.loc = src
- helmet = I
-
- src.update_icon()
- src.updateUsrDialog()
- return
-
- else if(istype(I,/obj/item/clothing/suit/space/hardsuit))
-
- if(locked)
- to_chat(user, "The suit cycler is locked.")
- return
-
- if(suit)
- to_chat(user, "The cycler already contains a hardsuit.")
- return
-
- var/obj/item/clothing/suit/space/hardsuit/S = I
-
- if(S.helmet)
- to_chat(user, "\The [S] will not fit into the cycler with a helmet attached.")
- return
-
- if(S.boots)
- to_chat(user, "\The [S] will not fit into the cycler with boots attached.")
- return
-
- to_chat(user, "You fit \the [I] into the suit cycler.")
- user.drop_item()
- I.loc = src
- suit = I
-
- src.update_icon()
- src.updateUsrDialog()
- return
-
- ..()
-
-/obj/machinery/suit_cycler/emag_act(user as mob)
- if(emagged)
- to_chat(user, "The cycler has already been subverted.")
- return
-
- //Clear the access reqs, disable the safeties, and open up all paintjobs.
- to_chat(user, "You run the sequencer across the interface, corrupting the operating protocols.")
- departments = list("Engineering","Mining","Medical","Security","Atmos","^%###^%$")
- emagged = 1
- safeties = 0
- req_access = list()
- return
-
-/obj/machinery/suit_cycler/attack_hand(mob/user as mob)
-
- add_fingerprint(user)
-
- if(..() || stat & (BROKEN|NOPOWER))
- return
-
- if(!user.IsAdvancedToolUser())
- return 0
-
- if(electrified != 0)
- if(src.shock(user, 100))
- return
-
- usr.set_machine(src)
-
- var/dat = "Suit Cycler Interface"
-
- if(src.active)
- dat+= "
The [model_text ? "[model_text] " : ""]suit cycler is currently in use. Please wait..."
-
- else if(locked)
- dat += "
The [model_text ? "[model_text] " : ""]suit cycler is currently locked. Please contact your system administrator."
- if(src.allowed(usr))
- dat += "
\[unlock unit\]"
- else
- dat += "Suit cycler
"
- dat += "Welcome to the [model_text ? "[model_text] " : ""]suit cycler control panel. \[lock unit\]
"
-
- dat += "Maintenance
"
- dat += "Helmet: [helmet ? "\the [helmet]" : "no helmet stored" ]. \[eject\]
"
- dat += "Suit: [suit ? "\the [suit]" : "no suit stored" ]. \[eject\]"
-
- if(suit && istype(suit))
- dat += "[(suit.damage ? " \[repair\]" : "")]"
-
- dat += "
UV decontamination systems: SYSTEM ERROR" : "green'>READY"]
"
- dat += "Output level: [radiation_level]
"
- dat += "\[select power level\] \[begin decontamination cycle\]
"
-
- dat += "Customisation
"
- dat += "Target product: [target_department], [target_species]."
- dat += "
\[apply customisation routine\]
"
-
-/* if(panel_open)
- var/list/vendwires = list(
- "Violet" = 1,
- "Orange" = 2,
- "Goldenrod" = 3,
- )
- dat += "Access Panel
"
- for(var/wiredesc in vendwires)
- var/is_uncut = src.wires & APCWireColorToFlag[vendwires[wiredesc]]
- dat += "[wiredesc] wire: "
- if(!is_uncut)
- dat += "Mend"
- else
- dat += "Cut "
- dat += "Pulse "
- dat += "
"
-
- dat += "
"
- dat += "The orange light is [(electrified == 0) ? "off" : "on"].
"
- dat += "The red light is [safeties ? "blinking" : "off"].
"
- dat += "The yellow light is [locked ? "on" : "off"].
" */
-
- var/datum/browser/popup = new(user, "suit_cycler", name, 400, 400)
- popup.set_content(dat)
- popup.open(0)
- onclose(user, "suit_cycler")
- return
-
-/obj/machinery/suit_cycler/Topic(href, href_list)
- if(href_list["eject_suit"])
- if(!suit) return
- suit.loc = get_turf(src)
- suit = null
- else if(href_list["eject_helmet"])
- if(!helmet) return
- helmet.loc = get_turf(src)
- helmet = null
- else if(href_list["select_department"])
- var/choice = input("Please select the target department paintjob.","Suit cycler",null) as null|anything in departments
- if(choice) target_department = choice
- else if(href_list["select_species"])
- var/choice = input("Please select the target species configuration.","Suit cycler",null) as null|anything in species
- if(choice) target_species = choice
- else if(href_list["select_rad_level"])
- var/choices = list(1,2,3)
- if(emagged)
- choices = list(1,2,3,4,5)
- radiation_level = input("Please select the desired radiation level.","Suit cycler",null) as null|anything in choices
- else if(href_list["repair_suit"])
-
- if(!suit) return
- active = 1
- spawn(100)
- repair_suit()
- finished_job()
-
- else if(href_list["apply_paintjob"])
-
- if(!suit && !helmet) return
- active = 1
- spawn(100)
- apply_paintjob()
- finished_job()
-
- else if(href_list["toggle_safties"])
- safeties = !safeties
-
- else if(href_list["toggle_lock"])
-
- if(src.allowed(usr))
- locked = !locked
- to_chat(usr, "You [locked ? "" : "un"]lock \the [src].")
- else
- to_chat(usr, "Access denied.")
-
- else if(href_list["begin_decontamination"])
-
- if(safeties && occupant)
- to_chat(usr, "The cycler has detected an occupant. Please remove the occupant before commencing the decontamination cycle.")
- return
-
- active = 1
- irradiating = 10
- src.updateUsrDialog()
-
- sleep(10)
-
- if(helmet)
- if(radiation_level > 1)
- helmet.clean_blood()
-
- if(suit)
- if(radiation_level > 1)
- suit.clean_blood()
-
-/* else if((href_list["cutwire"]) && (src.panel_open))
- var/twire = text2num(href_list["cutwire"])
- if(!( istype(usr.get_active_hand(), /obj/item/wirecutters) ))
- to_chat(usr, "You need wirecutters!")
- return
- if(src.isWireColorCut(twire))
- src.mend(twire)
- else
- src.cut(twire)
-
- else if((href_list["pulsewire"]) && (src.panel_open))
- var/twire = text2num(href_list["pulsewire"])
- if(!istype(usr.get_active_hand(), /obj/item/multitool))
- to_chat(usr, "You need a multitool!")
- return
- if(src.isWireColorCut(twire))
- to_chat(usr, "You can't pulse a cut wire.")
- return
- else
- src.pulse(twire)*/
-
- src.updateUsrDialog()
- return
-
-/obj/machinery/suit_cycler/process()
-
- if(electrified > 0)
- electrified--
-
- if(!active)
- return
-
- if(active && stat & (BROKEN|NOPOWER))
- active = 0
- irradiating = 0
- electrified = 0
- return
-
- if(irradiating == 1)
- finished_job()
- irradiating = 0
- return
-
- irradiating--
-
- if(occupant)
- if(prob(radiation_level*2)) occupant.emote("scream")
- if(radiation_level > 2)
- occupant.take_organ_damage(0,radiation_level*2 + rand(1,3))
- if(radiation_level > 1)
- occupant.take_organ_damage(0,radiation_level + rand(1,3))
- occupant.apply_effect(radiation_level*10, IRRADIATE)
-
-/obj/machinery/suit_cycler/proc/finished_job()
- var/turf/T = get_turf(src)
- T.visible_message("\The [src] pings loudly.")
- icon_state = initial(icon_state)
- active = 0
- src.updateUsrDialog()
-
-/obj/machinery/suit_cycler/proc/repair_suit()
- if(!suit || !suit.damage || !suit.can_breach)
- return
-
- suit.breaches = list()
- suit.calc_breach_damage()
-
- return
-
-/obj/machinery/suit_cycler/verb/leave()
- set name = "Eject Cycler"
- set category = "Object"
- set src in oview(1)
-
- if(usr.stat != 0)
- return
-
- eject_occupant(usr)
-
-/obj/machinery/suit_cycler/proc/eject_occupant(mob/user as mob)
-
- if(locked || active)
- to_chat(user, "The cycler is locked.")
- return
-
- if(!occupant)
- return
-
- occupant.forceMove(loc)
- occupant = null
-
- add_fingerprint(usr)
- updateUsrDialog()
- update_icon()
-
- return
-/*
-//HACKING PROCS, MOSTLY COPIED FROM VENDING MACHINES
-/obj/machinery/suit_cycler/proc/isWireColorCut(var/wireColor)
- var/wireFlag = APCWireColorToFlag[wireColor]
- return ((src.wires & wireFlag) == 0)
-
-/obj/machinery/suit_cycler/proc/isWireCut(var/wireIndex)
- var/wireFlag = APCIndexToFlag[wireIndex]
- return ((src.wires & wireFlag) == 0)
-
-/obj/machinery/suit_cycler/proc/cut(var/wireColor)
- var/wireFlag = APCWireColorToFlag[wireColor]
- var/wireIndex = APCWireColorToIndex[wireColor]
- src.wires &= ~wireFlag
- switch(wireIndex)
-
- if(WIRE_EXTEND)
- safeties = 0
- if(WIRE_SHOCK)
- electrified = -1
- if(WIRE_SCANID)
- locked = 0
-
-/obj/machinery/suit_cycler/proc/mend(var/wireColor)
- var/wireFlag = APCWireColorToFlag[wireColor]
- var/wireIndex = APCWireColorToIndex[wireColor] //not used in this function
- src.wires |= wireFlag
- switch(wireIndex)
- if(WIRE_SHOCK)
- src.electrified = 0
-
-/obj/machinery/suit_cycler/proc/pulse(var/wireColor)
- var/wireIndex = APCWireColorToIndex[wireColor]
- switch(wireIndex)
- if(WIRE_EXTEND)
- safeties = !locked
- if(WIRE_SHOCK)
- electrified = 30
- if(WIRE_SCANID)
- locked = !locked
-*/
-
-//There HAS to be a less bloated way to do this. TODO: some kind of table/icon name coding? ~Z
-/obj/machinery/suit_cycler/proc/apply_paintjob()
-
- if(!target_species || !target_department)
- return
-
- if(target_species)
- if(helmet) helmet.refit_for_species(target_species)
- if(suit) suit.refit_for_species(target_species)
-
- switch(target_department)
- if("Engineering")
- if(helmet)
- helmet.name = "engineering hardsuit helmet"
- helmet.icon_state = "hardsuit0-engineering"
- helmet.item_state = "eng_helm"
- helmet.item_color = "engineering"
- if(suit)
- suit.name = "engineering hardsuit"
- suit.icon_state = "hardsuit-engineering"
- suit.item_state = "eng_hardsuit"
- if("Mining")
- if(helmet)
- helmet.name = "mining hardsuit helmet"
- helmet.icon_state = "hardsuit0-mining"
- helmet.item_state = "mining_helm"
- helmet.item_color = "mining"
- if(suit)
- suit.name = "mining hardsuit"
- suit.icon_state = "hardsuit-mining"
- suit.item_state = "mining_hardsuit"
- if("Medical")
- if(helmet)
- helmet.name = "medical hardsuit helmet"
- helmet.icon_state = "hardsuit0-medical"
- helmet.item_state = "medical_helm"
- helmet.item_color = "medical"
- if(suit)
- suit.name = "medical hardsuit"
- suit.icon_state = "hardsuit-medical"
- suit.item_state = "medical_hardsuit"
- if("Security")
- if(helmet)
- helmet.name = "security hardsuit helmet"
- helmet.icon_state = "hardsuit0-sec"
- helmet.item_state = "sec_helm"
- helmet.item_color = "sec"
- if(suit)
- suit.name = "security hardsuit"
- suit.icon_state = "hardsuit-sec"
- suit.item_state = "sec_hardsuit"
- if("Atmos")
- if(helmet)
- helmet.name = "atmospherics hardsuit helmet"
- helmet.icon_state = "hardsuit0-atmos"
- helmet.item_state = "atmos_helm"
- helmet.item_color = "atmos"
- if(suit)
- suit.name = "atmospherics hardsuit"
- suit.icon_state = "hardsuit-atmos"
- suit.item_state = "atmos_hardsuit"
- if("^%###^%$")
- if(helmet)
- helmet.name = "blood-red hardsuit helmet"
- helmet.icon_state = "hardsuit0-syndie"
- helmet.item_state = "syndie_helm"
- helmet.item_color = "syndie"
- if(suit)
- suit.name = "blood-red hardsuit"
- suit.item_state = "syndie_hardsuit"
- suit.icon_state = "hardsuit-syndie"
+ return attack_hand(user)
diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm
index 42d241404b1..d26a24b39a2 100644
--- a/code/game/turfs/simulated/floor.dm
+++ b/code/game/turfs/simulated/floor.dm
@@ -180,7 +180,6 @@ var/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","damaged3","
var/turf/simulated/floor/plating/P = pry_tile(CB, user, TRUE)
if(!istype(P))
return
- update_icon()
P.attackby(T, user, params)
/turf/simulated/floor/proc/pry_tile(obj/item/C, mob/user, silent = FALSE)
diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm
index 4c6eee6311e..c6de130c81a 100644
--- a/code/game/turfs/simulated/floor/plating.dm
+++ b/code/game/turfs/simulated/floor/plating.dm
@@ -15,9 +15,6 @@
/turf/simulated/floor/plating/New()
..()
icon_plating = icon_state
- if(icon == 'icons/turf/floors/plating.dmi')
- smooth = SMOOTH_MORE
- canSmoothWith = list(/turf/simulated/floor/plating, /turf/space)
update_icon()
/turf/simulated/floor/plating/update_icon()
@@ -25,7 +22,6 @@
return
if(!broken && !burnt)
icon_state = icon_plating //Because asteroids are 'platings' too.
- underlays += image(icon, icon_state)
/turf/simulated/floor/plating/attackby(obj/item/C, mob/user, params)
if(..())
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 2e60537ce6f..4d6974f702f 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -226,8 +226,6 @@
for(var/obj/structure/cable/C in contents)
qdel(C)
- smooth_icon(src)
-
/turf/simulated/AfterChange(ignore_air, keep_cabling = FALSE)
..()
RemoveLattice()
diff --git a/code/modules/hydroponics/grown/kudzu.dm b/code/modules/hydroponics/grown/kudzu.dm
index 855ca829bfa..ba67bf426fa 100644
--- a/code/modules/hydroponics/grown/kudzu.dm
+++ b/code/modules/hydroponics/grown/kudzu.dm
@@ -59,7 +59,7 @@
mutations.Remove(pick(temp_mut_list))
temp_mut_list.Cut()
- if(S.has_reagent("welding_fuel", 5))
+ if(S.has_reagent("fuel", 5))
for(var/datum/spacevine_mutation/SM in mutations)
if(SM.quality == POSITIVE)
temp_mut_list += SM
@@ -94,4 +94,4 @@
desc = "Pueraria Virallis: An invasive species with vines that rapidly creep and wrap around whatever they contact."
icon_state = "kudzupod"
filling_color = "#6B8E23"
- bitesize_mod = 2
\ No newline at end of file
+ bitesize_mod = 2
diff --git a/code/modules/hydroponics/sample.dm b/code/modules/hydroponics/sample.dm
index 4478671b2fb..e2d5ea6eb97 100644
--- a/code/modules/hydroponics/sample.dm
+++ b/code/modules/hydroponics/sample.dm
@@ -12,7 +12,7 @@ var/list/chem_t2_reagents = list(
var/list/chem_t3_reagents = list(
"ethanol", "chlorine", "potassium",
"aluminium", "radium", "fluorine",
- "iron", "welding_fuel", "silver",
+ "iron", "fuel", "silver",
"stable_plasma"
)
@@ -41,4 +41,4 @@ var/list/chem_t4_reagents = list(
/obj/item/seeds/sample/alienweed
name = "alien weed sample"
icon_state = "alienweed"
- sample_color = null
\ No newline at end of file
+ sample_color = null
diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm
index 303b34aed34..79cfc3ae9f8 100644
--- a/code/modules/mining/mine_turfs.dm
+++ b/code/modules/mining/mine_turfs.dm
@@ -462,10 +462,10 @@ var/global/list/rockTurfEdgeCache = list(
/turf/simulated/floor/plating/airless/asteroid/New()
var/proper_name = name
+ ..()
name = proper_name
if(prob(20))
icon_state = "asteroid[rand(0,12)]"
- ..()
/turf/simulated/floor/plating/airless/asteroid/ex_act(severity, target)
switch(severity)
diff --git a/code/modules/mob/living/silicon/pai/recruit.dm b/code/modules/mob/living/silicon/pai/recruit.dm
index 45e28a85ee4..1797fc8b4bd 100644
--- a/code/modules/mob/living/silicon/pai/recruit.dm
+++ b/code/modules/mob/living/silicon/pai/recruit.dm
@@ -38,6 +38,8 @@ var/datum/paiController/paiController // Global handler for pAI candidates
var/obj/item/paicard/card = locate(href_list["device"])
if(card.pai)
return
+ if(usr.incapacitated() || isobserver(usr) || !card.Adjacent(usr))
+ return
if(istype(card,/obj/item/paicard) && istype(candidate,/datum/paiCandidate))
var/mob/living/silicon/pai/pai = new(card)
if(!candidate.name)
diff --git a/code/modules/modular_computers/file_system/computer_file.dm b/code/modules/modular_computers/file_system/computer_file.dm
index 25ca387a78e..f3b5a9659b2 100644
--- a/code/modules/modular_computers/file_system/computer_file.dm
+++ b/code/modules/modular_computers/file_system/computer_file.dm
@@ -4,10 +4,11 @@ var/global/file_uid = 0
var/filename = "NewFile" // Placeholder. No spacebars
var/filetype = "XXX" // File full names are [filename].[filetype] so like NewFile.XXX in this case
var/size = 1 // File size in GQ. Integers only!
- var/obj/item/computer_hardware/hard_drive/holder // Holder that contains this file.
+ var/obj/item/computer_hardware/hard_drive/holder // Holder that contains this file.
var/unsendable = 0 // Whether the file may be sent to someone via NTNet transfer or other means.
var/undeletable = 0 // Whether the file may be deleted. Setting to 1 prevents deletion/renaming/etc.
var/uid // UID of this file
+ var/password = "" // Placeholder for password.
/datum/computer_file/New()
..()
@@ -36,4 +37,14 @@ var/global/file_uid = 0
else
temp.filename = filename
temp.filetype = filetype
- return temp
\ No newline at end of file
+ temp.password = password
+ return temp
+
+/datum/computer_file/proc/can_access_file(mob/user, input_password = "")
+ if(!password)
+ return TRUE
+ if(!input_password)
+ input_password = sanitize(input(user, "Please enter a password to access file '[filename]':"))
+ if(input_password == password)
+ return TRUE
+ return FALSE
\ No newline at end of file
diff --git a/code/modules/modular_computers/file_system/programs/generic/file_browser.dm b/code/modules/modular_computers/file_system/programs/generic/file_browser.dm
index 89fea156510..23b2cdab7ab 100644
--- a/code/modules/modular_computers/file_system/programs/generic/file_browser.dm
+++ b/code/modules/modular_computers/file_system/programs/generic/file_browser.dm
@@ -55,7 +55,8 @@
"name" = F.filename,
"type" = F.filetype,
"size" = F.size,
- "undeletable" = F.undeletable
+ "undeletable" = F.undeletable,
+ "encrypted" = !!F.password
)))
data["files"] = files
if(RHDD)
@@ -66,7 +67,8 @@
"name" = F.filename,
"type" = F.filetype,
"size" = F.size,
- "undeletable" = F.undeletable
+ "undeletable" = F.undeletable,
+ "encrypted" = !!F.password
)))
data["usbfiles"] = usbfiles
@@ -83,6 +85,9 @@
switch(href_list["action"])
if("PRG_openfile")
. = 1
+ var/datum/computer_file/F = HDD.find_file_by_name(href_list["name"])
+ if(!F.can_access_file(usr))
+ return
open_file = href_list["name"]
if("PRG_newtextfile")
. = 1
@@ -197,4 +202,27 @@
if(!F || !istype(F))
return 1
var/datum/computer_file/C = F.clone(0)
- HDD.store_file(C)
\ No newline at end of file
+ HDD.store_file(C)
+ if("PRG_encrypt")
+ . = 1
+ if(!HDD)
+ return 1
+ var/datum/computer_file/F = HDD.find_file_by_name(href_list["name"])
+ if(!F || F.undeletable)
+ return 1
+ if(F.password)
+ return
+ var/new_password = sanitize(input(usr, "Enter an encryption key:", "Encrypt File"))
+ if(!new_password)
+ to_chat(usr, "File not encrypted.")
+ return
+ F.password=new_password
+ if("PRG_decrypt")
+ . = 1
+ if(!HDD)
+ return 1
+ var/datum/computer_file/F = HDD.find_file_by_name(href_list["name"])
+ if(!F || F.undeletable)
+ return 1
+ if(F.can_access_file(usr))
+ F.password = ""
\ No newline at end of file
diff --git a/html/changelog.html b/html/changelog.html
index 735cb9d6cee..2b13f2dbd94 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -56,11 +56,38 @@
-->
+
20 October 2018
+
Dapocalypse updated:
+
+ - Adds password protected files to modular computer.
+
+
Purpose updated:
+
+ - Suit storage units now contain magboots for relevant roles.
+ - Adds the captains jetpack to his suit storage unit, so it is now stealable again on Delta.
+
+
uc_guy updated:
+
+ - It is no longer possible to duplicate uvents.
+
+
variableundefined updated:
+
+ - Plating's icon is back to the old one once again.
+
+
19 October 2018
Fox McCloud updated:
- Fixes round-start sparks being stuck in maintenance
+
Purpose updated:
+
+ - Fixed an issue with Space Vine mutations
+
+
SpaceManiac updated:
+
+ - The body zone selector now indicates which body part you are about to select when hovered over.
+
TDSSS updated:
- New exosuit equipment: The rescue jaws for the Odysseus lets it open doors, firelocks and even force powered doors. It can also be added to firefighter ripleys.
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index 24edf7d9cf9..27ae375792b 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -7563,6 +7563,11 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
2018-10-19:
Fox McCloud:
- bugfix: Fixes round-start sparks being stuck in maintenance
+ Purpose:
+ - bugfix: Fixed an issue with Space Vine mutations
+ SpaceManiac:
+ - rscadd: The body zone selector now indicates which body part you are about to
+ select when hovered over.
TDSSS:
- rscadd: 'New exosuit equipment: The rescue jaws for the Odysseus lets it open
doors, firelocks and even force powered doors. It can also be added to firefighter
@@ -7574,3 +7579,14 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
- rscdel: Removed old UI from safe
- tweak: Safe now is only Right - Left - Right. Safe is 0-99 rather than 0-71.
- imageadd: Added safe dial for it's nanoui.
+2018-10-20:
+ Dapocalypse:
+ - rscadd: Adds password protected files to modular computer.
+ Purpose:
+ - rscadd: Suit storage units now contain magboots for relevant roles.
+ - bugfix: Adds the captains jetpack to his suit storage unit, so it is now stealable
+ again on Delta.
+ uc_guy:
+ - bugfix: It is no longer possible to duplicate uvents.
+ variableundefined:
+ - tweak: Plating's icon is back to the old one once again.
diff --git a/html/changelogs/AutoChangeLog-pr-9894.yml b/html/changelogs/AutoChangeLog-pr-9894.yml
new file mode 100644
index 00000000000..07a4419b100
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9894.yml
@@ -0,0 +1,4 @@
+author: "craftxbox"
+delete-after: True
+changes:
+ - bugfix: "added check to make sure person downloading pAI isnt dead."
diff --git a/html/changelogs/AutoChangeLog-pr-9908.yml b/html/changelogs/AutoChangeLog-pr-9908.yml
new file mode 100644
index 00000000000..f18a7bceab8
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9908.yml
@@ -0,0 +1,4 @@
+author: "Fox McCloud"
+delete-after: True
+changes:
+ - tweak: "Updates the Garbage SS so it's less likely to induce lag"
diff --git a/icons/obj/machines/suit_storage.dmi b/icons/obj/machines/suit_storage.dmi
new file mode 100644
index 00000000000..e61f9567c60
Binary files /dev/null and b/icons/obj/machines/suit_storage.dmi differ
diff --git a/icons/obj/suitstorage.dmi b/icons/obj/suitstorage.dmi
deleted file mode 100644
index 3fc3e4e7337..00000000000
Binary files a/icons/obj/suitstorage.dmi and /dev/null differ
diff --git a/icons/turf/floors/plating.dmi b/icons/turf/floors/plating.dmi
index c3c480bfc6a..fee52346e3c 100644
Binary files a/icons/turf/floors/plating.dmi and b/icons/turf/floors/plating.dmi differ
diff --git a/nano/templates/file_manager.tmpl b/nano/templates/file_manager.tmpl
index 1bdb0cd95c4..51d40b84475 100644
--- a/nano/templates/file_manager.tmpl
+++ b/nano/templates/file_manager.tmpl
@@ -32,6 +32,11 @@
{{:helper.link('DELETE', 'trash', {'action' : 'PRG_deletefile', 'name' : value.name}, value.undeletable ? 'disabled' : null)}}
{{:helper.link('RENAME', 'pencil', {'action' : 'PRG_rename', 'name' : value.name}, value.undeletable ? 'disabled' : null)}}
{{:helper.link('CLONE', 'files-o', {'action' : 'PRG_clone', 'name' : value.name}, value.undeletable ? 'disabled' : null)}}
+ {{if !value.encrypted}}
+ {{:helper.link('ENCRYPT', null, {'action' : 'PRG_encrypt', 'name' : value.name}, value.undeletable ? 'disabled' : null)}}
+ {{else}}
+ {{:helper.link('DECRYPT', null, {'action' : 'PRG_decrypt', 'name' : value.name}, value.undeletable ? 'disabled' : null)}}
+ {{/if}}
{{if data.usbconnected}}
{{:helper.link('EXPORT', 'upload', {'action' : 'PRG_copytousb', 'name' : value.name}, value.undeletable ? 'disabled' : null)}}
{{/if}}