diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm
index d698454cab9..0152af8b130 100644
--- a/code/controllers/master_controller.dm
+++ b/code/controllers/master_controller.dm
@@ -39,7 +39,6 @@ datum/controller/game_controller/proc/setup()
setup_objects()
setupgenetics()
- setup_economy()
SetupXenoarch()
transfer_controller = new
diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
index 97e1f59582d..8bc6cc0580c 100644
--- a/code/datums/datacore.dm
+++ b/code/datums/datacore.dm
@@ -2,10 +2,8 @@
data_core = new /obj/effect/datacore()
return 1
-/obj/effect/datacore/proc/manifest(var/nosleep = 0)
+/obj/effect/datacore/proc/manifest()
spawn()
- if(!nosleep)
- sleep(40)
for(var/mob/living/carbon/human/H in player_list)
manifest_inject(H)
return
diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm
index 7e8c8779cff..a0f1f9c7f1c 100644
--- a/code/datums/wires/airlock.dm
+++ b/code/datums/wires/airlock.dm
@@ -37,10 +37,11 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
var/haspower = A.arePowerSystemsOn() //If there's no power, then no lights will be on.
. += ..()
- . += text("
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]",
+ . += text("
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]",
(A.locked ? "The door bolts have fallen!" : "The door bolts look up."),
((A.lights && haspower) ? "The door bolt lights are on." : "The door bolt lights are off!"),
((haspower) ? "The test light is on." : "The test light is off!"),
+ ((A.backupPowerCablesCut()) ? "The backup power light is off!" : "The backup power light is on."),
((A.aiControlDisabled==0 && !A.emagged && haspower)? "The 'AI control allowed' light is on." : "The 'AI control allowed' light is off."),
((A.safe==0 && haspower)? "The 'Check Wiring' light is on." : "The 'Check Wiring' light is off."),
((A.normalspeed==0 && haspower)? "The 'Check Timing Mechanism' light is on." : "The 'Check Timing Mechanism' light is off."),
@@ -124,7 +125,7 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
//Sending a pulse through flashes the red light on the door (if the door has power).
if(A.arePowerSystemsOn() && A.density)
A.do_animate("deny")
- if(AIRLOCK_WIRE_MAIN_POWER1 || AIRLOCK_WIRE_MAIN_POWER2)
+ if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2)
//Sending a pulse through either one causes a breaker to trip, disabling the door for 10 seconds if backup power is connected, or 1 minute if not (or until backup power comes back on, whichever is shorter).
A.loseMainPower()
if(AIRLOCK_WIRE_DOOR_BOLTS)
@@ -135,7 +136,7 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048
else
A.unlock()
- if(AIRLOCK_WIRE_BACKUP_POWER1 || AIRLOCK_WIRE_BACKUP_POWER2)
+ if(AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2)
//two wires for backup power. Sending a pulse through either one causes a breaker to trip, but this does not disable it unless main power is down too (in which case it is disabled for 1 minute or however long it takes main power to come back, whichever is shorter).
A.loseBackupPower()
if(AIRLOCK_WIRE_AI_CONTROL)
diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index 99ff26c89a1..4d564bbf830 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -175,47 +175,91 @@
origin_tech = "materials=1"
var/breakouttime = 300 //Deciseconds = 30s = 0.5 minute
-/obj/item/weapon/legcuffs/beartrap
+/obj/item/weapon/beartrap
name = "bear trap"
throw_speed = 2
throw_range = 1
+ gender = PLURAL
+ icon = 'icons/obj/items.dmi'
icon_state = "beartrap0"
desc = "A trap used to catch bears and other legged creatures."
- var/armed = 0
+ throwforce = 0
+ w_class = 3.0
+ origin_tech = "materials=1"
+ var/deployed = 0
suicide_act(mob/user)
- viewers(user) << "\red [user] is putting the [src.name] on \his head! It looks like \he's trying to commit suicide."
+ viewers(user) << "[user] is putting the [src.name] on \his head! It looks like \he's trying to commit suicide."
return (BRUTELOSS)
-/obj/item/weapon/legcuffs/beartrap/attack_self(mob/user as mob)
+/obj/item/weapon/beartrap/attack_self(mob/user as mob)
..()
if(ishuman(user) && !user.stat && !user.restrained())
- armed = !armed
- icon_state = "beartrap[armed]"
- user << "[src] is now [armed ? "armed" : "disarmed"]"
+ if(deployed==0)
+ user.visible_message("[user] is deploying \the [src]", "You are deploying \the [src]!")
+ if (do_after(user, 60))
+ user.visible_message("[user] has deployed \the [src]", "You have deployed \the [src]!")
+ deployed = 1
+ user.drop_from_inventory(src, user.loc)
+ update_icon()
+ anchored = 1
-/obj/item/weapon/legcuffs/beartrap/Crossed(AM as mob|obj)
- if(armed)
+/obj/item/weapon/beartrap/attack_hand(mob/user as mob)
+ if(ishuman(user) && !user.stat && !user.restrained())
+ if(deployed==1)
+ user.visible_message("[user] is disarming \the [src]", "You are disarming \the [src]!")
+ if (do_after(user, 60))
+ user.visible_message("[user] has disarmed \the [src]", "You have disarmed \the [src]!")
+ deployed = 0
+ anchored = 0
+ update_icon()
+
+ if(deployed==0)
+ ..()
+
+/obj/item/weapon/beartrap/Crossed(AM as mob|obj)
+ if(deployed)
if(ishuman(AM))
if(isturf(src.loc))
- var/mob/living/carbon/H = AM
+ var/mob/living/carbon/human/H = AM
if(H.m_intent == "run")
- armed = 0
- H.legcuffed = src
- src.loc = H
- H.update_inv_legcuffed()
- H << "\red You step on \the [src]!"
- feedback_add_details("handcuffs","B") //Yes, I know they're legcuffs. Don't change this, no need for an extra variable. The "B" is used to tell them apart.
+ deployed = 0
+ update_icon()
+ H << "You step on \the [src]!"
for(var/mob/O in viewers(H, null))
if(O == H)
continue
- O.show_message("\red [H] steps on \the [src].", 1)
+ O.show_message("[H] steps on \the [src].", 1)
+ if(H.lying)
+ var/obj/item/organ/external/affecting = pick(H.organs)
+ if(affecting.take_damage(30, 0))
+ H.UpdateDamageIcon()
+ affecting.embed(src)
+ else
+ var/list/potentialorgans = list()
+ for(var/organ in list("l_leg", "r_leg", "l_foot", "r_foot"))
+ var/obj/item/organ/external/R = H.get_organ(organ)
+ if(R && !(R.status & ORGAN_DESTROYED))
+ potentialorgans += R
+ var/obj/item/organ/external/affecting = pick(potentialorgans)
+ if(affecting.take_damage(30, 0))
+ H.UpdateDamageIcon()
+ affecting.embed(src)
+
+
if(isanimal(AM) && !istype(AM, /mob/living/simple_animal/parrot) && !istype(AM, /mob/living/simple_animal/construct) && !istype(AM, /mob/living/simple_animal/shade) && !istype(AM, /mob/living/simple_animal/hostile/viscerator))
- armed = 0
+ deployed = 0
var/mob/living/simple_animal/SA = AM
SA.health -= 20
..()
+/obj/item/weapon/beartrap/update_icon()
+ ..()
+
+ if(deployed == 0)
+ icon_state = "beartrap0"
+ else
+ icon_state = "beartrap1"
/obj/item/weapon/caution
diff --git a/code/defines/procs/statistics.dm b/code/defines/procs/statistics.dm
index 07856d92512..60254577583 100644
--- a/code/defines/procs/statistics.dm
+++ b/code/defines/procs/statistics.dm
@@ -98,7 +98,7 @@ proc/statistic_cycle()
return
while(1)
sql_poll_population()
- sleep(600)
+ sleep(6000)
//This proc is used for feedback. It is executed at round end.
proc/sql_commit_feedback()
diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm
index 08ad7e72534..34a57a0768b 100644
--- a/code/game/gamemodes/gameticker.dm
+++ b/code/game/gamemodes/gameticker.dm
@@ -110,11 +110,11 @@ var/global/datum/controller/gameticker/ticker
else
src.mode.announce()
+ current_state = GAME_STATE_PLAYING
create_characters() //Create player characters and transfer them
collect_minds()
equip_characters()
data_core.manifest()
- current_state = GAME_STATE_PLAYING
callHook("roundstart")
@@ -155,7 +155,6 @@ var/global/datum/controller/gameticker/ticker
for(var/obj/multiz/ladder/L in world) L.connect() //Lazy hackfix for ladders. TODO: move this to an actual controller. ~ Z
if(config.sql_enabled)
- spawn(3000)
statistic_cycle() // Polls population totals regularly and stores them in an SQL DB -- TLE
return 1
diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm
index 33dcee54a2f..449e5f68ba9 100644
--- a/code/game/jobs/access.dm
+++ b/code/game/jobs/access.dm
@@ -160,7 +160,7 @@
access_hydroponics, access_library, access_lawyer, access_virology, access_psychiatrist, access_cmo, access_qm, access_clown, access_mime, access_surgery,
access_theatre, access_research, access_mining, access_mailsorting,
access_heads_vault, access_mining_station, access_xenobiology, access_ce, access_hop, access_hos, access_RC_announce,
- access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch)
+ access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_medical_equip)
/proc/get_all_centcom_access()
return list(access_cent_general, access_cent_thunder, access_cent_specops, access_cent_medical, access_cent_living, access_cent_storage, access_cent_teleporter, access_cent_creed, access_cent_captain)
diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm
index 125345c518a..3e6f0d8e33a 100644
--- a/code/game/machinery/bots/mulebot.dm
+++ b/code/game/machinery/bots/mulebot.dm
@@ -305,7 +305,14 @@
if("destination")
refresh=0
- var/new_dest = input("Enter new destination tag", "Mulebot [suffix ? "([suffix])" : ""]", destination) as text|null
+ var/new_dest
+ var/list/beaconlist = new()
+ for(var/obj/machinery/navbeacon/N in navbeacons)
+ beaconlist.Add(N.location)
+ if(beaconlist.len)
+ new_dest = input("Select new destination tag", "Mulebot [suffix ? "([suffix])" : ""]", destination) in beaconlist
+ else
+ alert("No destination beacons available.")
refresh=1
if(new_dest)
set_destination(new_dest)
@@ -741,11 +748,6 @@
if(!on)
return
- /*
- world << "rec signal: [signal.source]"
- for(var/x in signal.data)
- world << "* [x] = [signal.data[x]]"
- */
var/recv = signal.data["command"]
// process all-bot input
if(recv=="bot_status" && wires.RemoteRX())
diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm
index d7224f2212a..c9228000e25 100644
--- a/code/game/machinery/navbeacon.dm
+++ b/code/game/machinery/navbeacon.dm
@@ -1,6 +1,9 @@
// Navigation beacon for AI robots
// Functions as a transponder: looks for incoming signal matching
+
+var/global/list/navbeacons // no I don't like putting this in, but it will do for now
+
/obj/machinery/navbeacon
icon = 'icons/obj/objects.dmi'
@@ -27,6 +30,13 @@
var/turf/T = loc
hide(T.intact)
+
+ // add beacon to MULE bot beacon list
+ if(freq == 1400)
+ if(!navbeacons)
+ navbeacons = new()
+ navbeacons += src
+
spawn(5) // must wait for map loading to finish
if(radio_controller)
@@ -241,6 +251,7 @@ Transponder Codes:
"}
updateDialog()
/obj/machinery/navbeacon/Destroy()
+ navbeacons.Remove(src)
if(radio_controller)
radio_controller.remove_object(src, freq)
..()
diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm
index edf09f6ea85..7d0f9e3d4a3 100644
--- a/code/game/objects/items/weapons/twohanded.dm
+++ b/code/game/objects/items/weapons/twohanded.dm
@@ -139,19 +139,17 @@
/obj/item/weapon/twohanded/fireaxe/afterattack(atom/A as mob|obj|turf|area, mob/user as mob, proximity)
if(!proximity) return
..()
- if(A && wielded && (istype(A,/obj/structure/window) || istype(A,/obj/structure/grille))) //destroys windows and grilles in one hit
- if(istype(A,/obj/structure/window)) //should just make a window.Break() proc but couldn't bother with it
+ if(A && wielded)
+ if(istype(A,/obj/structure/window))
var/obj/structure/window/W = A
+ W.shatter()
+ else if(istype(A,/obj/structure/grille))
+ qdel(A)
+ else if(istype(A,/obj/effect/plant))
+ var/obj/effect/plant/P = A
+ P.die_off()
- new /obj/item/weapon/shard( W.loc )
- if(W.reinf) PoolOrNew(/obj/item/stack/rods, W.loc)
-
- if (W.dir == SOUTHWEST)
- new /obj/item/weapon/shard( W.loc )
- if(W.reinf) PoolOrNew(/obj/item/stack/rods, W.loc)
qdel(A)
-
-
/*
* Double-Bladed Energy Swords - Cheridan
*/
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index 5e1a551cecf..3b27308f05c 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -24,9 +24,39 @@
/obj/structure/closet/initialize()
if(!opened) // if closed, any item at the crate's loc is put in the contents
- for(var/obj/item/I in src.loc)
+ var/obj/item/I
+ for(I in src.loc)
if(I.density || I.anchored || I == src) continue
I.loc = src
+ // adjust locker size to hold all items with 5 units of free store room
+ var/content_size = 0
+ for(I in src.contents)
+ content_size += Ceiling(I.w_class/2)
+ if(content_size > storage_capacity-5)
+ storage_capacity = content_size + 5
+
+
+/obj/structure/closet/examine(mob/user)
+ if(get_dist(src, user) > 1)
+ return ..(user)
+
+ if(opened)
+ var/content_size = 0
+ for(var/obj/item/I in src.contents)
+ if(!I.anchored)
+ content_size += Ceiling(I.w_class/2)
+ if(!content_size)
+ user << "It is empty."
+ else if(storage_capacity > content_size*4)
+ user << "It is barely filled."
+ else if(storage_capacity > content_size*2)
+ user << "It is less than half full."
+ else if(storage_capacity > content_size)
+ user << "There is still some free space."
+ else
+ user << "It is full."
+
+
/obj/structure/closet/alter_health()
return get_turf(src)
@@ -329,25 +359,25 @@
escapee.next_move = world.time + 100
escapee.last_special = world.time + 100
escapee << "You lean on the back of \the [src] and start pushing the door open. (this will take about [breakout_time] minutes)"
-
+
visible_message("The [src] begins to shake violently!")
breakout = 1 //can't think of a better way to do this right now.
for(var/i in 1 to (6*breakout_time * 2)) //minutes * 6 * 5seconds * 2
playsound(src.loc, 'sound/effects/grillehit.ogg', 100, 1)
animate_shake()
-
+
if(!do_after(escapee, 50)) //5 seconds
breakout = 0
return
- if(!escapee || escapee.stat || escapee.loc != src)
+ if(!escapee || escapee.stat || escapee.loc != src)
breakout = 0
return //closet/user destroyed OR user dead/unconcious OR user no longer in closet OR closet opened
//Perform the same set of checks as above for weld and lock status to determine if there is even still a point in 'resisting'...
if(!req_breakout())
breakout = 0
return
-
+
//Well then break it!
breakout = 0
escapee << "You successfully break out!"
diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm
index fb9d27f7a57..bf0a5b5ce79 100644
--- a/code/modules/clothing/suits/miscellaneous.dm
+++ b/code/modules/clothing/suits/miscellaneous.dm
@@ -259,7 +259,7 @@
siemens_coefficient = 1
/obj/item/clothing/under/stripper/mankini
- name = "the mankini"
+ name = "mankini"
desc = "No honest man would wear this abomination"
icon_state = "mankini"
siemens_coefficient = 1
diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm
index ce4ff8306b4..feef7d06b1a 100644
--- a/code/modules/clothing/under/accessories/accessory.dm
+++ b/code/modules/clothing/under/accessories/accessory.dm
@@ -91,24 +91,42 @@
if(MALE) their = "his"
if(FEMALE) their = "her"
- var/sound = "pulse"
- var/sound_strength
-
+ var/sound = "heartbeat"
+ var/sound_strength = "cannot hear"
+ var/heartbeat = 0
+ if(M.species && M.species.has_organ["heart"])
+ var/obj/item/organ/heart/heart = M.internal_organs_by_name["heart"]
+ if(heart && !heart.robotic)
+ heartbeat = 1
if(M.stat == DEAD || (M.status_flags&FAKEDEATH))
sound_strength = "cannot hear"
sound = "anything"
else
- sound_strength = "hear a weak"
switch(body_part)
if("chest")
- if(M.oxyloss < 50)
- sound_strength = "hear a healthy"
- sound = "pulse and respiration"
+ sound_strength = "hear"
+ sound = "no heartbeat"
+ if(heartbeat)
+ var/obj/item/organ/heart/heart = M.internal_organs_by_name["heart"]
+ if(heart.is_bruised() || M.getOxyLoss() > 50)
+ sound = "[pick("odd noises in","weak")] heartbeat"
+ else
+ sound = "healthy heartbeat"
+
+ var/obj/item/organ/heart/L = M.internal_organs_by_name["lungs"]
+ if(!L || M.losebreath)
+ sound += " and no respiration"
+ else if(M.is_lung_ruptured() || M.getOxyLoss() > 50)
+ sound += " and [pick("wheezing","gurgling")] sounds"
+ else
+ sound += " and healthy respiration"
if("eyes","mouth")
sound_strength = "cannot hear"
sound = "anything"
else
- sound_strength = "hear a weak"
+ if(heartbeat)
+ sound_strength = "hear a weak"
+ sound = "pulse"
user.visible_message("[user] places [src] against [M]'s [body_part] and listens attentively.", "You place [src] against [their] [body_part]. You [sound_strength] [sound].")
return
diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm
index 8990d309a08..2d088658acd 100644
--- a/code/modules/hydroponics/spreading/spreading.dm
+++ b/code/modules/hydroponics/spreading/spreading.dm
@@ -16,13 +16,13 @@
seed.set_trait(TRAIT_SPREAD,2) // So it will function properly as vines.
seed.set_trait(TRAIT_POTENCY,rand(potency_min, potency_max)) // 70-100 potency will help guarantee a wide spread and powerful effects.
seed.set_trait(TRAIT_MATURATION,rand(maturation_min, maturation_max))
-
+
//make vine zero start off fully matured
var/obj/effect/plant/vine = new(T,seed)
vine.health = vine.max_health
vine.mature_time = 0
vine.process()
-
+
message_admins("Event: Spacevines spawned at [T.loc] ([T.x],[T.y],[T.z])")
/obj/effect/dead_plant
@@ -49,6 +49,7 @@
icon_state = "bush4-1"
layer = 3
pass_flags = PASSTABLE
+ mouse_opacity = 2
var/health = 10
var/max_health = 100
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 56d0a1718fd..72bd64453d5 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -173,7 +173,7 @@
)
for(var/obj/item/organ/external/org in H.organs)
- var/status = ""
+ var/list/status = list()
var/brutedamage = org.brute_dam
var/burndamage = org.burn_dam
if(halloss > 0)
@@ -181,29 +181,39 @@
brutedamage += halloss
if(prob(30))
burndamage += halloss
+ switch(brutedamage)
+ if(1 to 20)
+ status += "bruised"
+ if(20 to 40)
+ status += "wounded"
+ if(40 to INFINITY)
+ status += "mangled"
- if(brutedamage > 0)
- status = "bruised"
- if(brutedamage > 20)
- status = "bleeding"
- if(brutedamage > 40)
- status = "mangled"
- if(brutedamage > 0 && burndamage > 0)
- status += " and "
- if(burndamage > 40)
- status += "peeling away"
+ switch(burndamage)
+ if(1 to 10)
+ status += "numb"
+ if(10 to 40)
+ status += "blistered"
+ if(40 to INFINITY)
+ status += "peeling away"
- else if(burndamage > 10)
- status += "blistered"
- else if(burndamage > 0)
- status += "numb"
if(org.status & ORGAN_DESTROYED)
- status = "MISSING!"
+ status += "MISSING"
if(org.status & ORGAN_MUTATED)
- status = "weirdly shapen."
- if(status == "")
- status = "OK"
- src.show_message(text("\t []My [] is [].",status=="OK"?"\blue ":"\red ",org.name,status),1)
+ status += "weirdly shapen"
+ if(org.dislocated == 2)
+ status += "dislocated"
+ if(org.status & ORGAN_BROKEN)
+ status += "hurts when touched"
+ if(org.status & ORGAN_DEAD)
+ status += "is bruised and necrotic"
+ if(!org.is_usable())
+ status += "dangling uselessly"
+ if(status.len)
+ src.show_message("My [org.name] is [english_list(status)].",1)
+ else
+ src.show_message("My [org.name] is OK.",1)
+
if((SKELETON in H.mutations) && (!H.w_uniform) && (!H.wear_suit))
H.play_xylophone()
else if (on_fire)
@@ -452,17 +462,17 @@
Stun(stun_duration)
Weaken(Floor(stun_duration/2))
return 1
-
+
/mob/living/carbon/proc/add_chemical_effect(var/effect, var/magnitude = 1)
if(effect in chem_effects)
chem_effects[effect] += magnitude
else
- chem_effects[effect] = magnitude
-
+ chem_effects[effect] = magnitude
+
/mob/living/carbon/get_default_language()
if(default_language)
return default_language
if(!species)
return null
- return species.default_language ? all_languages[species.default_language] : null
+ return species.default_language ? all_languages[species.default_language] : null
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index d7255571613..dad4e902446 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -274,76 +274,17 @@
wound_flavor_text["[temp.name]"] = "[t_He] has a robot [temp.name]!\n"
continue
else
- wound_flavor_text["[temp.name]"] = "[t_He] has a robot [temp.name]. It has"
- if(temp.brute_dam) switch(temp.brute_dam)
- if(0 to 20)
- wound_flavor_text["[temp.name]"] += " some dents"
- if(21 to INFINITY)
- wound_flavor_text["[temp.name]"] += pick(" a lot of dents"," severe denting")
- if(temp.brute_dam && temp.burn_dam)
- wound_flavor_text["[temp.name]"] += " and"
- if(temp.burn_dam) switch(temp.burn_dam)
- if(0 to 20)
- wound_flavor_text["[temp.name]"] += " some burns"
- if(21 to INFINITY)
- wound_flavor_text["[temp.name]"] += pick(" a lot of burns"," severe melting")
- if(wound_flavor_text["[temp.name]"])
- wound_flavor_text["[temp.name]"] += "!\n"
- else if(temp.wounds.len > 0)
- var/list/wound_descriptors = list()
- for(var/datum/wound/W in temp.wounds)
- if(W.internal && !temp.open) continue // can't see internal wounds
- var/this_wound_desc = W.desc
- if(W.damage_type == BURN && W.salved) this_wound_desc = "salved [this_wound_desc]"
- if(W.bleeding()) this_wound_desc = "bleeding [this_wound_desc]"
- else if(W.bandaged) this_wound_desc = "bandaged [this_wound_desc]"
- if(W.germ_level > 600) this_wound_desc = "badly infected [this_wound_desc]"
- else if(W.germ_level > 330) this_wound_desc = "lightly infected [this_wound_desc]"
- if(this_wound_desc in wound_descriptors)
- wound_descriptors[this_wound_desc] += W.amount
- continue
- wound_descriptors[this_wound_desc] = W.amount
- if(wound_descriptors.len)
- var/list/flavor_text = list()
- var/list/no_exclude = list("gaping wound", "big gaping wound", "massive wound", "large bruise",\
- "huge bruise", "massive bruise", "severe burn", "large burn", "deep burn", "carbonised area")
- for(var/wound in wound_descriptors)
- switch(wound_descriptors[wound])
- if(1)
- if(!flavor_text.len)
- flavor_text += "[t_He] has[prob(10) && !(wound in no_exclude) ? " what might be" : ""] a [wound]"
- else
- flavor_text += "[prob(10) && !(wound in no_exclude) ? " what might be" : ""] a [wound]"
- if(2)
- if(!flavor_text.len)
- flavor_text += "[t_He] has[prob(10) && !(wound in no_exclude) ? " what might be" : ""] a pair of [wound]s"
- else
- flavor_text += "[prob(10) && !(wound in no_exclude) ? " what might be" : ""] a pair of [wound]s"
- if(3 to 5)
- if(!flavor_text.len)
- flavor_text += "[t_He] has several [wound]s"
- else
- flavor_text += " several [wound]s"
- if(6 to INFINITY)
- if(!flavor_text.len)
- flavor_text += "[t_He] has a bunch of [wound]s"
- else
- flavor_text += " a ton of [wound]\s"
- var/flavor_text_string = ""
- for(var/text = 1, text <= flavor_text.len, text++)
- if(text == flavor_text.len && flavor_text.len > 1)
- flavor_text_string += ", and"
- else if(flavor_text.len > 1 && text > 1)
- flavor_text_string += ","
- flavor_text_string += flavor_text[text]
- flavor_text_string += " on [t_his] [temp.name].
"
- wound_flavor_text["[temp.name]"] = flavor_text_string
- else
- wound_flavor_text["[temp.name]"] = ""
+ wound_flavor_text["[temp.name]"] = "[t_He] has a robot [temp.name]. It has[temp.get_wounds_desc()]!\n"
+ else if(temp.wounds.len > 0 || temp.open)
+ wound_flavor_text["[temp.name]"] = "[t_He] has [temp.get_wounds_desc()] on [t_his] [temp.name].
"
if(temp.status & ORGAN_BLEEDING)
is_bleeding["[temp.name]"] = 1
else
wound_flavor_text["[temp.name]"] = ""
+ if(temp.dislocated == 2)
+ wound_flavor_text["[temp.name]"] += "[capitalize(t_his)] [temp.joint] is dislocated!
"
+ if(((temp.status & ORGAN_BROKEN) && temp.brute_dam > temp.min_broken_damage) || (temp.status & ORGAN_MUTATED))
+ wound_flavor_text["[temp.name]"] += "[capitalize(t_his)] [temp.name] is dented and swollen!
"
//Handles the text strings being added to the actual description.
//If they have something that covers the limb, and it is not missing, put flavortext. If it is covered but bleeding, add other flavortext.
@@ -354,9 +295,9 @@
msg += wound_flavor_text["head"]
else if(is_bleeding["head"])
msg += "[src] has blood running down [t_his] face!\n"
- if(wound_flavor_text["chest"] && !w_uniform && !skipjumpsuit) //No need. A missing chest gibs you.
- msg += wound_flavor_text["chest"]
- else if(is_bleeding["chest"])
+ if(wound_flavor_text["upper body"] && !w_uniform && !skipjumpsuit) //No need. A missing chest gibs you.
+ msg += wound_flavor_text["upper body"]
+ else if(is_bleeding["upper body"])
display_chest = 1
if(wound_flavor_text["left arm"] && (is_destroyed["left arm"] || (!w_uniform && !skipjumpsuit)))
msg += wound_flavor_text["left arm"]
@@ -374,9 +315,9 @@
msg += wound_flavor_text["right hand"]
else if(is_bleeding["right hand"])
display_gloves = 1
- if(wound_flavor_text["groin"] && (is_destroyed["groin"] || (!w_uniform && !skipjumpsuit)))
- msg += wound_flavor_text["groin"]
- else if(is_bleeding["groin"])
+ if(wound_flavor_text["lower body"] && (is_destroyed["lower body"] || (!w_uniform && !skipjumpsuit)))
+ msg += wound_flavor_text["lower body"]
+ else if(is_bleeding["lower body"])
display_chest = 1
if(wound_flavor_text["left leg"] && (is_destroyed["left leg"] || (!w_uniform && !skipjumpsuit)))
msg += wound_flavor_text["left leg"]
diff --git a/code/modules/mob/living/silicon/robot/robot_items.dm b/code/modules/mob/living/silicon/robot/robot_items.dm
index 3bc0dd9a150..768e42370f2 100644
--- a/code/modules/mob/living/silicon/robot/robot_items.dm
+++ b/code/modules/mob/living/silicon/robot/robot_items.dm
@@ -129,7 +129,10 @@
return
if(istype(target,/obj/machinery/portable_atmospherics/hydroponics))
var/obj/machinery/portable_atmospherics/hydroponics/T = target
- T.harvest(user)
+ if(T.harvest) //Try to harvest, assuming it's alive.
+ T.harvest(user)
+ else if(T.dead) //It's probably dead otherwise.
+ T.remove_dead(user)
else
user << "Harvesting \a [target] is not the purpose of this tool. The [src] is for plants being grown."
diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm
index d3b889198c5..4a51684139b 100644
--- a/code/modules/mob/mob_grab.dm
+++ b/code/modules/mob/mob_grab.dm
@@ -297,6 +297,43 @@
assailant << "You are no longer pinning [affecting] to the ground."
force_down = 0
return
+ var/mob/living/carbon/human/H = M
+ var/obj/item/organ/external/E = H.get_organ(hit_zone)
+ if(E && !(E.status & ORGAN_DESTROYED))
+ assailant.visible_message("[assailant] starts inspecting [affecting]'s [E.name] carefully.")
+ if(do_mob(assailant,H, 10))
+ if(E.wounds.len)
+ assailant << "You find [E.get_wounds_desc()]"
+ else
+ assailant << "You find no visible wounds."
+ else
+ assailant << "You must stand still to inspect [E] for wounds."
+ assailant << "Checking bones now..."
+ if(do_mob(assailant, H, 20))
+ if(E.status & ORGAN_BROKEN)
+ assailant << "The [E.encased ? E.encased : "bone in the [E.name]"] moves slightly when you poke it!"
+ H.custom_pain("Your [E.name] hurts where it's poked.")
+ else
+ assailant << "The [E.encased ? E.encased : "bones in the [E.name]"] seem to be fine."
+ else
+ assailant << "You must stand still to feel [E] for fractures."
+ assailant << "Checking skin now..."
+ if(do_mob(assailant, H, 10))
+ var/bad = 0
+ if(H.getToxLoss() >= 40)
+ assailant << "[H] has an unhealthy skin discoloration."
+ bad = 1
+ if(H.getOxyLoss() >= 20)
+ assailant << "[H]'s skin is unusaly pale."
+ bad = 1
+ if(E.status & ORGAN_DEAD)
+ assailant << "[E] is decaying!"
+ if(!bad)
+ assailant << "[H]'s skin is normal."
+ else
+ assailant << "You must stand still to check [H]'s skin for abnormalities."
+ else
+ assailant << "[H] is missing that bodypart."
if(I_GRAB)
if(state < GRAB_AGGRESSIVE)
assailant << "You require a better grab to do this."
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index c0a7fbce3c5..1f7220f6995 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -106,7 +106,8 @@
O.add_ai_verbs()
O.rename_self("ai",1)
- qdel(src)
+ spawn(0) // Mobs still instantly del themselves, thus we need to spawn or O will never be returned
+ qdel(src)
return O
//human -> robot
@@ -158,7 +159,8 @@
callHook("borgify", list(O))
O.Namepick()
- qdel(src)
+ spawn(0) // Mobs still instantly del themselves, thus we need to spawn or O will never be returned
+ qdel(src)
return O
//human -> alien
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index 84775c2ac49..d8817aa56d8 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -926,6 +926,58 @@ Note that amputating the affected organ does in fact remove the infection from t
"\red You hear a sickening sizzle.")
disfigured = 1
+/obj/item/organ/external/proc/get_wounds_desc()
+ . = ""
+ if(status & ORGAN_ROBOT)
+ if(brute_dam)
+ switch(brute_dam)
+ if(0 to 20)
+ . += " some dents"
+ if(21 to INFINITY)
+ . += pick(" a lot of dents"," severe denting")
+ if(brute_dam && burn_dam)
+ . += " and"
+ if(burn_dam)
+ switch(burn_dam)
+ if(0 to 20)
+ . += " some burns"
+ if(21 to INFINITY)
+ . += pick(" a lot of burns"," severe melting")
+ return
+
+ var/list/wound_descriptors = list()
+ if(open > 1)
+ wound_descriptors["an open incision"] = 1
+ else if (open)
+ wound_descriptors["an incision"] = 1
+ for(var/datum/wound/W in wounds)
+ if(W.internal && !open) continue // can't see internal wounds
+ var/this_wound_desc = W.desc
+ if(W.damage_type == BURN && W.salved) this_wound_desc = "salved [this_wound_desc]"
+ if(W.bleeding()) this_wound_desc = "bleeding [this_wound_desc]"
+ else if(W.bandaged) this_wound_desc = "bandaged [this_wound_desc]"
+ if(W.germ_level > 600) this_wound_desc = "badly infected [this_wound_desc]"
+ else if(W.germ_level > 330) this_wound_desc = "lightly infected [this_wound_desc]"
+ if(wound_descriptors[this_wound_desc])
+ wound_descriptors[this_wound_desc] += W.amount
+ else
+ wound_descriptors[this_wound_desc] = W.amount
+
+ if(wound_descriptors.len)
+ var/list/flavor_text = list()
+ var/list/no_exclude = list("gaping wound", "big gaping wound", "massive wound", "large bruise",\
+ "huge bruise", "massive bruise", "severe burn", "large burn", "deep burn", "carbonised area")
+ for(var/wound in wound_descriptors)
+ switch(wound_descriptors[wound])
+ if(1)
+ flavor_text += "[prob(10) && !(wound in no_exclude) ? "what might be " : ""]a [wound]"
+ if(2)
+ flavor_text += "[prob(10) && !(wound in no_exclude) ? "what might be " : ""]a pair of [wound]s"
+ if(3 to 5)
+ flavor_text += "several [wound]s"
+ if(6 to INFINITY)
+ flavor_text += "a ton of [wound]\s"
+ return english_list(flavor_text)
/****************************************************
ORGAN DEFINES
****************************************************/
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm
index 2d742bd01ed..eac0f76cd27 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm
@@ -11,6 +11,17 @@
description = "A chemical element, the builing block of life."
reagent_state = SOLID
color = "#1C1300"
+ ingest_met = REM * 5
+
+/datum/reagent/carbon/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
+ if(alien == IS_DIONA)
+ return
+ if(M.ingested && M.ingested.reagent_list.len > 1) // Need to have at least 2 reagents - cabon and something to remove
+ var/effect = 1 / (M.ingested.reagent_list.len - 1)
+ for(var/datum/reagent/R in M.ingested.reagent_list)
+ if(R == src)
+ continue
+ M.ingested.remove_reagent(R.id, removed * effect)
/datum/reagent/carbon/touch_turf(var/turf/T)
if(!istype(T, /turf/space))
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
index c17178ae630..0009684c309 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
@@ -329,7 +329,7 @@
M.stuttering = 0
M.confused = 0
if(M.ingested)
- for(var/datum/reagent/R in M.ingested)
+ for(var/datum/reagent/R in M.ingested.reagent_list)
if(istype(R, /datum/reagent/ethanol))
R.dose = max(R.dose - removed * 5, 0)
diff --git a/code/modules/research/xenoarchaeology/finds/finds.dm b/code/modules/research/xenoarchaeology/finds/finds.dm
index 7de8474aef7..7c1a238083d 100644
--- a/code/modules/research/xenoarchaeology/finds/finds.dm
+++ b/code/modules/research/xenoarchaeology/finds/finds.dm
@@ -191,7 +191,7 @@
if(9)
item_type = "[pick("wicked","evil","byzantine","dangerous")] looking [pick("device","contraption","thing","trap")]"
apply_prefix = 0
- new_item = new /obj/item/weapon/legcuffs/beartrap(src.loc)
+ new_item = new /obj/item/weapon/beartrap(src.loc)
additional_desc = "[pick("It looks like it could take a limb off",\
"Could be some kind of animal trap",\
"There appear to be [pick("dark red","dark purple","dark green","dark blue")] stains along part of it")]."
diff --git a/code/modules/tables/interactions.dm b/code/modules/tables/interactions.dm
index 09e32deebea..980227db8cf 100644
--- a/code/modules/tables/interactions.dm
+++ b/code/modules/tables/interactions.dm
@@ -123,7 +123,7 @@
break_to_parts()
return
- if(!material)
+ if(can_plate && !material)
user << "There's nothing to put \the [W] on! Try adding plating to \the [src] first."
return
diff --git a/html/changelog.html b/html/changelog.html
index fcd40835d23..6cc3c3bc315 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -56,6 +56,33 @@
-->
+
18 May 2015
+
Hubblenaut updated:
+
+ - Adds a light for available backup power on airlocks.
+
+
Kelenius updated:
+
+ - There has been a big update to the reagent system. A full-ish changelog can be found here: http://pastebin.com/imHXTRHz. In particular:
+ - Reagents now differentiate between being ingested (food, pills, smoke), injected (syringes, IV drips), and put on the skin (sprays, beaker splashing).
+ - Injecting food and drinks will cause bad effects.
+ - Healing reagents, generally speaking, have stronger effects when injected.
+ - Toxins now work slower and deal more damage. Seek medical help!
+ - Alcohol robustness has been lowered.
+ - Acid will no longer melt large numbers of items at once.
+ - Synaptizine is no longer hilariously deadly.
+
+
Loganbacca updated:
+
+ - Changed MULE destination selection to be list based.
+
+
PsiOmegaDelta updated:
+
+ - Destroying a camera by brute force now has a chance to break the wiring within.
+ - Turf are now processed. This, for example, causes radioactive walls to regularly irradiate nearby mobs.
+ - Welders should now always update their icon and inhand states properly.
+
+
17 May 2015
PsiOmegaDelta updated:
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index 257c304edf8..a0bf108e0e1 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -1794,3 +1794,25 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
2015-05-17:
PsiOmegaDelta:
- bugfix: Teleporter artifacts should no longer teleport mobs inside objects.
+2015-05-18:
+ Hubblenaut:
+ - rscadd: Adds a light for available backup power on airlocks.
+ Kelenius:
+ - tweak: 'There has been a big update to the reagent system. A full-ish changelog
+ can be found here: http://pastebin.com/imHXTRHz. In particular:'
+ - tweak: Reagents now differentiate between being ingested (food, pills, smoke),
+ injected (syringes, IV drips), and put on the skin (sprays, beaker splashing).
+ - tweak: Injecting food and drinks will cause bad effects.
+ - tweak: Healing reagents, generally speaking, have stronger effects when injected.
+ - tweak: Toxins now work slower and deal more damage. Seek medical help!
+ - tweak: Alcohol robustness has been lowered.
+ - tweak: Acid will no longer melt large numbers of items at once.
+ - tweak: Synaptizine is no longer hilariously deadly.
+ Loganbacca:
+ - tweak: Changed MULE destination selection to be list based.
+ PsiOmegaDelta:
+ - tweak: Destroying a camera by brute force now has a chance to break the wiring
+ within.
+ - rscadd: Turf are now processed. This, for example, causes radioactive walls to
+ regularly irradiate nearby mobs.
+ - bugfix: Welders should now always update their icon and inhand states properly.
diff --git a/html/changelogs/Comma-PR-9337.yml b/html/changelogs/Comma-PR-9337.yml
new file mode 100644
index 00000000000..cf1aac28916
--- /dev/null
+++ b/html/changelogs/Comma-PR-9337.yml
@@ -0,0 +1,8 @@
+author: Chinsky
+
+delete-after: True
+
+changes:
+ - rscadd: "Ghetto diagnosis. Grab patient, aim at bodypart you want to check, click on them with help intent. This will tell you about their wounds, fractures and other oddities (toxins/oxygen) for that bodypart."
+ - rscadd: "Fractures are visible on very damaged limbs. Dislocations are always visible. Surgery incisions now visible too."
+ - rscadd: "Stethoscopes actually make sense now. They care for heart/lungs status when reporting pulse and respiration now."
\ No newline at end of file
diff --git a/html/changelogs/PsiOmegaDelta-RandomWireBreaking.yml b/html/changelogs/PsiOmegaDelta-RandomWireBreaking.yml
deleted file mode 100644
index 64d8b00286f..00000000000
--- a/html/changelogs/PsiOmegaDelta-RandomWireBreaking.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: PsiOmegaDelta
-delete-after: True
-
-changes:
- - tweak: "Destroying a camera by brute force now has a chance to break the wiring within."
diff --git a/html/changelogs/PsiOmegaDelta-TurfProcessing.yml b/html/changelogs/PsiOmegaDelta-TurfProcessing.yml
deleted file mode 100644
index a7bb128b14a..00000000000
--- a/html/changelogs/PsiOmegaDelta-TurfProcessing.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: PsiOmegaDelta
-delete-after: True
-changes:
- - rscadd: "Turf are now processed. This, for example, causes radioactive walls to regularly irradiate nearby mobs."
diff --git a/html/changelogs/PsiOmegaDelta-WelderIcon-150516.yml b/html/changelogs/PsiOmegaDelta-WelderIcon-150516.yml
deleted file mode 100644
index a7c90fbd7a9..00000000000
--- a/html/changelogs/PsiOmegaDelta-WelderIcon-150516.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: PsiOmegaDelta
-delete-after: True
-
-changes:
- - bugfix: "Welders should now always update their icon and inhand states properly."
diff --git a/html/changelogs/Yoshax - trapping.YML b/html/changelogs/Yoshax - trapping.YML
new file mode 100644
index 00000000000..d9b7884761a
--- /dev/null
+++ b/html/changelogs/Yoshax - trapping.YML
@@ -0,0 +1,37 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: Yoshax
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - tweak: "Bear traps now do damage when stood on, enough to break bones! Bear traps can now affect any limb of a person who is on the ground, including head! Bear traps are no longer legcuffs and instead embed in the limb they attack."
+ - tweak: "Bear traps now take several seconds to deploy and cannot be picked up when armed, they must be disarmed by clicking on them. They also cannot be moved then they are deployed."
\ No newline at end of file
diff --git a/icons/obj/tables.dmi b/icons/obj/tables.dmi
index 36de1b41836..99b21bcfcbc 100644
Binary files a/icons/obj/tables.dmi and b/icons/obj/tables.dmi differ
diff --git a/maps/exodus-1.dmm b/maps/exodus-1.dmm
index 5d41e5d42da..9e54641cc1f 100644
--- a/maps/exodus-1.dmm
+++ b/maps/exodus-1.dmm
@@ -4927,7 +4927,7 @@
"bQM" = (/obj/structure/table/standard,/obj/machinery/newscaster/security_unit{pixel_x = 0; pixel_y = 32},/obj/machinery/recharger{pixel_y = 0},/obj/item/weapon/packageWrap,/obj/item/weapon/hand_labeler,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/crew_quarters/heads/hop)
"bQN" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/obj/machinery/light,/turf/simulated/floor,/area/janitor)
"bQO" = (/obj/structure/janitorialcart,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor,/area/janitor)
-"bQP" = (/obj/item/weapon/legcuffs/beartrap,/obj/item/weapon/legcuffs/beartrap,/obj/item/weapon/storage/box/mousetraps,/obj/item/weapon/storage/box/mousetraps,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/janitor)
+"bQP" = (/obj/item/weapon/beartrap,/obj/item/weapon/storage/box/mousetraps,/obj/item/weapon/storage/box/mousetraps,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/item/weapon/beartrap,/turf/simulated/floor,/area/janitor)
"bQQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/janitor)
"bQR" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor,/area/janitor)
"bQS" = (/obj/effect/decal/cleanable/cobweb,/obj/effect/decal/cleanable/generic,/turf/simulated/floor/plating,/area/maintenance/engineering)