diff --git a/code/WorkInProgress/computer3/lapvend.dm b/code/WorkInProgress/computer3/lapvend.dm
index 36de9e4cfc9..72531b5d8ee 100644
--- a/code/WorkInProgress/computer3/lapvend.dm
+++ b/code/WorkInProgress/computer3/lapvend.dm
@@ -174,8 +174,9 @@
vendmode = 1
if("cancel")
- relap.loc = src.loc
- relap = null
+ if(relap)
+ relap.loc = src.loc
+ relap = null
vendmode = 0
src.updateUsrDialog()
diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index e666a036530..e3c9ff8c867 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -866,6 +866,7 @@ client
return
var/new_organ = input("Please choose an organ to add.","Organ",null) as null|anything in typesof(/datum/organ/internal)-/datum/organ/internal
+ if(!new_organ) return
if(!M)
usr << "Mob doesn't exist anymore"
diff --git a/code/defines/procs/radio.dm b/code/defines/procs/radio.dm
index 0cbd009076c..1e0e045928b 100644
--- a/code/defines/procs/radio.dm
+++ b/code/defines/procs/radio.dm
@@ -47,7 +47,7 @@
/proc/get_receiver_reception(var/receiver, var/datum/signal/signal)
if(receiver && check_signal(signal))
var/turf/pos = get_turf(receiver)
- if(pos.z in signal.data["level"])
+ if(pos && (pos.z in signal.data["level"]))
return TELECOMMS_RECEPTION_RECEIVER
return TELECOMMS_RECEPTION_NONE
diff --git a/code/game/machinery/doors/firedoor_assembly.dm b/code/game/machinery/doors/firedoor_assembly.dm
index 1372997f83f..435a9278577 100644
--- a/code/game/machinery/doors/firedoor_assembly.dm
+++ b/code/game/machinery/doors/firedoor_assembly.dm
@@ -5,7 +5,7 @@ obj/structure/firedoor_assembly
icon_state = "door_construction"
anchored = 0
opacity = 0
- density = 0
+ density = 1
var/wired = 0
obj/structure/firedoor_assembly/update_icon()
@@ -35,7 +35,7 @@ obj/structure/firedoor_assembly/attackby(C as obj, mob/user as mob)
user << "You cut the wires!"
new/obj/item/stack/cable_coil(src.loc, 1)
wired = 0
-
+
else if(istype(C, /obj/item/weapon/airalarm_electronics) && wired)
if(anchored)
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
@@ -48,7 +48,6 @@ obj/structure/firedoor_assembly/attackby(C as obj, mob/user as mob)
user << "You must secure \the [src] first!"
else if(istype(C, /obj/item/weapon/wrench))
anchored = !anchored
- density = !density
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
user.visible_message("[user] has [anchored ? "" : "un" ]secured \the [src]!",
"You have [anchored ? "" : "un" ]secured \the [src]!")
diff --git a/code/game/machinery/supply_display.dm b/code/game/machinery/supply_display.dm
index aacd770d790..97e747c0dba 100644
--- a/code/game/machinery/supply_display.dm
+++ b/code/game/machinery/supply_display.dm
@@ -3,7 +3,7 @@
/obj/machinery/status_display/supply_display/update()
if(!..() && mode == STATUS_DISPLAY_CUSTOM)
- message1 = "SUPPLY"
+ message1 = "CARGO"
message2 = ""
var/datum/shuttle/ferry/supply/shuttle = supply_controller.shuttle
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 09850e39632..d0c52d7f59f 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -35,7 +35,7 @@
var/siemens_coefficient = 1 // for electrical admittance/conductance (electrocution checks and shit)
var/slowdown = 0 // How much clothing is slowing you down. Negative values speeds you up
var/canremove = 1 //Mostly for Ninja code at this point but basically will not allow the item to be removed if set to 0. /N
- var/armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
+ var/list/armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
var/list/allowed = null //suit storage stuff.
var/obj/item/device/uplink/hidden/hidden_uplink = null // All items can have an uplink hidden inside, just remember to add the triggers.
var/zoomdevicename = null //name used for message when binoculars/scope is used
diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm
index d7a20b73d01..c006cd892db 100644
--- a/code/modules/clothing/masks/gasmask.dm
+++ b/code/modules/clothing/masks/gasmask.dm
@@ -12,6 +12,7 @@
siemens_coefficient = 0.9
var/gas_filter_strength = 1 //For gas mask filters
var/list/filtered_gases = list("phoron", "sleeping_agent")
+ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 75, rad = 0)
/obj/item/clothing/mask/gas/filter_air(datum/gas_mixture/air)
var/datum/gas_mixture/filtered = new
@@ -32,7 +33,7 @@
desc = "A modernised version of the classic design, this mask will not only filter out phoron but it can also be connected to an air supply."
icon_state = "plaguedoctor"
item_state = "gas_mask"
- armor = list(melee = 0, bullet = 0, laser = 2,energy = 2, bomb = 0, bio = 75, rad = 0)
+ armor = list(melee = 0, bullet = 0, laser = 2,energy = 2, bomb = 0, bio = 90, rad = 0)
body_parts_covered = HEAD|FACE
/obj/item/clothing/mask/gas/swat
diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm
index 3f3094c794d..758baae8b9c 100644
--- a/code/modules/clothing/masks/miscellaneous.dm
+++ b/code/modules/clothing/masks/miscellaneous.dm
@@ -24,7 +24,7 @@
body_parts_covered = 0
gas_transfer_coefficient = 0.90
permeability_coefficient = 0.01
- armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 25, rad = 0)
+ armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 60, rad = 0)
/obj/item/clothing/mask/fakemoustache
name = "fake moustache"
diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm
index dd0d073cd24..b308fda2b40 100644
--- a/code/modules/clothing/spacesuits/rig/rig.dm
+++ b/code/modules/clothing/spacesuits/rig/rig.dm
@@ -138,7 +138,7 @@
piece.name = "[suit_type] [initial(piece.name)]"
piece.desc = "It seems to be part of a [src.name]."
piece.icon_state = "[initial(icon_state)]"
- piece.armor = armor
+ piece.armor = armor.Copy()
piece.min_cold_protection_temperature = min_cold_protection_temperature
piece.max_heat_protection_temperature = max_heat_protection_temperature
piece.siemens_coefficient = siemens_coefficient
@@ -227,7 +227,7 @@
if(!failed_to_seal && M.back == src && piece == compare_piece)
if(!instant)
- if(!do_after(M,SEAL_DELAY))
+ if(!do_after(M,SEAL_DELAY,needhand=0))
failed_to_seal = 1
piece.icon_state = "[initial(icon_state)][!seal_target ? "_sealed" : ""]"
@@ -251,6 +251,13 @@
else
helmet.flags &= ~AIRTIGHT
helmet.update_light(wearer)
+
+ //sealed pieces become airtight, protecting against diseases
+ if (!seal_target)
+ piece.armor["bio"] = 100
+ else
+ piece.armor["bio"] = src.armor["bio"]
+
else
failed_to_seal = 1
diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm
index 509d0697540..33e6f47c574 100644
--- a/code/modules/hydroponics/seed_datums.dm
+++ b/code/modules/hydroponics/seed_datums.dm
@@ -217,8 +217,8 @@ proc/populate_seed_list()
"water",
"potassium",
"plasticide",
- "slimetoxin",
- "aslimetoxin",
+ "mutationtoxin",
+ "amutationtoxin",
"inaprovaline",
"space_drugs",
"paroxetine",
diff --git a/code/modules/hydroponics/vines.dm b/code/modules/hydroponics/vines.dm
index b25c03080ed..699063fec46 100644
--- a/code/modules/hydroponics/vines.dm
+++ b/code/modules/hydroponics/vines.dm
@@ -362,6 +362,8 @@
SV.life()
+ if(!SV) continue
+
if(SV.energy < 2) //If tile isn't fully grown
var/chance
if(seed)
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index c2f7adc1716..c1d577834d3 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -143,7 +143,7 @@ Works together with spawning an observer, noted above.
ghost.can_reenter_corpse = can_reenter_corpse
ghost.timeofdeath = src.timeofdeath //BS12 EDIT
ghost.key = key
- if(!ghost.client.holder && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed.
+ if(ghost.client && !ghost.client.holder && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed.
ghost.verbs -= /mob/dead/observer/verb/toggle_antagHUD // Poor guys, don't know what they are missing!
return ghost
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index de50d9aa442..414f7e2bfb3 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -120,7 +120,7 @@ emp_act
/mob/living/carbon/human/proc/getarmor_organ(var/datum/organ/external/def_zone, var/type)
if(!type) return 0
var/protection = 0
- var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform)
+ var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes)
for(var/gear in protective_gear)
if(gear && istype(gear ,/obj/item/clothing))
var/obj/item/clothing/C = gear
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index de66e6bef11..72c281a1f2d 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -407,11 +407,10 @@
loc.assume_air(breath)
//spread some viruses while we are at it
- if (virus2.len > 0)
- if (prob(10) && get_infection_chance(src))
-// log_debug("[src] : Exhaling some viruses")
- for(var/mob/living/carbon/M in view(1,src))
- src.spread_disease_to(M)
+ if (virus2.len > 0 && prob(10))
+// log_debug("[src] : Exhaling some viruses")
+ for(var/mob/living/carbon/M in view(1,src))
+ src.spread_disease_to(M)
proc/get_breath_from_internal(volume_needed)
diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm
index d1f0c824548..366cd9351d4 100644
--- a/code/modules/power/power.dm
+++ b/code/modules/power/power.dm
@@ -294,6 +294,8 @@
for(var/obj/structure/cable/Cable in net2.cables) //merge cables
net1.add_cable(Cable)
+ if(!net2) return net1
+
for(var/obj/machinery/power/Node in net2.nodes) //merge power machines
if(!Node.connect_to_network())
Node.disconnect_from_network() //if somehow we can't connect the machine to the new powernet, disconnect it from the old nonetheless
diff --git a/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm b/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm
index 1b3afdd22c4..41089867896 100644
--- a/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm
+++ b/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm
@@ -102,7 +102,7 @@
spawned_obj.desc += " It is made of [source_material]."
else
spawned_obj.desc = "It is made of [source_material]."
- source_material.loc = null
+ del(source_material)
spawn_progress_time = 0
max_spawn_time = rand(30,100)
diff --git a/code/modules/virus2/helpers.dm b/code/modules/virus2/helpers.dm
index 927078b062a..18c2db0f14c 100644
--- a/code/modules/virus2/helpers.dm
+++ b/code/modules/virus2/helpers.dm
@@ -1,49 +1,58 @@
-//Returns 1 if mob can be infected, 0 otherwise. Checks his clothing.
-proc/get_infection_chance(var/mob/living/carbon/M, var/vector = "Airborne")
- var/score = 0
+//Returns 1 if mob can be infected, 0 otherwise.
+proc/infection_check(var/mob/living/carbon/M, var/vector = "Airborne")
if (!istype(M))
return 0
- if(istype(M, /mob/living/carbon/human))
+ var/protection = M.getarmor(null, "bio") //gets the full body bio armour value, weighted by body part coverage.
+ var/score = round(0.06*protection) //scales 100% protection to 6.
- if (vector == "Airborne")
- if(M.internal) //not breathing infected air helps greatly
- score = 30
- if(M.wear_mask)
- score += 5
- if(istype(M:wear_mask, /obj/item/clothing/mask/surgical) && !M.internal)
- score += 10
- if(istype(M:wear_suit, /obj/item/clothing/suit/space) && istype(M:head, /obj/item/clothing/head/helmet/space))
- score += 20
- if(istype(M:wear_suit, /obj/item/clothing/suit/bio_suit) && istype(M:head, /obj/item/clothing/head/bio_hood))
- score += 30
+ switch(vector)
+ if("Airborne")
+ if(M.internal)
+ score = 6 //not breathing infected air helps greatly
+ var/obj/item/I = M.wear_mask
+
+ //masks provide a small bonus and can replace overall bio protection
+ score = max(score, round(0.06*I.armor["bio"]))
+ if (istype(I, /obj/item/clothing/mask))
+ score += 1 //this should be added after
+
+ if("Contact")
+ if(istype(M, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = M
+
+ //gloves provide a larger bonus
+ if (istype(H.gloves, /obj/item/clothing/gloves))
+ score += 2
-
- if (vector == "Contact")
- if(M:gloves) score += 15
- if(istype(M:wear_suit, /obj/item/clothing/suit/space) && istype(M:head, /obj/item/clothing/head/helmet/space))
- score += 15
- if(istype(M:wear_suit, /obj/item/clothing/suit/bio_suit) && istype(M:head, /obj/item/clothing/head/bio_hood))
- score += 15
-
-
-// log_debug("[M]'s resistance to [vector] viruses: [score]")
-
- if(score >= 30)
+ if(score >= 6)
return 0
- else if(score == 25 && prob(99))
+ else if(score >= 5 && prob(99))
return 0
- else if(score == 20 && prob(95))
+ else if(score >= 4 && prob(95))
return 0
- else if(score == 15 && prob(75))
+ else if(score >= 3 && prob(75))
return 0
- else if(score == 10 && prob(55))
+ else if(score >= 2 && prob(55))
return 0
- else if(score == 5 && prob(35))
+ else if(score >= 1 && prob(35))
return 0
-// log_debug("Infection got through")
return 1
+//Similar to infection check, but used for when M is spreading the virus.
+/proc/infection_spreading_check(var/mob/living/carbon/M, var/vector = "Airborne")
+ if (!istype(M))
+ return 0
+
+ var/protection = M.getarmor(null, "bio") //gets the full body bio armour value, weighted by body part coverage.
+
+ if (vector == "Airborne")
+ var/obj/item/I = M.wear_mask
+ if (istype(I))
+ protection = max(protection, round(0.06*I.armor["bio"]))
+
+ return prob(protection)
+
//Checks if table-passing table can reach target (5 tile radius)
proc/airborne_can_reach(turf/source, turf/target)
var/obj/dummy = new(source)
@@ -84,17 +93,14 @@ proc/airborne_can_reach(turf/source, turf/target)
// log_debug("Infecting [M]")
- if(prob(disease.infectionchance) || forced)
- // certain clothes can prevent an infection
- if(!forced && !get_infection_chance(M, disease.spreadtype))
- return
-
+ if(forced || (infection_check(M, disease.spreadtype) && prob(disease.infectionchance)))
var/datum/disease2/disease/D = disease.getcopy()
D.minormutate()
// log_debug("Adding virus")
M.virus2["[D.uniqueID]"] = D
M.hud_updateflag |= 1 << STATUS_HUD
+
//Infects mob M with disease D
/proc/infect_mob(var/mob/living/carbon/M, var/datum/disease2/disease/D)
infect_virus2(M,D,1)
@@ -126,12 +132,15 @@ proc/airborne_can_reach(turf/source, turf/target)
// log_debug("Attempting virus [ID]")
var/datum/disease2/disease/V = virus2[ID]
if(V.spreadtype != vector) continue
+
+ //It's hard to get other people sick if you're in an airtight suit.
+ if(!infection_spreading_check(src, V.spreadtype)) continue
if (vector == "Airborne")
if(airborne_can_reach(get_turf(src), get_turf(victim)))
// log_debug("In range, infecting")
infect_virus2(victim,V)
- else
+// else
// log_debug("Could not reach target")
if (vector == "Contact")
@@ -148,7 +157,7 @@ proc/airborne_can_reach(turf/source, turf/target)
var/mob/living/carbon/human/H = victim
var/datum/organ/external/select_area = H.get_organ(src.zone_sel.selecting)
var/list/clothes = list(H.head, H.wear_mask, H.wear_suit, H.w_uniform, H.gloves, H.shoes)
- for(var/obj/item/clothing/C in clothes )
+ for(var/obj/item/clothing/C in clothes)
if(C && istype(C))
if(C.body_parts_covered & select_area.body_part)
nudity = 0
@@ -156,4 +165,5 @@ proc/airborne_can_reach(turf/source, turf/target)
for (var/ID in victim.virus2)
var/datum/disease2/disease/V = victim.virus2[ID]
if(V && V.spreadtype != vector) continue
+ if(!infection_spreading_check(victim, V.spreadtype)) continue
infect_virus2(src,V)
diff --git a/maps/exodus-1.dmm b/maps/exodus-1.dmm
index efabf77e10e..363ec734335 100644
--- a/maps/exodus-1.dmm
+++ b/maps/exodus-1.dmm
@@ -878,7 +878,7 @@
"aqT" = (/turf/simulated/floor/plating/airless,/area/solar/fore)
"aqU" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/lawoffice)
"aqV" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/lawoffice)
-"aqW" = (/obj/structure/stool/bed/chair/office/dark,/obj/effect/landmark/start{name = "Internal Affairs Agent"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/junction,/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/lawoffice)
+"aqW" = (/obj/structure/stool/bed/chair/office/dark,/obj/effect/landmark/start{name = "Internal Affairs Agent"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/lawoffice)
"aqX" = (/obj/machinery/camera{c_tag = "Detective South"; dir = 1},/obj/machinery/computer/secure_data,/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office)
"aqY" = (/obj/structure/disposalpipe/segment,/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = -30},/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office)
"aqZ" = (/obj/structure/closet{name = "Evidence Closet"},/obj/item/weapon/storage/box/bodybags,/obj/item/weapon/storage/box/evidence,/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office)