diff --git a/baystation12.dme b/baystation12.dme
index a271554e66c..2518938c8c3 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -1175,6 +1175,7 @@
#include "code\modules\surgery\eye.dm"
#include "code\modules\surgery\face.dm"
#include "code\modules\surgery\generic.dm"
+#include "code\modules\surgery\implant.dm"
#include "code\modules\surgery\other.dm"
#include "code\modules\surgery\ribcage.dm"
#include "code\modules\surgery\robolimbs.dm"
diff --git a/code/WorkInProgress/Cib/MedicalSideEffects.dm b/code/WorkInProgress/Cib/MedicalSideEffects.dm
index e9dcb51e136..c886a8abe91 100644
--- a/code/WorkInProgress/Cib/MedicalSideEffects.dm
+++ b/code/WorkInProgress/Cib/MedicalSideEffects.dm
@@ -24,11 +24,17 @@
side_effects += M
/mob/living/carbon/human/proc/handle_medical_side_effects()
- if(src.reagents.has_reagent("cryoxadone"))
+ if(src.reagents.has_reagent("cryoxadone") || src.reagents.get_reagent_amount("bicaridine") >= 15 || src.reagents.get_reagent_amount("tricordrazine") >= 15)
src.add_side_effect("Headache")
- /*if(src.reagents.has_reagent("kelotane") && prob(20) || src.reagents.has_reagent("dermaline"))
- src.add_side_effect("Bad Stomach")*/
+ if(src.reagents.get_reagent_amount("kelotane") >= 30 || src.reagents.get_reagent_amount("dermaline") >= 15)
+ src.add_side_effect("Bad Stomach")
+
+ if(src.reagents.get_reagent_amount("tramadol") >= 16 || src.reagents.get_reagent_amount("anti_toxin") >= 30)
+ src.add_side_effect("Cramps")
+
+ if(src.reagents.get_reagent_amount("space_drugs") >= 10)
+ src.add_side_effect("Itch")
// One full cycle(in terms of strength) every 10 minutes
var/strength_percent = sin(life_tick / 2)
@@ -45,29 +51,6 @@
// Effect slowly growing stronger
M.strength+=0.08
-// HEADACHE
-// ========
-/datum/medical_effect/headache/name = "Headache"
-/datum/medical_effect/headache/on_life(mob/living/carbon/human/H, strength)
- switch(strength)
- if(1 to 10)
- H.custom_pain("You feel a light pain in your head.",0)
- if(11 to 30)
- H.custom_pain("You feel a throbbing pain in your head!",1)
- if(31 to 99)
- H.custom_pain("You feel an excrutiating pain in your head!",1)
- H.adjustBrainLoss(1)
- if(99 to INFINITY)
- H.custom_pain("It feels like your head is about to split open!",1)
- H.adjustBrainLoss(3)
- var/datum/organ/external/O = H.organs_by_name["head"]
- O.take_damage(0, 1, 0, "Headache")
-
-/datum/medical_effect/headache/cure(mob/living/carbon/human/H)
- if(H.reagents.has_reagent("alkysine"))
- return 1
- return 0
-
// HEADACHE
// ========
/datum/medical_effect/headache/name = "Headache"
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
index d0b8b90d6b5..566a587b8a0 100644
--- a/code/__HELPERS/global_lists.dm
+++ b/code/__HELPERS/global_lists.dm
@@ -66,6 +66,7 @@ var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Al
for(var/T in paths)
var/datum/surgery_step/S = new T
surgery_steps += S
+ sort_surgeries()
/* // Uncomment to debug chemical reaction list.
/client/verb/debug_chemical_list()
diff --git a/code/datums/organs/organ_external.dm b/code/datums/organs/organ_external.dm
index a90389dc214..7710fb6a4f7 100644
--- a/code/datums/organs/organ_external.dm
+++ b/code/datums/organs/organ_external.dm
@@ -31,6 +31,7 @@
var/status = 0
var/open = 0
var/stage = 0
+ var/cavity = 0
var/obj/item/hidden = null
var/list/implants = list()
@@ -239,25 +240,65 @@
// process wounds, doing healing etc., only do this every 4 ticks to save processing power
if(owner.life_tick % wound_update_accuracy == 0)
update_wounds()
+
+ //Dismemberment
if(status & ORGAN_DESTROYED)
if(!destspawn && config.limbs_can_break)
droplimb()
return
- if(!(status & ORGAN_BROKEN))
- perma_injury = 0
if(parent)
if(parent.status & ORGAN_DESTROYED)
status |= ORGAN_DESTROYED
owner.update_body(1)
return
+
+ //Bone fracurtes
if(config.bones_can_break && brute_dam > min_broken_damage * config.organ_health_multiplier && !(status & ORGAN_ROBOT))
src.fracture()
- if(germ_level > 0)
- for(var/datum/wound/W in wounds) if(!W.bandaged && !W.salved)
- W.germ_level = max(W.germ_level, germ_level)
+ if(!(status & ORGAN_BROKEN))
+ perma_injury = 0
+
+ update_germs()
update_icon()
return
+//Updating germ levels. Handles organ germ levels and necrosis.
+#define GANGREN_LEVEL_ONE 100
+#define GANGREN_LEVEL_TWO 1000
+#define GANGREN_LEVEL_TERMINAL 2500
+#define GERM_TRANSFER_AMOUNT germ_level/500
+/datum/organ/external/proc/update_germs()
+ if(germ_level > 0 && owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs
+ //Syncing germ levels with external wounds
+ for(var/datum/wound/W in wounds)
+ if(!W.bandaged && !W.salved)
+ W.germ_level = max(W.germ_level, germ_level) //Wounds get all the germs
+ if (W.germ_level > germ_level) //Badly infected wounds raise internal germ levels
+ germ_level++
+
+ if(germ_level > GANGREN_LEVEL_ONE && prob(round(germ_level/100)))
+ germ_level++
+ owner.adjustToxLoss(1)
+
+ if(germ_level > GANGREN_LEVEL_TWO)
+ germ_level++
+ owner.adjustToxLoss(1)
+/*
+ if(germ_level > GANGREN_LEVEL_TERMINAL)
+ if (!(status & ORGAN_DEAD))
+ status |= ORGAN_DEAD
+ owner << "You can't feel your [display_name] anymore..."
+ owner.update_body(1)
+ if (prob(10)) //Spreading the fun
+ if (children) //To child organs
+ for (var/datum/organ/external/child in children)
+ if (!(child.status & (ORGAN_DEAD|ORGAN_DESTROYED|ORGAN_ROBOT)))
+ child.germ_level += round(GERM_TRANSFER_AMOUNT)
+ if (parent)
+ if (!(parent.status & (ORGAN_DEAD|ORGAN_DESTROYED|ORGAN_ROBOT)))
+ parent.germ_level += round(GERM_TRANSFER_AMOUNT)
+*/
+
//Updating wounds. Handles wound natural healing, internal bleedings and infections
/datum/organ/external/proc/update_wounds()
for(var/datum/wound/W in wounds)
@@ -281,14 +322,12 @@
// amount of healing is spread over all the wounds
W.heal_damage((wound_update_accuracy * amount * W.amount * config.organ_regeneration_multiplier) / (20*owner.number_wounds+1))
- if(W.germ_level > 100 && prob(10))
- owner.adjustToxLoss(1 * wound_update_accuracy)
- if(W.germ_level > 1000)
- owner.adjustToxLoss(1 * wound_update_accuracy)
-
// Salving also helps against infection
if(W.germ_level > 0 && W.salved && prob(2))
W.germ_level = 0
+ W.disinfected = 1
+
+
// sync the organ's damage with its wounds
src.update_damages()
diff --git a/code/datums/organs/wound.dm b/code/datums/organs/wound.dm
index b90ddfca81a..90909a3f62d 100644
--- a/code/datums/organs/wound.dm
+++ b/code/datums/organs/wound.dm
@@ -96,6 +96,23 @@
else if(damage_type == BURN)
return salved
+ // checks if wound is considered open for external infections
+ // untreated cuts (and bleeding bruises) and burns are possibly infectable, chance higher if wound is bigger
+ proc/can_infect()
+ if (is_treated() && damage < 10)
+ return 0
+ if (disinfected)
+ return 0
+ var/dam_coef = round(damage/10)
+ switch (damage_type)
+ if (BRUISE)
+ return prob(dam_coef*5) && bleeding() //bruises only infectable if bleeding
+ if (BURN)
+ return prob(dam_coef*10)
+ if (CUT)
+ return prob(dam_coef*20)
+
+ return 0
// heal the given amount of damage, and if the given amount of damage was more
// than what needed to be healed, return how much heal was left
// set @heals_internal to also heal internal organ damage
diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm
index 1a78d4be758..4b095488f9d 100644
--- a/code/game/machinery/cryo.dm
+++ b/code/game/machinery/cryo.dm
@@ -10,7 +10,6 @@
var/temperature_archived
var/mob/living/carbon/occupant = null
var/beaker = null
- var/next_trans = 0
var/current_heat_capacity = 50
@@ -164,12 +163,12 @@
var/heal_brute = occupant.getBruteLoss() ? min(1, 20/occupant.getBruteLoss()) : 0
var/heal_fire = occupant.getFireLoss() ? min(1, 20/occupant.getFireLoss()) : 0
occupant.heal_organ_damage(heal_brute,heal_fire)
- if(beaker && (next_trans == 0))
+ var/has_cryo = occupant.reagents.get_reagent_amount("cryoxadone") >= 1
+ var/has_clonexa = occupant.reagents.get_reagent_amount("clonexadone") >= 1
+ var/has_cryo_medicine = has_cryo || has_clonexa
+ if(beaker && !has_cryo_medicine)
beaker:reagents.trans_to(occupant, 1, 10)
beaker:reagents.reaction(occupant)
- next_trans++
- if(next_trans == 10)
- next_trans = 0
/obj/machinery/atmospherics/unary/cryo_cell/proc/heat_gas_contents()
if(air_contents.total_moles() < 1)
diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm
index c123ebde2bb..903bb1b1bf9 100644
--- a/code/game/objects/items/weapons/implants/implant.dm
+++ b/code/game/objects/items/weapons/implants/implant.dm
@@ -180,33 +180,39 @@ Implant Specifics:
"}
switch (severity)
if (2.0) //Weak EMP will make implant tear limbs off.
if (prob(50))
- if (ishuman(imp_in) && part)
- imp_in.visible_message("\red Something beeps inside [imp_in][part ? "'s [part.display_name]" : ""]!")
- playsound(loc, 'sound/items/countdown.ogg', 75, 1, -3)
- spawn(25)
- if (ishuman(imp_in) && part)
- //No tearing off these parts since it's pretty much killing
- //and you can't replace groins
- if (istype(part,/datum/organ/external/chest) || \
- istype(part,/datum/organ/external/groin) || \
- istype(part,/datum/organ/external/head))
- part.createwound(BRUISE, 60) //mangle them instead
- else
- part.droplimb(1)
- explosion(get_turf(imp_in), -1, -1, 2, 3, 3)
- del(src)
-
+ small_boom()
if (1.0) //strong EMP will melt implant either making it go off, or disarming it
- if (prob(50))
- activate() //50% chance of bye bye
- else
- meltdown() //50% chance of implant disarming
+ if (prob(70))
+ if (prob(50))
+ small_boom()
+ else
+ if (prob(50))
+ activate() //50% chance of bye bye
+ else
+ meltdown() //50% chance of implant disarming
spawn (20)
malfunction--
islegal()
return 0
+ proc/small_boom()
+ if (ishuman(imp_in) && part)
+ imp_in.visible_message("\red Something beeps inside [imp_in][part ? "'s [part.display_name]" : ""]!")
+ playsound(loc, 'sound/items/countdown.ogg', 75, 1, -3)
+ spawn(25)
+ if (ishuman(imp_in) && part)
+ //No tearing off these parts since it's pretty much killing
+ //and you can't replace groins
+ if (istype(part,/datum/organ/external/chest) || \
+ istype(part,/datum/organ/external/groin) || \
+ istype(part,/datum/organ/external/head))
+ part.createwound(BRUISE, 60) //mangle them instead
+ else
+ part.droplimb(1)
+ explosion(get_turf(imp_in), -1, -1, 2, 3, 3)
+ del(src)
+
/obj/item/weapon/implant/chem
name = "chem"
desc = "Injects things."
diff --git a/code/modules/events/infestation.dm b/code/modules/events/infestation.dm
index d9505e3b53e..31f4ecdc19c 100644
--- a/code/modules/events/infestation.dm
+++ b/code/modules/events/infestation.dm
@@ -70,29 +70,37 @@
turfs += F
var/list/spawn_types = list()
+ var/max_number
vermin = rand(0,2)
switch(vermin)
if(VERM_MICE)
spawn_types = list(/mob/living/simple_animal/mouse/gray, /mob/living/simple_animal/mouse/brown, /mob/living/simple_animal/mouse/white)
+ max_number = 12
vermstring = "mice"
if(VERM_LIZARDS)
spawn_types = list(/mob/living/simple_animal/lizard)
+ max_number = 6
vermstring = "lizards"
if(VERM_SPIDERS)
spawn_types = list(/obj/effect/spider/spiderling)
vermstring = "spiders"
+
spawn(0)
- var/num = rand(1, 3)
+ var/num = rand(2,max_number)
while(turfs.len > 0 && num > 0)
var/turf/simulated/floor/T = pick(turfs)
turfs.Remove(T)
num--
+
+
if(vermin == VERM_SPIDERS)
var/obj/effect/spider/spiderling/S = new(T)
S.amount_grown = -1
else
var/spawn_type = pick(spawn_types)
new spawn_type(T)
+
+
/datum/event/infestation/announce()
command_alert("Bioscans indicate that [vermstring] have been breeding in [locstring]. Clear them out, before this starts to affect productivity.", "Vermin infestation")
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 491a457e648..1adee6f3054 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -919,4 +919,33 @@
src.custom_pain("You feel a stabbing pain in your chest!", 1)
E.ruptured_lungs = 1
+/*
+/mob/living/carbon/human/verb/simulate()
+ set name = "sim"
+ set background = 1
+ var/damage = input("Wound damage","Wound damage") as num
+
+ var/germs = 0
+ var/tdamage = 0
+ var/ticks = 0
+ while (germs < 2501 && ticks < 100000 && round(damage/10)*20)
+ diary << "VIRUS TESTING: [ticks] : germs [germs] tdamage [tdamage] prob [round(damage/10)*20]"
+ ticks++
+ if (prob(round(damage/10)*20))
+ germs++
+ if (germs == 100)
+ world << "Reached stage 1 in [ticks] ticks"
+ if (germs > 100)
+ if (prob(10))
+ damage++
+ germs++
+ if (germs == 1000)
+ world << "Reached stage 2 in [ticks] ticks"
+ if (germs > 1000)
+ damage++
+ germs++
+ if (germs == 2500)
+ world << "Reached stage 3 in [ticks] ticks"
+ world << "Mob took [tdamage] tox damage"
+*/
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 478416aae1c..88b96a13deb 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -222,6 +222,7 @@ proc/get_damage_icon_part(damage_state, body_part)
var/husk_color_mod = rgb(96,88,80)
var/hulk_color_mod = rgb(48,224,40)
var/plant_color_mod = rgb(144,224,144)
+ var/necrosis_color_mod = rgb(10,50,0)
var/husk = (HUSK in src.mutations) //100% unnecessary -Agouri //nope, do you really want to iterate through src.mutations repeatedly? -Pete
var/fat = (FAT in src.mutations)
@@ -283,6 +284,9 @@ proc/get_damage_icon_part(damage_state, body_part)
temp = new /icon(icobase, "[part.icon_name]")
if(part.status & ORGAN_ROBOT)
temp.GrayScale()
+ if(part.status & ORGAN_DEAD)
+ temp.ColorTone(necrosis_color_mod)
+ temp.SetIntensity(0.7)
else if(!skeleton)
if(husk)
temp.ColorTone(husk_color_mod)
diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm
index 3e014582c94..f327da094f4 100644
--- a/code/modules/reagents/Chemistry-Reagents.dm
+++ b/code/modules/reagents/Chemistry-Reagents.dm
@@ -19,6 +19,8 @@ datum
var/list/data = null
var/volume = 0
var/nutriment_factor = 0
+ var/custom_metabolism = REAGENTS_METABOLISM
+ var/mildly_toxic = 0
//var/list/viruses = list()
var/color = "#000000" // rgb: 0, 0, 0 (does not support alpha channels - yet!)
@@ -68,7 +70,14 @@ datum
on_mob_life(var/mob/living/M as mob)
if(!istype(M, /mob/living))
return //Noticed runtime errors from pacid trying to damage ghosts, this should fix. --NEO
- holder.remove_reagent(src.id, REAGENTS_METABOLISM) //By default it slowly disappears.
+ // Certain elements in too large amounts cause side-effects
+
+ if(mildly_toxic && istype(M, /mob/living/carbon/human/))
+ var/mob/living/carbon/human/H = M
+ if(H.side_effects.len == 0)
+ M.add_side_effect(pick("Headache", "Bad Stomach", "Itch"))
+
+ holder.remove_reagent(src.id, custom_metabolism) //By default it slowly disappears.
return
on_move(var/mob/M)
@@ -199,6 +208,7 @@ datum
description = "A ubiquitous chemical substance that is composed of hydrogen and oxygen."
reagent_state = LIQUID
color = "#0064C8" // rgb: 0, 100, 200
+ custom_metabolism = 0.01
reaction_turf(var/turf/simulated/T, var/volume)
if (!istype(T)) return
@@ -309,24 +319,28 @@ datum
description = "A Toxic chemical."
reagent_state = LIQUID
color = "#CF3600" // rgb: 207, 54, 0
+ custom_metabolism = 0.01
on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
- M.adjustToxLoss(1.5*REM)
+ // Toxins are really weak, but without being treated, last very long.
+ M.adjustToxLoss(0.2)
..()
return
cyanide
+ // Fast and lethal
name = "Cyanide"
id = "cyanide"
description = "A highly toxic chemical."
reagent_state = LIQUID
color = "#CF3600" // rgb: 207, 54, 0
+ custom_metabolism = 0.4
on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
- M.adjustToxLoss(3*REM)
- M.adjustOxyLoss(3*REM)
+ M.adjustToxLoss(4)
+ M.adjustOxyLoss(4)
M.sleeping += 1
..()
return
@@ -405,6 +419,8 @@ datum
reagent_state = LIQUID
color = "#E895CC" // rgb: 232, 149, 204
+ custom_metabolism = 0.1
+
on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
if(!data) data = 1
@@ -540,12 +556,17 @@ datum
reagent_state = GAS
color = "#808080" // rgb: 128, 128, 128
+ custom_metabolism = 0.01
+
copper
name = "Copper"
id = "copper"
description = "A highly ductile metal."
color = "#6E3B08" // rgb: 110, 59, 8
+ mildly_toxic = 1
+ custom_metabolism = 0.01
+
nitrogen
name = "Nitrogen"
id = "nitrogen"
@@ -553,6 +574,9 @@ datum
reagent_state = GAS
color = "#808080" // rgb: 128, 128, 128
+ mildly_toxic = 1
+ custom_metabolism = 0.01
+
hydrogen
name = "Hydrogen"
id = "hydrogen"
@@ -560,6 +584,9 @@ datum
reagent_state = GAS
color = "#808080" // rgb: 128, 128, 128
+ mildly_toxic = 1
+ custom_metabolism = 0.01
+
potassium
name = "Potassium"
id = "potassium"
@@ -567,6 +594,10 @@ datum
reagent_state = SOLID
color = "#A0A0A0" // rgb: 160, 160, 160
+
+ mildly_toxic = 1
+ custom_metabolism = 0.01
+
mercury
name = "Mercury"
id = "mercury"
@@ -589,6 +620,9 @@ datum
reagent_state = SOLID
color = "#BF8C00" // rgb: 191, 140, 0
+ mildly_toxic = 1
+ custom_metabolism = 0.01
+
carbon
name = "Carbon"
id = "carbon"
@@ -596,6 +630,9 @@ datum
reagent_state = SOLID
color = "#1C1300" // rgb: 30, 20, 0
+ mildly_toxic = 1
+ custom_metabolism = 0.01
+
reaction_turf(var/turf/T, var/volume)
src = null
if(!istype(T, /turf/space))
@@ -634,6 +671,9 @@ datum
reagent_state = SOLID
color = "#808080" // rgb: 128, 128, 128
+ mildly_toxic = 1
+ custom_metabolism = 0.01
+
phosphorus
name = "Phosphorus"
id = "phosphorus"
@@ -641,6 +681,9 @@ datum
reagent_state = SOLID
color = "#832828" // rgb: 131, 40, 40
+ mildly_toxic = 1
+ custom_metabolism = 0.01
+
lithium
name = "Lithium"
id = "lithium"
@@ -826,6 +869,9 @@ datum
reagent_state = LIQUID
color = "#808080" // rgb: 128, 128, 128
+ mildly_toxic = 1
+ custom_metabolism = 0.01
+
nitroglycerin
name = "Nitroglycerin"
id = "nitroglycerin"
@@ -833,6 +879,9 @@ datum
reagent_state = LIQUID
color = "#808080" // rgb: 128, 128, 128
+ mildly_toxic = 1
+ custom_metabolism = 0.01
+
radium
name = "Radium"
id = "radium"
@@ -1403,6 +1452,7 @@ datum
description = "Synaptizine is used to treat various diseases."
reagent_state = LIQUID
color = "#C8A5DC" // rgb: 200, 165, 220
+ custom_metabolism = 0.01
on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
@@ -1440,6 +1490,7 @@ datum
description = "Hyronalin is a medicinal drug used to counter the effect of radiation poisoning."
reagent_state = LIQUID
color = "#C8A5DC" // rgb: 200, 165, 220
+ custom_metabolism = 0.05
on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
@@ -1453,6 +1504,7 @@ datum
description = "Arithrazine is an unstable medication used for the most extreme cases of radiation poisoning."
reagent_state = LIQUID
color = "#C8A5DC" // rgb: 200, 165, 220
+ custom_metabolism = 0.05
on_mob_life(var/mob/living/M as mob)
if(M.stat == 2.0)
@@ -1471,6 +1523,7 @@ datum
description = "Alkysine is a drug used to lessen the damage to neurological tissue after a catastrophic injury. Can heal brain tissue."
reagent_state = LIQUID
color = "#C8A5DC" // rgb: 200, 165, 220
+ custom_metabolism = 0.05
on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
@@ -1516,11 +1569,11 @@ datum
description = "Hyperzine is a highly effective, long lasting, muscle stimulant."
reagent_state = LIQUID
color = "#C8A5DC" // rgb: 200, 165, 220
+ custom_metabolism = 0.03
on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
if(prob(5)) M.emote(pick("twitch","blink_r","shiver"))
- holder.remove_reagent(src.id, 0.5 * REAGENTS_METABOLISM)
..()
return
@@ -1535,9 +1588,9 @@ datum
if(!M) M = holder.my_atom
if(M.bodytemperature < 170)
M.adjustCloneLoss(-1)
- M.adjustOxyLoss(-3)
- M.heal_organ_damage(3,3)
- M.adjustToxLoss(-3)
+ M.adjustOxyLoss(-1)
+ M.heal_organ_damage(1,1)
+ M.adjustToxLoss(-1)
..()
return
@@ -1564,9 +1617,9 @@ datum
description = "An all-purpose antiviral agent."
reagent_state = LIQUID
color = "#C8A5DC" // rgb: 200, 165, 220
+ custom_metabolism = 0.01
- on_mob_life(var/mob/living/M as mob)//no more mr. panacea
- holder.remove_reagent(src.id, 0.2)
+ on_mob_life(var/mob/living/M as mob)
..()
return
@@ -1612,6 +1665,7 @@ datum
description = "A powerful hallucinogen. Not a thing to be messed with."
reagent_state = LIQUID
color = "#B31008" // rgb: 139, 166, 233
+ custom_metabolism = 0.05
on_mob_life(var/mob/living/M)
if(!M) M = holder.my_atom
diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm
index 9ffa4baa561..0e8e6f0ace4 100644
--- a/code/modules/reagents/reagent_containers/pill.dm
+++ b/code/modules/reagents/reagent_containers/pill.dm
@@ -84,7 +84,7 @@
icon_state = "pill17"
New()
..()
- reagents.add_reagent("anti_toxin", 50)
+ reagents.add_reagent("anti_toxin", 25)
/obj/item/weapon/reagent_containers/pill/tox
name = "Toxins pill"
@@ -175,4 +175,4 @@
..()
reagents.add_reagent("impedrezene", 10)
reagents.add_reagent("synaptizine", 5)
- reagents.add_reagent("hyperzine", 5)
+ reagents.add_reagent("hyperzine", 5)
diff --git a/code/modules/surgery/appendix.dm b/code/modules/surgery/appendix.dm
index 9443b7aca34..027e323c576 100644
--- a/code/modules/surgery/appendix.dm
+++ b/code/modules/surgery/appendix.dm
@@ -4,6 +4,7 @@
//////////////////////////////////////////////////////////////////
/datum/surgery_step/appendectomy/
+ priority = 2
can_infect = 1
blood_level = 1
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm
index 95d173acbe6..e0eaab854ff 100644
--- a/code/modules/surgery/bones.dm
+++ b/code/modules/surgery/bones.dm
@@ -4,6 +4,7 @@
//////////////////////////////////////////////////////////////////
/datum/surgery_step/glue_bone
+ priority = 2
required_tool = /obj/item/weapon/bonegel
allowed_tools = list(/obj/item/weapon/screwdriver)
can_infect = 1
diff --git a/code/modules/surgery/braincore.dm b/code/modules/surgery/braincore.dm
index e809f3cb954..d08d6d98784 100644
--- a/code/modules/surgery/braincore.dm
+++ b/code/modules/surgery/braincore.dm
@@ -4,6 +4,7 @@
//////////////////////////////////////////////////////////////////
/datum/surgery_step/brain/
+ priority = 2
blood_level = 1
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
return target_zone == "head" && hasorgans(target)
diff --git a/code/modules/surgery/eye.dm b/code/modules/surgery/eye.dm
index 224afc5af83..8f100aee173 100644
--- a/code/modules/surgery/eye.dm
+++ b/code/modules/surgery/eye.dm
@@ -4,6 +4,7 @@
//////////////////////////////////////////////////////////////////
/datum/surgery_step/eye
+ priority = 2
can_infect = 1
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if (!hasorgans(target))
diff --git a/code/modules/surgery/face.dm b/code/modules/surgery/face.dm
index 2e6e0c65d05..90ce1d81349 100644
--- a/code/modules/surgery/face.dm
+++ b/code/modules/surgery/face.dm
@@ -4,6 +4,7 @@
//////////////////////////////////////////////////////////////////
/datum/surgery_step/face
+ priority = 2
can_infect = 0
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if (!hasorgans(target))
diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm
new file mode 100644
index 00000000000..1a64f37cf2b
--- /dev/null
+++ b/code/modules/surgery/implant.dm
@@ -0,0 +1,200 @@
+//Procedures in this file: Putting items in body cavity. Implant removal. Items removal.
+
+//////////////////////////////////////////////////////////////////
+// ITEM PLACEMENT SURGERY //
+//////////////////////////////////////////////////////////////////
+
+/datum/surgery_step/cavity
+ priority = 1
+ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ return affected.open == 2 && !(affected.status & ORGAN_BLEEDING) && (target_zone != "chest" || target.op_stage.ribcage == 2)
+
+ proc/get_max_wclass(datum/organ/external/affected)
+ switch (affected.name)
+ if ("head")
+ return 1
+ if ("chest")
+ return 3
+ if ("groin")
+ return 2
+ return 0
+
+ proc/get_cavity(datum/organ/external/affected)
+ switch (affected.name)
+ if ("head")
+ return "cranial"
+ if ("chest")
+ return "thoracic"
+ if ("groin")
+ return "abdominal"
+ return ""
+
+/datum/surgery_step/cavity/make_space
+ required_tool = /obj/item/weapon/surgicaldrill
+ allowed_tools = list(/obj/item/weapon/pen,/obj/item/stack/rods)
+
+ min_duration = 60
+ max_duration = 80
+
+ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ return ..() && !affected.cavity && !affected.hidden
+
+ begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ user.visible_message("[user] starts making some space inside [target]'s [get_cavity(affected)] cavity with \the [tool].", \
+ "You start making some space inside [target]'s [get_cavity(affected)] cavity with \the [tool]." )
+ target.custom_pain("The pain in your chest is living hell!",1)
+ affected.cavity = 1
+ ..()
+
+ end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/datum/organ/external/chest/affected = target.get_organ(target_zone)
+ user.visible_message("\blue [user] makes some space inside [target]'s [get_cavity(affected)] cavity with \the [tool].", \
+ "\blue You make some space inside [target]'s [get_cavity(affected)] cavity with \the [tool]." )
+
+ fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/datum/organ/external/chest/affected = target.get_organ(target_zone)
+ user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!", \
+ "\red Your hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!")
+ affected.createwound(CUT, 20)
+
+/datum/surgery_step/cavity/close_space
+ priority = 2
+ required_tool = /obj/item/weapon/cautery
+ allowed_tools = list(/obj/item/weapon/weldingtool, /obj/item/clothing/mask/cigarette, /obj/item/weapon/lighter)
+
+ min_duration = 60
+ max_duration = 80
+
+ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ return ..() && affected.cavity
+
+ begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ user.visible_message("[user] starts mending [target]'s [get_cavity(affected)] cavity wall with \the [tool].", \
+ "You start mending [target]'s [get_cavity(affected)] cavity wall with \the [tool]." )
+ target.custom_pain("The pain in your chest is living hell!",1)
+ affected.cavity = 0
+ ..()
+
+ end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/datum/organ/external/chest/affected = target.get_organ(target_zone)
+ user.visible_message("\blue [user] mends [target]'s [get_cavity(affected)] cavity walls with \the [tool].", \
+ "\blue You mend [target]'s [get_cavity(affected)] cavity walls with \the [tool]." )
+
+ fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/datum/organ/external/chest/affected = target.get_organ(target_zone)
+ user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!", \
+ "\red Your hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!")
+ affected.createwound(CUT, 20)
+
+/datum/surgery_step/cavity/place_item
+ priority = 0
+ required_tool = /obj/item
+
+ min_duration = 80
+ max_duration = 100
+
+ can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ var/can_fit = !affected.hidden && affected.cavity && tool.w_class <= get_max_wclass(affected)
+ return ..() && can_fit
+
+ begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ user.visible_message("[user] starts putting \the [tool] inside [target]'s [get_cavity(affected)] cavity.", \
+ "You start putting \the [tool] inside [target]'s [get_cavity(affected)] cavity." )
+ target.custom_pain("The pain in your chest is living hell!",1)
+ ..()
+
+ end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/datum/organ/external/chest/affected = target.get_organ(target_zone)
+
+ user.visible_message("\blue [user] puts \the [tool] inside [target]'s [get_cavity(affected)] cavity.", \
+ "\blue You put \the [tool] inside [target]'s [get_cavity(affected)] cavity." )
+ if (tool.w_class > get_max_wclass(affected)/2 && prob(50))
+ user << "\red You tear some vessels trying to fit such big object in this cavity."
+ var/datum/wound/internal_bleeding/I = new (15)
+ affected.wounds += I
+ affected.owner.custom_pain("You feel something rip in your [affected.display_name]!", 1)
+ user.drop_item()
+ affected.hidden = tool
+ tool.loc = target
+ affected.cavity = 0
+
+ fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/datum/organ/external/chest/affected = target.get_organ(target_zone)
+ user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!", \
+ "\red Your hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!")
+ affected.createwound(CUT, 20)
+
+//////////////////////////////////////////////////////////////////
+// IMPLANT/ITEM REMOVAL SURGERY //
+//////////////////////////////////////////////////////////////////
+
+/datum/surgery_step/cavity/implant_removal
+ required_tool = /obj/item/weapon/hemostat
+ allowed_tools = list(/obj/item/weapon/wirecutters, /obj/item/weapon/kitchen/utensil/fork)
+
+ min_duration = 80
+ max_duration = 100
+
+ begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ user.visible_message("[user] starts poking around inside the incision on [target]'s [affected.display_name] with \the [tool].", \
+ "You start poking around inside the incision on [target]'s [affected.display_name] with \the [tool]" )
+ target.custom_pain("The pain in your chest is living hell!",1)
+ ..()
+
+ end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/datum/organ/external/chest/affected = target.get_organ(target_zone)
+
+ var/find_prob = 0
+ if (affected.implants.len)
+ var/obj/item/weapon/implant/imp = affected.implants[1]
+ if (imp.islegal())
+ find_prob +=60
+ else
+ find_prob +=40
+ if (isright(tool))
+ find_prob +=20
+ if (prob(find_prob))
+ user.visible_message("\blue [user] takes something out of incision on [target]'s [affected.display_name] with \the [tool].", \
+ "\blue You take something out of incision on [target]'s [affected.display_name]s with \the [tool]." )
+ affected.implants -= imp
+ imp.loc = get_turf(target)
+ imp.imp_in = null
+ imp.implanted = 0
+ else if (affected.hidden)
+ user.visible_message("\blue [user] takes something out of incision on [target]'s [affected.display_name] with \the [tool].", \
+ "\blue You take something out of incision on [target]'s [affected.display_name]s with \the [tool]." )
+ affected.hidden.loc = get_turf(target)
+ if(!affected.hidden.blood_DNA)
+ affected.hidden.blood_DNA = list()
+ affected.hidden.blood_DNA[target.dna.unique_enzymes] = target.dna.b_type
+ affected.hidden.update_icon()
+ affected.hidden = null
+
+ else
+ user.visible_message("\blue [user] could not find anything inside [target]'s [affected.display_name], and pulls \the [tool] out.", \
+ "\blue You could not find anything inside [target]'s [affected.display_name]." )
+
+ fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ var/datum/organ/external/chest/affected = target.get_organ(target_zone)
+ user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!", \
+ "\red Your hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!")
+ affected.createwound(CUT, 20)
+ if (affected.implants.len)
+ var/fail_prob = 10
+ if (!isright(tool))
+ fail_prob += 30
+ if (prob(fail_prob))
+ var/obj/item/weapon/implant/imp = affected.implants[1]
+ user.visible_message("\red Something beeps inside [target]'s [affected.display_name]!")
+ playsound(imp.loc, 'sound/items/countdown.ogg', 75, 1, -3)
+ spawn(25)
+ imp.activate()
+
diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm
index 3c3dd477b40..d75bb538f3d 100644
--- a/code/modules/surgery/other.dm
+++ b/code/modules/surgery/other.dm
@@ -5,6 +5,7 @@
/datum/surgery_step/fix_vein
+ priority = 2
required_tool = /obj/item/weapon/FixOVein
allowed_tools = list(/obj/item/weapon/cable_coil)
can_infect = 1
@@ -45,120 +46,3 @@
user.visible_message("\red [user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.display_name]!" , \
"\red Your hand slips, smearing [tool] in the incision in [target]'s [affected.display_name]!")
affected.take_damage(5, 0)
-
-//////////////////////////////////////////////////////////////////
-// IMPLANT REMOVAL SURGERY //
-//////////////////////////////////////////////////////////////////
-
-/datum/surgery_step/implant_removal
- required_tool = /obj/item/weapon/hemostat
- allowed_tools = list(/obj/item/weapon/wirecutters, /obj/item/weapon/kitchen/utensil/fork)
-
- min_duration = 80
- max_duration = 100
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- return affected.open == 2 && !(affected.status & ORGAN_BLEEDING)
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("[user] starts poking around inside the incision on [target]'s [affected.display_name] with \the [tool].", \
- "You start poking around inside the incision on [target]'s [affected.display_name] with \the [tool]" )
- target.custom_pain("The pain in your chest is living hell!",1)
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/chest/affected = target.get_organ(target_zone)
-
- var/find_prob = 0
- if (affected.implants.len)
- var/obj/item/weapon/implant/imp = affected.implants[1]
- if (imp.islegal())
- find_prob +=60
- else
- find_prob +=40
- if (isright(tool))
- find_prob +=20
- if (prob(find_prob))
- user.visible_message("\blue [user] takes something out of incision on [target]'s [affected.display_name] with \the [tool].", \
- "\blue You take something out of incision on [target]'s [affected.display_name]s with \the [tool]." )
- affected.implants -= imp
- imp.loc = get_turf(target)
- imp.imp_in = null
- imp.implanted = 0
- else if (affected.hidden)
- user.visible_message("\blue [user] takes something out of incision on [target]'s [affected.display_name] with \the [tool].", \
- "\blue You take something out of incision on [target]'s [affected.display_name]s with \the [tool]." )
- affected.hidden.loc = get_turf(target)
- if(!affected.hidden.blood_DNA)
- affected.hidden.blood_DNA = list()
- affected.hidden.blood_DNA[target.dna.unique_enzymes] = target.dna.b_type
- affected.hidden.update_icon()
- affected.hidden = null
-
- else
- user.visible_message("\blue [user] could not find anything inside [target]'s [affected.display_name], and pulls \the [tool] out.", \
- "\blue You could not find anything inside [target]'s [affected.display_name]." )
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/chest/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!", \
- "\red Your hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!")
- affected.createwound(CUT, 20)
- if (affected.implants.len)
- var/fail_prob = 10
- if (!isright(tool))
- fail_prob += 30
- if (prob(fail_prob))
- var/obj/item/weapon/implant/imp = affected.implants[1]
- user.visible_message("\red Something beeps inside [target]'s [affected.display_name]!")
- playsound(imp.loc, 'sound/items/countdown.ogg', 75, 1, -3)
- spawn(25)
- imp.activate()
-
-//////////////////////////////////////////////////////////////////
-// ITEM PLACEMENT SURGERY //
-//////////////////////////////////////////////////////////////////
-
-/datum/surgery_step/item_place
- required_tool = /obj/item
-
- min_duration = 80
- max_duration = 100
- var/max_size = 2 //maximum w_class of item that fits.
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- if (affected.name in list("chest","groin","head"))
- max_size = 3
- else
- max_size = 2
- return affected.open == 2 && !(affected.status & ORGAN_BLEEDING) && tool.w_class <= max_size && !affected.hidden
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("[user] starts putting [tool] inside the incision on [target]'s [affected.display_name].", \
- "You start putting [tool] inside the incision on [target]'s [affected.display_name]." )
- target.custom_pain("The pain in your chest is living hell!",1)
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/chest/affected = target.get_organ(target_zone)
-
- user.visible_message("\blue [user] puts [tool] inside [target]'s [affected.display_name].", \
- "\blue You put [tool] inside [target]'s [affected.display_name]." )
- if (tool.w_class > max_size/2 && prob(50))
- user << "\red You tear some vessels trying to fit such big object in this cavity."
- var/datum/wound/internal_bleeding/I = new (15)
- affected.wounds += I
- affected.owner.custom_pain("You feel something rip in your [affected.display_name]!", 1)
- user.drop_item()
- affected.hidden = tool
- tool.loc = target
-
- fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/chest/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!", \
- "\red Your hand slips, scraping tissue inside [target]'s [affected.display_name] with \the [tool]!")
- affected.createwound(CUT, 20)
diff --git a/code/modules/surgery/ribcage.dm b/code/modules/surgery/ribcage.dm
index 04c09cd02ed..de5325f9821 100644
--- a/code/modules/surgery/ribcage.dm
+++ b/code/modules/surgery/ribcage.dm
@@ -3,6 +3,7 @@
// GENERIC RIBCAGE SURGERY //
//////////////////////////////////////////////////////////////////
/datum/surgery_step/ribcage
+ priority = 2
can_infect = 1
blood_level = 1
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
@@ -195,4 +196,4 @@
var/datum/organ/external/chest/affected = target.get_organ("chest")
user.visible_message("\red [user]'s hand slips, slicing an artery inside [target]'s chest with \the [tool]!", \
"\red Your hand slips, slicing an artery inside [target]'s chest with \the [tool]!")
- affected.createwound(CUT, 20)
\ No newline at end of file
+ affected.createwound(CUT, 20)
diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm
index 0b2919214da..62b9afb52c0 100644
--- a/code/modules/surgery/surgery.dm
+++ b/code/modules/surgery/surgery.dm
@@ -1,6 +1,7 @@
/* SURGERY STEPS */
/datum/surgery_step
+ var/priority = 0 //steps with higher priority would be attempted first
// type path referencing the required tool for this step
var/required_tool = null
@@ -78,6 +79,22 @@ proc/do_surgery(mob/living/M, mob/living/user, obj/item/tool)
return 1 //don't want to do weapony things after surgery
return 0
+proc/sort_surgeries()
+ var/gap = surgery_steps.len
+ var/swapped = 1
+ while (gap > 1 || swapped)
+ swapped = 0
+ if(gap > 1)
+ gap = round(gap / 1.247330950103979)
+ if(gap < 1)
+ gap = 1
+ for(var/i = 1; gap + i <= surgery_steps.len; i++)
+ var/datum/surgery_step/l = surgery_steps[i] //Fucking hate
+ var/datum/surgery_step/r = surgery_steps[gap+i] //how lists work here
+ if(l.priority < r.priority)
+ surgery_steps.Swap(i, gap + i)
+ swapped = 1
+
/datum/surgery_status/
var/eyes = 0
var/face = 0
diff --git a/code/setup.dm b/code/setup.dm
index 33202de26f0..1812f920119 100644
--- a/code/setup.dm
+++ b/code/setup.dm
@@ -74,7 +74,7 @@
#define HUNGER_FACTOR 0.05
// How many units of reagent are consumed per tick, by default.
-#define REAGENTS_METABOLISM 0.4
+#define REAGENTS_METABOLISM 0.2
// By defining the effect multiplier this way, it'll exactly adjust
// all effects according to how they originally were with the 0.4 metabolism
@@ -580,6 +580,7 @@ var/list/TAGGERLOCATIONS = list("Disposals",
#define ORGAN_ROBOT 128
#define ORGAN_SPLINTED 256
#define SALVED 512
+#define ORGAN_DEAD 1024
#define ROUNDSTART_LOGOUT_REPORT_TIME 6000 //Amount of time (in deciseconds) after the rounds starts, that the player disconnect report is issued.
diff --git a/html/changelog.html b/html/changelog.html
index 9559cb76328..2071172483a 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -58,6 +58,14 @@ Stuff which is in development and not yet visible to players or just code relate
should be listed in the changelog upon commit though. Thanks. -->
+