diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index 1cc90d4f29..77cbcb7536 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -60,8 +60,19 @@
#define BRAIN_TRAUMA_SEVERE /datum/brain_trauma/severe
#define BRAIN_TRAUMA_SPECIAL /datum/brain_trauma/special
+#define TRAUMA_RESILIENCE_BASIC 1 //Curable with chems
+#define TRAUMA_RESILIENCE_SURGERY 2 //Curable with brain surgery
+#define TRAUMA_RESILIENCE_LOBOTOMY 3 //Curable with lobotomy
+#define TRAUMA_RESILIENCE_MAGIC 4 //Curable only with magic
+#define TRAUMA_RESILIENCE_ABSOLUTE 5 //This is here to stay
+
#define BRAIN_DAMAGE_INTEGRITY_MULTIPLIER 0.5
+//Surgery Defines
+#define BIOWARE_GENERIC "generic"
+#define BIOWARE_NERVES "nerves"
+#define BIOWARE_CIRCULATION "circulation"
+
//Health hud screws for carbon mobs
#define SCREWYHUD_NONE 0
#define SCREWYHUD_CRIT 1
diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm
index 8c2791670c..5a9b8181af 100644
--- a/code/__DEFINES/role_preferences.dm
+++ b/code/__DEFINES/role_preferences.dm
@@ -26,7 +26,8 @@
#define ROLE_SERVANT_OF_RATVAR "servant of Ratvar"
#define ROLE_BORER "borer"
#define ROLE_BROTHER "blood brother"
-#define ROLE_MISCREANT "miscreant"
+#define ROLE_BRAINWASHED "brainwashed victim"
+#define ROLE_MISCREANT "miscreant"
//Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR.
//The gamemode specific ones are just so the gamemodes can query whether a player is old enough
diff --git a/code/datums/brain_damage/brain_trauma.dm b/code/datums/brain_damage/brain_trauma.dm
index 53b0fbe056..508dccef4a 100644
--- a/code/datums/brain_damage/brain_trauma.dm
+++ b/code/datums/brain_damage/brain_trauma.dm
@@ -10,12 +10,13 @@
var/gain_text = "You feel traumatized."
var/lose_text = "You no longer feel traumatized."
var/can_gain = TRUE //can this be gained through random traumas?
- var/permanent = FALSE //can this be cured?
+ var/resilience = TRAUMA_RESILIENCE_BASIC //how hard is this to cure?
-/datum/brain_trauma/New(obj/item/organ/brain/B, _permanent)
+/datum/brain_trauma/New(obj/item/organ/brain/B, _resilience)
brain = B
owner = B.owner
- permanent = _permanent
+ if(_resilience)
+ resilience = _resilience
if(owner)
on_gain()
diff --git a/code/datums/brain_damage/severe.dm b/code/datums/brain_damage/severe.dm
index b4d1951eb5..821770e9c5 100644
--- a/code/datums/brain_damage/severe.dm
+++ b/code/datums/brain_damage/severe.dm
@@ -3,6 +3,7 @@
//They cannot be cured with chemicals, and require brain surgery to solve.
/datum/brain_trauma/severe
+ resilience = TRAUMA_RESILIENCE_SURGERY
/datum/brain_trauma/severe/mute
name = "Mutism"
diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index 59cbf745f8..4e9aab7b4c 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -964,7 +964,7 @@
var/angle = input(usr, "Choose angle to rotate","Transform Mod") as null|num
if(!isnull(angle))
A.transform = M.Turn(angle)
-
+
href_list["datumrefresh"] = href_list["modtransform"]
else if(href_list["rotatedatum"])
@@ -1006,7 +1006,6 @@
var/list/traumas = subtypesof(/datum/brain_trauma)
var/result = input(usr, "Choose the brain trauma to apply","Traumatize") as null|anything in traumas
- var/permanent = alert("Do you want to make the trauma unhealable?", "Permanently Traumatize", "Yes", "No")
if(!usr)
return
if(QDELETED(C))
@@ -1014,7 +1013,7 @@
return
if(result)
- C.gain_trauma(result, permanent)
+ C.gain_trauma(result)
href_list["datumrefresh"] = href_list["givetrauma"]
@@ -1027,7 +1026,7 @@
to_chat(usr, "This can only be done to instances of type /mob/living/carbon")
return
- C.cure_all_traumas(TRUE, TRUE)
+ C.cure_all_traumas(TRUE, TRAUMA_RESILIENCE_ABSOLUTE)
href_list["datumrefresh"] = href_list["curetraumas"]
diff --git a/code/datums/diseases/advance/symptoms/sensory.dm b/code/datums/diseases/advance/symptoms/sensory.dm
index bb1170bc58..de146fd9d1 100644
--- a/code/datums/diseases/advance/symptoms/sensory.dm
+++ b/code/datums/diseases/advance/symptoms/sensory.dm
@@ -54,12 +54,11 @@
M.adjustBrainLoss(-3)
if(trauma_heal_mild && iscarbon(M))
var/mob/living/carbon/C = M
- if(prob(30) && C.has_trauma_type(BRAIN_TRAUMA_SPECIAL))
- C.cure_trauma_type(BRAIN_TRAUMA_SPECIAL)
- if(prob(10) && C.has_trauma_type(BRAIN_TRAUMA_MILD))
- C.cure_trauma_type(BRAIN_TRAUMA_MILD)
- if(trauma_heal_severe && prob(10) && C.has_trauma_type(BRAIN_TRAUMA_SEVERE))
- C.cure_trauma_type(BRAIN_TRAUMA_SEVERE)
+ if(prob(10))
+ if(trauma_heal_severe)
+ C.cure_trauma_type(TRAUMA_RESILIENCE_LOBOTOMY)
+ else
+ C.cure_trauma_type(TRAUMA_RESILIENCE_BASIC)
diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm
index 8d53987a2b..4dca5017b9 100644
--- a/code/game/machinery/computer/Operating.dm
+++ b/code/game/machinery/computer/Operating.dm
@@ -6,12 +6,24 @@
circuit = /obj/item/circuitboard/computer/operating
var/mob/living/carbon/human/patient
var/obj/structure/table/optable/table
+ var/list/advanced_surgeries = list()
light_color = LIGHT_COLOR_BLUE
/obj/machinery/computer/operating/Initialize()
. = ..()
find_table()
+/obj/machinery/computer/operating/attackby(obj/item/O, mob/user, params)
+ if(istype(O, /obj/item/disk/surgery))
+ user.visible_message("[user] begins to load \the [O] in \the [src]...",
+ "You begin to load a surgery protocol from \the [O]...",
+ "You hear the chatter of a floppy drive.")
+ var/obj/item/disk/surgery/D = O
+ if(do_after(user, 10, target = src))
+ advanced_surgeries |= D.surgeries
+ return TRUE
+ return ..()
+
/obj/machinery/computer/operating/proc/find_table()
for(var/direction in GLOB.cardinals)
table = locate(/obj/structure/table/optable, get_step(src, direction))
@@ -69,4 +81,4 @@
"next_step" = capitalize(surgery_step.name),
"alternative_step" = alternative_step
))
- return data
+ return data
\ No newline at end of file
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index acfa74980b..3c778818a5 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -161,7 +161,16 @@ GAS ANALYZER
if(LAZYLEN(C.get_traumas()))
var/list/trauma_text = list()
for(var/datum/brain_trauma/B in C.get_traumas())
- trauma_text += B.scan_desc
+ var/trauma_desc = ""
+ switch(B.resilience)
+ if(TRAUMA_RESILIENCE_SURGERY)
+ trauma_desc += "severe "
+ if(TRAUMA_RESILIENCE_LOBOTOMY)
+ trauma_desc += "deep-rooted "
+ if(TRAUMA_RESILIENCE_MAGIC, TRAUMA_RESILIENCE_ABSOLUTE)
+ trauma_desc += "permanent "
+ trauma_desc += B.scan_desc
+ trauma_text += trauma_desc
to_chat(user, "\tCerebral traumas detected: subjects appears to be suffering from [english_list(trauma_text)].")
if(advanced)
to_chat(user, "\tBrain Activity Level: [(200 - M.getBrainLoss())/2]%.")
diff --git a/code/game/objects/items/implants/implant_loyality.dm b/code/game/objects/items/implants/implant_loyality.dm
index 186730d0fc..773d784fbd 100644
--- a/code/game/objects/items/implants/implant_loyality.dm
+++ b/code/game/objects/items/implants/implant_loyality.dm
@@ -20,13 +20,17 @@
if(..())
if(!target.mind)
return TRUE
+
+ if(target.mind.has_antag_datum(/datum/antagonist/brainwashed))
+ target.mind.remove_antag_datum(/datum/antagonist/brainwashed)
+
if(target.mind.has_antag_datum(/datum/antagonist/rev/head) || target.mind.unconvertable)
if(!silent)
target.visible_message("[target] seems to resist the implant!", "You feel something interfering with your mental conditioning, but you resist it!")
removed(target, 1)
qdel(src)
return FALSE
-
+
var/datum/antagonist/rev/rev = target.mind.has_antag_datum(/datum/antagonist/rev)
if(rev)
rev.remove_revolutionary(FALSE, user)
diff --git a/code/game/objects/items/implants/implantchair.dm b/code/game/objects/items/implants/implantchair.dm
index 448b32e2d5..e8933b7151 100644
--- a/code/game/objects/items/implants/implantchair.dm
+++ b/code/game/objects/items/implants/implantchair.dm
@@ -179,17 +179,16 @@
/obj/machinery/implantchair/brainwash/implant_action(mob/living/C,mob/user)
if(!istype(C) || !C.mind) // I don't know how this makes any sense for silicons but laws trump objectives anyway.
- return 0
+ return FALSE
if(custom)
if(!user || !user.Adjacent(src))
- return 0
+ return FALSE
objective = stripped_input(usr,"What order do you want to imprint on [C]?","Enter the order","",120)
message_admins("[key_name_admin(user)] set brainwash machine objective to '[objective]'.")
log_game("[key_name(user)] set brainwash machine objective to '[objective]'.")
- var/datum/objective/custom_objective = new/datum/objective(objective)
- custom_objective.owner = C.mind
- C.mind.objectives += custom_objective
- C.mind.announce_objectives()
+ if(C.isloyal())
+ return FALSE
+ brainwash(C, objective)
message_admins("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
log_game("[key_name(user)] brainwashed [key_name(C)] with objective '[objective]'.")
- return 1
+ return TRUE
\ No newline at end of file
diff --git a/code/modules/antagonists/abductor/abductor.dm b/code/modules/antagonists/abductor/abductor.dm
index 2f6ef07afd..8e29b38fe1 100644
--- a/code/modules/antagonists/abductor/abductor.dm
+++ b/code/modules/antagonists/abductor/abductor.dm
@@ -11,7 +11,7 @@
var/outfit
var/landmark_type
var/greet_text
-
+
/datum/antagonist/abductor/agent
name = "Abductor Agent"
@@ -167,7 +167,7 @@
/datum/antagonist/abductee/proc/give_objective()
var/mob/living/carbon/human/H = owner.current
if(istype(H))
- H.gain_trauma_type(BRAIN_TRAUMA_MILD)
+ H.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_LOBOTOMY)
var/objtype = (prob(75) ? /datum/objective/abductee/random : pick(subtypesof(/datum/objective/abductee/) - /datum/objective/abductee/random))
var/datum/objective/abductee/O = new objtype()
objectives += O
diff --git a/code/modules/antagonists/abductor/equipment/abduction_surgery.dm b/code/modules/antagonists/abductor/equipment/abduction_surgery.dm
index ffce85e435..656fb61f43 100644
--- a/code/modules/antagonists/abductor/equipment/abduction_surgery.dm
+++ b/code/modules/antagonists/abductor/equipment/abduction_surgery.dm
@@ -52,49 +52,4 @@
user.temporarilyRemoveItemFromInventory(tool, TRUE)
var/obj/item/organ/heart/gland/gland = tool
gland.Insert(target, 2)
- return 1
-
-/datum/surgery/pacify
- name = "violence neutralization"
- steps = list(/datum/surgery_step/incise,
- /datum/surgery_step/retract_skin,
- /datum/surgery_step/saw,
- /datum/surgery_step/clamp_bleeders,
- /datum/surgery_step/pacify,
- /datum/surgery_step/close)
-
- species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
- possible_locs = list("head")
- requires_bodypart_type = 0
-
-/datum/surgery/pacify/can_start(mob/user, mob/living/carbon/target)
- if(!ishuman(user))
- return FALSE
- var/mob/living/carbon/human/H = user
- . = FALSE
- if(!(H.dna.species.id == "abductor"))
- . = TRUE
- for(var/obj/item/implant/abductor/A in H.implants)
- . = TRUE
- var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN)
- if(!B)
- to_chat(user, "It's hard to do surgery on someone's brain when they don't have one.")
- return FALSE
-
-/datum/surgery_step/pacify
- name = "rewire brain"
- implements = list(/obj/item/hemostat = 100, /obj/item/screwdriver = 35, /obj/item/pen = 15)
- time = 40
-
-/datum/surgery_step/pacify/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- user.visible_message("[user] begins to reshape [target]'s brain.", "You begin to reshape [target]'s brain...")
-
-/datum/surgery_step/pacify/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- user.visible_message("[user] successfully reshapes [target]'s brain!", "You succeed in reshaping [target]'s brain.")
- target.gain_trauma(/datum/brain_trauma/severe/pacifism)
- return TRUE
-
-/datum/surgery_step/pacify/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- user.visible_message("[user] successfully reshapes [target]'s brain!", "You screwed up, and rewired [target]'s brain the wrong way around...")
- target.gain_trauma_type(BRAIN_TRAUMA_SEVERE)
- return FALSE
\ No newline at end of file
+ return 1
\ No newline at end of file
diff --git a/code/modules/antagonists/abductor/equipment/gland.dm b/code/modules/antagonists/abductor/equipment/gland.dm
index b9114da9ea..192bfcdf84 100644
--- a/code/modules/antagonists/abductor/equipment/gland.dm
+++ b/code/modules/antagonists/abductor/equipment/gland.dm
@@ -230,12 +230,12 @@
/obj/item/organ/heart/gland/trauma/activate()
to_chat(owner, "You feel a spike of pain in your head.")
if(prob(33))
- owner.gain_trauma_type(BRAIN_TRAUMA_SPECIAL, TRUE)
+ owner.gain_trauma_type(BRAIN_TRAUMA_SPECIAL, TRAUMA_RESILIENCE_LOBOTOMY)
else
if(prob(20))
- owner.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRUE)
+ owner.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_LOBOTOMY)
else
- owner.gain_trauma_type(BRAIN_TRAUMA_MILD, TRUE)
+ owner.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_LOBOTOMY)
/obj/item/organ/heart/gland/spiderman
cooldown_low = 450
diff --git a/code/modules/antagonists/brainwashing/brainwashing.dm b/code/modules/antagonists/brainwashing/brainwashing.dm
new file mode 100644
index 0000000000..1bc14ec8b3
--- /dev/null
+++ b/code/modules/antagonists/brainwashing/brainwashing.dm
@@ -0,0 +1,84 @@
+/proc/brainwash(mob/living/L, directives)
+ if(!L.mind)
+ return
+ if(!islist(directives))
+ directives = list(directives)
+ var/datum/mind/M = L.mind
+ var/datum/antagonist/brainwashed/B = M.has_antag_datum(/datum/antagonist/brainwashed)
+ if(B)
+ for(var/O in directives)
+ var/datum/objective/brainwashing/objective = new(O)
+ B.objectives += objective
+ M.objectives += objective
+ B.greet()
+ else
+ B = new()
+ for(var/O in directives)
+ var/datum/objective/brainwashing/objective = new(O)
+ B.objectives += objective
+ M.add_antag_datum(B)
+
+ var/begin_message = "[L] has been brainwashed with the following objectives: "
+ var/obj_message = english_list(directives)
+ var/end_message = "."
+ var/rendered = begin_message + obj_message + end_message
+ deadchat_broadcast(rendered, follow_target = L, turf_target = get_turf(L), message_type=DEADCHAT_REGULAR)
+
+/datum/antagonist/brainwashed
+ name = "Brainwashed Victim"
+ job_rank = ROLE_BRAINWASHED
+ roundend_category = "brainwashed victims"
+ show_in_antagpanel = TRUE
+ antagpanel_category = "Other"
+ show_name_in_check_antagonists = TRUE
+
+/datum/antagonist/brainwashed/on_gain()
+ owner.objectives |= objectives
+ . = ..()
+
+/datum/antagonist/brainwashed/on_removal()
+ owner.objectives -= objectives
+ . = ..()
+
+/datum/antagonist/brainwashed/greet()
+ to_chat(owner, "Your mind reels as it begins focusing on a single purpose...")
+ to_chat(owner, "Follow the Directives, at any cost!")
+ var/i = 1
+ for(var/X in objectives)
+ var/datum/objective/O = X
+ to_chat(owner, "[i]. [O.explanation_text]")
+ i++
+
+/datum/antagonist/brainwashed/farewell()
+ to_chat(owner, "Your mind suddenly clears...")
+ to_chat(owner, "You feel the weight of the Directives disappear! You no longer have to obey them.")
+ owner.announce_objectives()
+
+/datum/antagonist/brainwashed/admin_add(datum/mind/new_owner,mob/admin)
+ var/mob/living/carbon/C = new_owner.current
+ if(!istype(C))
+ return
+ var/list/objectives = list()
+ do
+ var/objective = stripped_input(admin, "Add an objective, or leave empty to finish.", "Brainwashing", null, MAX_MESSAGE_LEN)
+ if(objective)
+ objectives += objective
+ while(alert(admin,"Add another objective?","More Brainwashing","Yes","No") == "Yes")
+
+ if(alert(admin,"Confirm Brainwashing?","Are you sure?","Yes","No") == "No")
+ return
+
+ if(!LAZYLEN(objectives))
+ return
+
+ if(QDELETED(C))
+ to_chat(admin, "Mob doesn't exist anymore")
+ return
+
+ brainwash(C, objectives)
+ var/obj_list = english_list(objectives)
+ message_admins("[key_name_admin(admin)] has brainwashed [key_name_admin(C)] with the following objectives: [obj_list].")
+ log_admin("[key_name(admin)] has brainwashed [key_name(C)] with the following objectives: [obj_list].")
+
+/datum/objective/brainwashing
+ completed = TRUE
diff --git a/code/modules/jobs/job_types/civilian.dm b/code/modules/jobs/job_types/civilian.dm
index 67bc2143f8..9a2030d7ed 100644
--- a/code/modules/jobs/job_types/civilian.dm
+++ b/code/modules/jobs/job_types/civilian.dm
@@ -152,7 +152,7 @@ Curator
return
H.grant_all_languages(omnitongue=TRUE)
- H.gain_trauma(/datum/brain_trauma/mild/phobia, FALSE, "snakes") //why does it have to be snakes...
+ H.gain_trauma(/datum/brain_trauma/mild/phobia, TRAUMA_RESILIENCE_SURGERY, "snakes") //why does it have to be snakes...
/*
Lawyer
*/
diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm
index f6fbbaab4b..dd8c84c969 100644
--- a/code/modules/mob/living/blood.dm
+++ b/code/modules/mob/living/blood.dm
@@ -98,6 +98,7 @@
add_splatter_floor(src.loc, 1)
/mob/living/carbon/human/bleed(amt)
+ amt *= physiology.bleed_mod
if(!(NOBLOOD in dna.species.species_traits))
..()
diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm
index ad58d2fa8e..ac2f8ae58e 100644
--- a/code/modules/mob/living/brain/brain_item.dm
+++ b/code/modules/mob/living/brain/brain_item.dm
@@ -179,27 +179,28 @@
////////////////////////////////////TRAUMAS////////////////////////////////////////
-/obj/item/organ/brain/proc/has_trauma_type(brain_trauma_type, consider_permanent = FALSE)
+/obj/item/organ/brain/proc/has_trauma_type(brain_trauma_type, resilience = TRAUMA_RESILIENCE_ABSOLUTE)
for(var/X in traumas)
var/datum/brain_trauma/BT = X
- if(istype(BT, brain_trauma_type) && (consider_permanent || !BT.permanent))
+ if(istype(BT, brain_trauma_type) && (BT.resilience <= resilience))
return BT
//Add a specific trauma
-/obj/item/organ/brain/proc/gain_trauma(datum/brain_trauma/trauma, permanent = FALSE, list/arguments)
+/obj/item/organ/brain/proc/gain_trauma(datum/brain_trauma/trauma, resilience, list/arguments)
var/trauma_type
if(ispath(trauma))
trauma_type = trauma
SSblackbox.record_feedback("tally", "traumas", 1, trauma_type)
- traumas += new trauma_type(arglist(list(src, permanent) + arguments))
+ traumas += new trauma_type(arglist(list(src, resilience) + arguments))
else
SSblackbox.record_feedback("tally", "traumas", 1, trauma.type)
traumas += trauma
- trauma.permanent = permanent
+ if(resilience)
+ trauma.resilience = resilience
//Add a random trauma of a certain subtype
-/obj/item/organ/brain/proc/gain_trauma_type(brain_trauma_type = /datum/brain_trauma, permanent = FALSE)
+/obj/item/organ/brain/proc/gain_trauma_type(brain_trauma_type = /datum/brain_trauma, resilience)
var/list/datum/brain_trauma/possible_traumas = list()
for(var/T in subtypesof(brain_trauma_type))
var/datum/brain_trauma/BT = T
@@ -208,16 +209,16 @@
var/trauma_type = pick(possible_traumas)
SSblackbox.record_feedback("tally", "traumas", 1, trauma_type)
- traumas += new trauma_type(src, permanent)
+ traumas += new trauma_type(src, resilience)
-//Cure a random trauma of a certain subtype
-/obj/item/organ/brain/proc/cure_trauma_type(brain_trauma_type, cure_permanent = FALSE)
- var/datum/brain_trauma/trauma = has_trauma_type(brain_trauma_type)
- if(trauma && (cure_permanent || !trauma.permanent))
+//Cure a random trauma of a certain resilience level
+/obj/item/organ/brain/proc/cure_trauma_type(resilience = TRAUMA_RESILIENCE_BASIC)
+ var/datum/brain_trauma/trauma = has_trauma_type(resilience)
+ if(trauma)
qdel(trauma)
-/obj/item/organ/brain/proc/cure_all_traumas(cure_permanent = FALSE)
+/obj/item/organ/brain/proc/cure_all_traumas(resilience = TRAUMA_RESILIENCE_BASIC)
for(var/X in traumas)
var/datum/brain_trauma/trauma = X
- if(cure_permanent || !trauma.permanent)
+ if(trauma.resilience <= resilience)
qdel(trauma)
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index fee97c1d01..c38799e9b4 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -746,16 +746,16 @@
update_inv_handcuffed()
update_hud_handcuffed()
-/mob/living/carbon/fully_heal(admin_revive = 0)
+/mob/living/carbon/fully_heal(admin_revive = FALSE)
if(reagents)
reagents.clear_reagents()
var/obj/item/organ/brain/B = getorgan(/obj/item/organ/brain)
if(B)
- B.damaged_brain = 0
+ B.damaged_brain = FALSE
for(var/thing in viruses)
var/datum/disease/D = thing
if(D.severity != VIRUS_SEVERITY_POSITIVE)
- D.cure(0)
+ D.cure(FALSE)
if(admin_revive)
regenerate_limbs()
regenerate_organs()
@@ -765,7 +765,7 @@
update_handcuffed()
if(reagents)
reagents.addiction_list = list()
- cure_all_traumas(TRUE, TRUE)
+ cure_all_traumas(TRUE, TRAUMA_RESILIENCE_MAGIC)
..()
// heal ears after healing traits, since ears check TRAIT_DEAF trait
// when healing.
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index 81f64d1d26..56420df35a 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -121,9 +121,9 @@
ContactContractDisease(D)
if(lying && surgeries.len)
- if(user.a_intent == INTENT_HELP)
+ if(user.a_intent == INTENT_HELP || user.a_intent == INTENT_DISARM)
for(var/datum/surgery/S in surgeries)
- if(S.next_step(user))
+ if(S.next_step(user, user.a_intent))
return 1
return 0
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index d59c3cfba2..7ff6c5a13f 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -22,6 +22,7 @@
//initialise organs
create_internal_organs() //most of it is done in set_species now, this is only for parent call
+ physiology = new()
handcrafting = new()
@@ -29,6 +30,10 @@
AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT), CALLBACK(src, .proc/clean_blood))
+/mob/living/carbon/human/Destroy()
+ QDEL_NULL(physiology)
+ return ..()
+
/mob/living/carbon/human/OpenCraftingMenu()
handcrafting.ui_interact(src)
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 918b66c6c5..e6fbfe7be9 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -29,6 +29,7 @@
var/obj/item/clothing/C = bp
if(C.body_parts_covered & def_zone.body_part)
protection += C.armor.getRating(d_type)
+ protection += physiology.armor.getRating(d_type)
return protection
/mob/living/carbon/human/on_hit(obj/item/projectile/P)
@@ -458,6 +459,7 @@
heart.beating = TRUE
if(stat == CONSCIOUS)
to_chat(src, "You feel your heart beating again!")
+ siemens_coeff *= physiology.siemens_coeff
. = ..(shock_damage,source,siemens_coeff,safety,override,tesla_shock, illusion, stun)
if(.)
electrocution_animation(40)
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 7c4d12aaa1..2bc4de894e 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -45,6 +45,9 @@
var/drunkenness = 0 //Overall drunkenness - check handle_alcohol() in life.dm for effects
var/datum/personal_crafting/handcrafting
+ var/datum/physiology/physiology
+
+ var/list/datum/bioware = list()
var/creamed = FALSE //to use with creampie overlays
var/static/list/can_ride_typecache = typecacheof(list(/mob/living/carbon/human, /mob/living/simple_animal/slime, /mob/living/simple_animal/parrot))
diff --git a/code/modules/mob/living/carbon/human/physiology.dm b/code/modules/mob/living/carbon/human/physiology.dm
new file mode 100644
index 0000000000..3d1cae8f41
--- /dev/null
+++ b/code/modules/mob/living/carbon/human/physiology.dm
@@ -0,0 +1,27 @@
+//Stores several modifiers in a way that isn't cleared by changing species
+
+/datum/physiology
+ var/brute_mod = 1 // % of brute damage taken from all sources
+ var/burn_mod = 1 // % of burn damage taken from all sources
+ var/tox_mod = 1 // % of toxin damage taken from all sources
+ var/oxy_mod = 1 // % of oxygen damage taken from all sources
+ var/clone_mod = 1 // % of clone damage taken from all sources
+ var/stamina_mod = 1 // % of stamina damage taken from all sources
+ var/brain_mod = 1 // % of brain damage taken from all sources
+
+ var/pressure_mod = 1// % of brute damage taken from low or high pressure (stacks with brute_mod)
+ var/heat_mod = 1 // % of burn damage taken from heat (stacks with burn_mod)
+ var/cold_mod = 1 // % of burn damage taken from cold (stacks with burn_mod)
+
+ var/damage_resistance = 0 // %damage reduction from all sources
+
+ var/siemens_coeff = 1 // resistance to shocks
+
+ var/stun_mod = 1 // % stun modifier
+ var/bleed_mod = 1 // % bleeding modifier
+ var/datum/armor/armor // internal armor datum
+
+ var/speed_mod = 0 //tick modifier for each step. Positive is slower, negative is faster.
+
+/datum/physiology/New()
+ armor = new
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index f4822a066e..21c24eac9b 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -1213,19 +1213,20 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if(H.movement_type & FLYING)
flight = 1
- if(!flightpack) //Check for chemicals and innate speedups and slowdowns if we're moving using our body and not a flying suit
+ if(H.has_gravity())
+ gravity = TRUE
+
+ if(!flightpack && gravity) //Check for chemicals and innate speedups and slowdowns if we're moving using our body and not a flying suit
if(H.has_trait(TRAIT_GOTTAGOFAST))
. -= 1
if(H.has_trait(TRAIT_GOTTAGOREALLYFAST))
. -= 2
. += speedmod
+ . += H.physiology.speed_mod
if(H.has_trait(TRAIT_IGNORESLOWDOWN))
ignoreslow = 1
- if(H.has_gravity())
- gravity = 1
-
if(!gravity)
var/obj/item/tank/jetpack/J = H.back
var/obj/item/clothing/suit/space/hardsuit/C = H.wear_suit
@@ -1551,6 +1552,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H)
var/hit_percent = (100-(blocked+armor))/100
+ hit_percent = (hit_percent * (100-H.physiology.damage_resistance))/100
if(!damage || hit_percent <= 0)
return 0
@@ -1568,27 +1570,27 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if(BRUTE)
H.damageoverlaytemp = 20
if(BP)
- if(BP.receive_damage(damage * hit_percent * brutemod, 0))
+ if(BP.receive_damage(damage * hit_percent * brutemod * H.physiology.brute_mod, 0))
H.update_damage_overlays()
else//no bodypart, we deal damage with a more general method.
- H.adjustBruteLoss(damage * hit_percent * brutemod)
+ H.adjustBruteLoss(damage * hit_percent * brutemod * H.physiology.brute_mod)
if(BURN)
H.damageoverlaytemp = 20
if(BP)
- if(BP.receive_damage(0, damage * hit_percent * burnmod))
+ if(BP.receive_damage(0, damage * hit_percent * burnmod * H.physiology.burn_mod))
H.update_damage_overlays()
else
- H.adjustFireLoss(damage * hit_percent* burnmod)
+ H.adjustFireLoss(damage * hit_percent * burnmod * H.physiology.burn_mod)
if(TOX)
- H.adjustToxLoss(damage * hit_percent)
+ H.adjustToxLoss(damage * hit_percent * H.physiology.tox_mod)
if(OXY)
- H.adjustOxyLoss(damage * hit_percent)
+ H.adjustOxyLoss(damage * hit_percent * H.physiology.oxy_mod)
if(CLONE)
- H.adjustCloneLoss(damage * hit_percent)
+ H.adjustCloneLoss(damage * hit_percent * H.physiology.clone_mod)
if(STAMINA)
- H.adjustStaminaLoss(damage * hit_percent)
+ H.adjustStaminaLoss(damage * hit_percent * H.physiology.stamina_mod)
if(BRAIN)
- H.adjustBrainLoss(damage * hit_percent)
+ H.adjustBrainLoss(damage * hit_percent * H.physiology.brain_mod)
return 1
/datum/species/proc/on_hit(obj/item/projectile/P, mob/living/carbon/human/H)
@@ -1656,7 +1658,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
burn_damage = HEAT_DAMAGE_LEVEL_3
else
burn_damage = HEAT_DAMAGE_LEVEL_2
- burn_damage *= heatmod
+ burn_damage = burn_damage * heatmod * H.physiology.heat_mod
if (H.stat < UNCONSCIOUS && (prob(burn_damage) * 10) / 4) //40% for level 3 damage on humans
H.emote("scream")
H.apply_damage(burn_damage, BURN)
@@ -1664,13 +1666,13 @@ GLOBAL_LIST_EMPTY(roundstart_races)
switch(H.bodytemperature)
if(200 to BODYTEMP_COLD_DAMAGE_LIMIT)
H.throw_alert("temp", /obj/screen/alert/cold, 1)
- H.apply_damage(COLD_DAMAGE_LEVEL_1*coldmod, BURN)
+ H.apply_damage(COLD_DAMAGE_LEVEL_1*coldmod*H.physiology.cold_mod, BURN)
if(120 to 200)
H.throw_alert("temp", /obj/screen/alert/cold, 2)
- H.apply_damage(COLD_DAMAGE_LEVEL_2*coldmod, BURN)
+ H.apply_damage(COLD_DAMAGE_LEVEL_2*coldmod*H.physiology.cold_mod, BURN)
else
H.throw_alert("temp", /obj/screen/alert/cold, 3)
- H.apply_damage(COLD_DAMAGE_LEVEL_3*coldmod, BURN)
+ H.apply_damage(COLD_DAMAGE_LEVEL_3*coldmod*H.physiology.cold_mod, BURN)
else
H.clear_alert("temp")
@@ -1680,7 +1682,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
switch(adjusted_pressure)
if(HAZARD_HIGH_PRESSURE to INFINITY)
if(!(RESISTPRESSURE in species_traits))
- H.adjustBruteLoss( min( ( (adjusted_pressure / HAZARD_HIGH_PRESSURE) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE) )
+ H.adjustBruteLoss(min(((adjusted_pressure / HAZARD_HIGH_PRESSURE) -1 ) * PRESSURE_DAMAGE_COEFFICIENT, MAX_HIGH_PRESSURE_DAMAGE) * H.physiology.pressure_mod)
H.throw_alert("pressure", /obj/screen/alert/highpressure, 2)
else
H.clear_alert("pressure")
@@ -1694,7 +1696,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if(H.dna.check_mutation(COLDRES) || (RESISTPRESSURE in species_traits))
H.clear_alert("pressure")
else
- H.adjustBruteLoss( LOW_PRESSURE_DAMAGE )
+ H.adjustBruteLoss(LOW_PRESSURE_DAMAGE * H.physiology.pressure_mod)
H.throw_alert("pressure", /obj/screen/alert/lowpressure, 2)
//////////
@@ -1782,7 +1784,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
////////////
/datum/species/proc/spec_stun(mob/living/carbon/human/H,amount)
- . = stunmod * amount
+ . = stunmod * H.physiology.stun_mod * amount
//////////////
//Space Move//
diff --git a/code/modules/mob/living/carbon/status_procs.dm b/code/modules/mob/living/carbon/status_procs.dm
index 300455a174..eccdd5d2cf 100644
--- a/code/modules/mob/living/carbon/status_procs.dm
+++ b/code/modules/mob/living/carbon/status_procs.dm
@@ -73,28 +73,28 @@
if(B)
. = B.traumas
-/mob/living/carbon/proc/has_trauma_type(brain_trauma_type, consider_permanent = FALSE)
+/mob/living/carbon/proc/has_trauma_type(brain_trauma_type, resilience)
var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN)
if(B)
- . = B.has_trauma_type(brain_trauma_type, consider_permanent)
+ . = B.has_trauma_type(brain_trauma_type, resilience)
-/mob/living/carbon/proc/gain_trauma(datum/brain_trauma/trauma, permanent = FALSE, list/arguments)
+/mob/living/carbon/proc/gain_trauma(datum/brain_trauma/trauma, resilience, list/arguments)
var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN)
if(B)
- . = B.gain_trauma(trauma, permanent, arguments)
+ . = B.gain_trauma(trauma, resilience, arguments)
-/mob/living/carbon/proc/gain_trauma_type(brain_trauma_type = /datum/brain_trauma, permanent = FALSE)
+/mob/living/carbon/proc/gain_trauma_type(brain_trauma_type = /datum/brain_trauma, resilience)
var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN)
if(B)
- . = B.gain_trauma_type(brain_trauma_type, permanent)
+ . = B.gain_trauma_type(brain_trauma_type, resilience)
-/mob/living/carbon/proc/cure_trauma_type(brain_trauma_type, cure_permanent = FALSE)
+/mob/living/carbon/proc/cure_trauma_type(resilience)
var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN)
if(B)
- . = B.cure_trauma_type(brain_trauma_type, cure_permanent)
+ . = B.cure_trauma_type(resilience)
-/mob/living/carbon/proc/cure_all_traumas(cure_permanent = FALSE)
+/mob/living/carbon/proc/cure_all_traumas(resilience)
var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN)
if(B)
- . = B.cure_all_traumas(cure_permanent)
+ . = B.cure_all_traumas(resilience)
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index 01c1bb6815..64454b130e 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -78,9 +78,6 @@
O.setBrainLoss(getBrainLoss(), 0)
O.updatehealth()
O.radiation = radiation
- for(var/T in get_traumas())
- var/datum/brain_trauma/BT = T
- O.gain_trauma(BT.type, BT.permanent)
//re-add implants to new mob
if (tr_flags & TR_KEEPIMPLANTS)
@@ -238,9 +235,6 @@
O.setBrainLoss(getBrainLoss(), 0)
O.updatehealth()
O.radiation = radiation
- for(var/T in get_traumas())
- var/datum/brain_trauma/BT = T
- O.gain_trauma(BT.type, BT.permanent)
//re-add implants to new mob
if (tr_flags & TR_KEEPIMPLANTS)
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index ee25eed30d..dabbec25a8 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -59,7 +59,7 @@
M.confused = 0
M.SetSleeping(0, 0)
M.jitteriness = 0
- M.cure_all_traumas(TRUE, TRUE)
+ M.cure_all_traumas(TRUE, TRAUMA_RESILIENCE_MAGIC)
for(var/thing in M.viruses)
var/datum/disease/D = thing
if(D.severity == VIRUS_SEVERITY_POSITIVE)
@@ -832,10 +832,8 @@
M.adjustBrainLoss(-2*REM)
if(iscarbon(M))
var/mob/living/carbon/C = M
- if(prob(30) && C.has_trauma_type(BRAIN_TRAUMA_SPECIAL))
- C.cure_trauma_type(BRAIN_TRAUMA_SPECIAL)
- if(prob(10) && C.has_trauma_type(BRAIN_TRAUMA_MILD))
- C.cure_trauma_type(BRAIN_TRAUMA_MILD)
+ if(prob(10))
+ C.cure_trauma_type(TRAUMA_RESILIENCE_BASIC)
..()
/datum/reagent/medicine/mutadone
diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm
index c3f0df7b14..9f287c6ee2 100644
--- a/code/modules/research/designs/medical_designs.dm
+++ b/code/modules/research/designs/medical_designs.dm
@@ -457,3 +457,103 @@
build_path = /obj/item/organ/lungs/cybernetic/upgraded
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
+
+/datum/design/surgery_lobotomy
+ name = "Lobotomy Surgery Disk"
+ desc = "A disk containing the instructions for a Lobotomy surgery."
+ id = "surgery_lobotomy"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 300, MAT_GLASS = 100)
+ build_path = /obj/item/disk/surgery/lobotomy
+ category = list("Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
+
+/datum/design/surgery_pacify
+ name = "Pacification Surgery Disk"
+ desc = "A disk containing the instructions for a Pacification surgery."
+ id = "surgery_pacify"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 300, MAT_GLASS = 100)
+ build_path = /obj/item/disk/surgery/pacification
+ category = list("Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
+
+/datum/design/surgery_viral_bonding
+ name = "Viral Bonding Surgery Disk"
+ desc = "A disk containing the instructions for a Viral Bonding surgery."
+ id = "surgery_viral_bond"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 300, MAT_GLASS = 100)
+ build_path = /obj/item/disk/surgery/viral_bonding
+ category = list("Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
+
+/datum/design/surgery_reconstruction
+ name = "Reconstruction Surgery Disk"
+ desc = "A disk containing the instructions for a Reconstruction surgery."
+ id = "surgery_reconstruction"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 300, MAT_GLASS = 100)
+ build_path = /obj/item/disk/surgery/reconstruction
+ category = list("Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
+
+/datum/design/surgery_revival
+ name = "Revival Surgery Disk"
+ desc = "A disk containing the instructions for a Revival surgery."
+ id = "surgery_revival"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 300, MAT_GLASS = 100)
+ build_path = /obj/item/disk/surgery/revival
+ category = list("Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
+
+/datum/design/surgery_brainwashing
+ name = "Brainwashing Surgery Disk"
+ desc = "A disk containing the instructions for a Brainwashing surgery."
+ id = "surgery_brainwashing"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 300, MAT_GLASS = 100)
+ build_path = /obj/item/disk/surgery/brainwashing
+ category = list("Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
+
+/datum/design/surgery_nerve_splicing
+ name = "Nerve Splicing Surgery Disk"
+ desc = "A disk containing the instructions for a Nerve Splicing surgery."
+ id = "surgery_nerve_splice"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 300, MAT_GLASS = 100)
+ build_path = /obj/item/disk/surgery/nerve_splicing
+ category = list("Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
+
+/datum/design/surgery_nerve_grounding
+ name = "Nerve Grounding Surgery Disk"
+ desc = "A disk containing the instructions for a Nerve Grounding surgery."
+ id = "surgery_nerve_ground"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 300, MAT_GLASS = 100)
+ build_path = /obj/item/disk/surgery/nerve_grounding
+ category = list("Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
+
+/datum/design/surgery_vein_threading
+ name = "Vein Threading Surgery Disk"
+ desc = "A disk containing the instructions for a Vein Threading surgery."
+ id = "surgery_vein_thread"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 300, MAT_GLASS = 100)
+ build_path = /obj/item/disk/surgery/vein_threading
+ category = list("Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
+
+/datum/design/surgery_necrotic_revival
+ name = "Necrotic Revival Surgery Disk"
+ desc = "A disk containing the instructions for a Necrotic Revival surgery."
+ id = "surgery_zombie"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 300, MAT_GLASS = 100)
+ build_path = /obj/item/disk/surgery/necrotic_revival
+ category = list("Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
\ No newline at end of file
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index 4b5a231439..2842068c66 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -39,6 +39,34 @@
research_cost = 2500
export_price = 5000
+/////////////////////////Advanced Surgery/////////////////////////
+/datum/techweb_node/adv_surgery
+ id = "adv_surgery"
+ display_name = "Advanced Surgery"
+ description = "When simple medicine doesn't cut it."
+ prereq_ids = list("adv_biotech")
+ design_ids = list("surgery_lobotomy", "surgery_reconstruction")
+ research_cost = 2500
+ export_price = 5000
+
+/datum/techweb_node/exp_surgery
+ id = "exp_surgery"
+ display_name = "Experimental Surgery"
+ description = "When evolution isn't fast enough."
+ prereq_ids = list("adv_surgery")
+ design_ids = list("surgery_revival","surgery_pacify","surgery_vein_thread","surgery_nerve_splice","surgery_nerve_ground","surgery_viral_bond")
+ research_cost = 5000
+ export_price = 5000
+
+/datum/techweb_node/alien_surgery
+ id = "alien_surgery"
+ display_name = "Alien Surgery"
+ description = "Abductors did nothing wrong."
+ prereq_ids = list("exp_surgery", "alientech")
+ design_ids = list("surgery_brainwashing","surgery_zombie")
+ research_cost = 10000
+ export_price = 5000
+
/////////////////////////data theory tech/////////////////////////
/datum/techweb_node/datatheory //Computer science
id = "datatheory"
diff --git a/code/modules/surgery/advanced/bioware/bioware.dm b/code/modules/surgery/advanced/bioware/bioware.dm
new file mode 100644
index 0000000000..6c0a7529d0
--- /dev/null
+++ b/code/modules/surgery/advanced/bioware/bioware.dm
@@ -0,0 +1,30 @@
+//Bioware
+//Body modifications applied through surgery. They generally affect physiology.
+
+/datum/bioware
+ var/name = "Generic Bioware"
+ var/mob/living/carbon/human/owner
+ var/desc = "If you see this something's wrong, warn a coder."
+ var/active = FALSE
+ var/mod_type = BIOWARE_GENERIC
+
+/datum/bioware/New(mob/living/carbon/human/_owner)
+ owner = _owner
+ for(var/X in owner.bioware)
+ var/datum/bioware/B = X
+ if(B.mod_type == mod_type)
+ qdel(src)
+ return
+ on_gain()
+
+/datum/bioware/Destroy()
+ owner = null
+ if(active)
+ on_lose()
+ return ..()
+
+/datum/bioware/proc/on_gain()
+ active = TRUE
+
+/datum/bioware/proc/on_lose()
+ return
\ No newline at end of file
diff --git a/code/modules/surgery/advanced/bioware/bioware_surgery.dm b/code/modules/surgery/advanced/bioware/bioware_surgery.dm
new file mode 100644
index 0000000000..86817b9b09
--- /dev/null
+++ b/code/modules/surgery/advanced/bioware/bioware_surgery.dm
@@ -0,0 +1,12 @@
+/datum/surgery/advanced/bioware
+ name = "enhancement surgery"
+ var/bioware_target = BIOWARE_GENERIC
+
+/datum/surgery/advanced/bioware/can_start(mob/user, mob/living/carbon/human/target)
+ if(!..())
+ return FALSE
+ for(var/X in target.bioware)
+ var/datum/bioware/B = X
+ if(B.mod_type == bioware_target)
+ return FALSE
+ return TRUE
\ No newline at end of file
diff --git a/code/modules/surgery/advanced/bioware/nerve_grounding.dm b/code/modules/surgery/advanced/bioware/nerve_grounding.dm
new file mode 100644
index 0000000000..dd2be71026
--- /dev/null
+++ b/code/modules/surgery/advanced/bioware/nerve_grounding.dm
@@ -0,0 +1,43 @@
+/obj/item/disk/surgery/nerve_grounding
+ desc = "The disk provides instructions on how to reroute the nervous system to ground electric shocks."
+ surgeries = list(/datum/surgery/advanced/bioware/nerve_grounding)
+
+/datum/surgery/advanced/bioware/nerve_grounding
+ name = "nerve grounding"
+ steps = list(/datum/surgery_step/incise,
+ /datum/surgery_step/retract_skin,
+ /datum/surgery_step/clamp_bleeders,
+ /datum/surgery_step/incise,
+ /datum/surgery_step/incise,
+ /datum/surgery_step/ground_nerves,
+ /datum/surgery_step/close)
+ possible_locs = list("chest")
+ bioware_target = BIOWARE_NERVES
+
+/datum/surgery_step/ground_nerves
+ name = "ground nerves"
+ accept_hand = TRUE
+ time = 155
+
+/datum/surgery_step/ground_nerves/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] starts splicing together [target]'s nerves.", "You start splicing together [target]'s nerves.")
+
+/datum/surgery_step/ground_nerves/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] successfully splices [target]'s nervous system!", "You successfully splice [target]'s nervous system!")
+ new /datum/bioware/grounded_nerves(target)
+ return TRUE
+
+/datum/bioware/grounded_nerves
+ name = "Grounded Nerves"
+ desc = "Nerves form a safe path for electricity to traverse, protecting the body from electric shocks."
+ mod_type = "nerves"
+ var/prev_coeff
+
+/datum/bioware/grounded_nerves/on_gain()
+ ..()
+ prev_coeff = owner.physiology.siemens_coeff
+ owner.physiology.siemens_coeff = 0
+
+/datum/bioware/grounded_nerves/on_lose()
+ ..()
+ owner.physiology.siemens_coeff = prev_coeff
\ No newline at end of file
diff --git a/code/modules/surgery/advanced/bioware/nerve_splicing.dm b/code/modules/surgery/advanced/bioware/nerve_splicing.dm
new file mode 100644
index 0000000000..8579f9b107
--- /dev/null
+++ b/code/modules/surgery/advanced/bioware/nerve_splicing.dm
@@ -0,0 +1,41 @@
+/obj/item/disk/surgery/nerve_splicing
+ desc = "The disk provides instructions on how to splice the circulatory system to counter stuns and paralysis."
+ surgeries = list(/datum/surgery/advanced/bioware/nerve_splicing)
+
+/datum/surgery/advanced/bioware/nerve_splicing
+ name = "nerve splicing"
+ steps = list(/datum/surgery_step/incise,
+ /datum/surgery_step/retract_skin,
+ /datum/surgery_step/clamp_bleeders,
+ /datum/surgery_step/incise,
+ /datum/surgery_step/incise,
+ /datum/surgery_step/splice_nerves,
+ /datum/surgery_step/close)
+ possible_locs = list("chest")
+ bioware_target = BIOWARE_NERVES
+
+/datum/surgery_step/splice_nerves
+ name = "splice nerves"
+ accept_hand = TRUE
+ time = 155
+
+/datum/surgery_step/splice_nerves/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] starts splicing together [target]'s nerves.", "You start splicing together [target]'s nerves.")
+
+/datum/surgery_step/splice_nerves/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] successfully splices [target]'s nervous system!", "You successfully splice [target]'s nervous system!")
+ new /datum/bioware/spliced_nerves(target)
+ return TRUE
+
+/datum/bioware/spliced_nerves
+ name = "Spliced Nerves"
+ desc = "Nerves are connected to each other multiple times, greatly reducing the impact of stunning effects."
+ mod_type = "nerves"
+
+/datum/bioware/spliced_nerves/on_gain()
+ ..()
+ owner.physiology.stun_mod *= 0.5
+
+/datum/bioware/spliced_nerves/on_lose()
+ ..()
+ owner.physiology.stun_mod *= 2
\ No newline at end of file
diff --git a/code/modules/surgery/advanced/bioware/vein_threading.dm b/code/modules/surgery/advanced/bioware/vein_threading.dm
new file mode 100644
index 0000000000..082b87109e
--- /dev/null
+++ b/code/modules/surgery/advanced/bioware/vein_threading.dm
@@ -0,0 +1,41 @@
+/obj/item/disk/surgery/vein_threading
+ desc = "The disk provides instructions on how to modify the circulatory system to greatly slow down bleeding."
+ surgeries = list(/datum/surgery/advanced/bioware/vein_threading)
+
+/datum/surgery/advanced/bioware/vein_threading
+ name = "vein threading"
+ steps = list(/datum/surgery_step/incise,
+ /datum/surgery_step/retract_skin,
+ /datum/surgery_step/clamp_bleeders,
+ /datum/surgery_step/incise,
+ /datum/surgery_step/incise,
+ /datum/surgery_step/thread_veins,
+ /datum/surgery_step/close)
+ possible_locs = list("chest")
+ bioware_target = BIOWARE_CIRCULATION
+
+/datum/surgery_step/thread_veins
+ name = "thread veins"
+ accept_hand = TRUE
+ time = 125
+
+/datum/surgery_step/thread_veins/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] starts weaving [target]'s circulatory system.", "You start weaving [target]'s circulatory system.")
+
+/datum/surgery_step/thread_veins/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] weaves [target]'s circulatory system into a resistant mesh!", "You weave [target]'s circulatory system into a resistant mesh!")
+ new /datum/bioware/threaded_veins(target)
+ return TRUE
+
+/datum/bioware/threaded_veins
+ name = "Threaded Veins"
+ desc = "The circulatory system is woven into a mesh, severely reducing the amount of blood lost from wounds."
+ mod_type = "circulation"
+
+/datum/bioware/threaded_veins/on_gain()
+ ..()
+ owner.physiology.bleed_mod *= 0.25
+
+/datum/bioware/threaded_veins/on_lose()
+ ..()
+ owner.physiology.bleed_mod *= 4
\ No newline at end of file
diff --git a/code/modules/surgery/advanced/brainwashing.dm b/code/modules/surgery/advanced/brainwashing.dm
new file mode 100644
index 0000000000..bc397b7c66
--- /dev/null
+++ b/code/modules/surgery/advanced/brainwashing.dm
@@ -0,0 +1,58 @@
+/obj/item/disk/surgery/brainwashing
+ desc = "The disk provides instructions on how to impress an order on a brain, making it the primary objective of the patient."
+ surgeries = list(/datum/surgery/advanced/brainwashing)
+
+/datum/surgery/advanced/brainwashing
+ name = "brainwashing"
+ steps = list(
+ /datum/surgery_step/incise,
+ /datum/surgery_step/retract_skin,
+ /datum/surgery_step/saw,
+ /datum/surgery_step/clamp_bleeders,
+ /datum/surgery_step/brainwash,
+ /datum/surgery_step/close)
+
+ species = list(/mob/living/carbon/human)
+ possible_locs = list("head")
+
+/datum/surgery/advanced/brainwashing/can_start(mob/user, mob/living/carbon/target)
+ if(!..())
+ return FALSE
+ var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN)
+ if(!B)
+ return FALSE
+ return TRUE
+
+/datum/surgery_step/brainwash
+ name = "brainwash"
+ implements = list(/obj/item/hemostat = 85, /obj/item/wirecutters = 50, /obj/item/stack/packageWrap = 35, /obj/item/stack/cable_coil = 15)
+ time = 200
+ var/objective
+
+/datum/surgery_step/brainwash/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ objective = stripped_input(user, "Choose the objective to imprint on your victim's brain.", "Brainwashing", null, MAX_MESSAGE_LEN)
+ if(!objective)
+ return -1
+ user.visible_message("[user] begins to tinker with [target]'s brain.", "You begin to brainwash [target]...")
+
+/datum/surgery_step/brainwash/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ if(!target.mind)
+ user.visible_message("[target] doesn't respond to the brainwashing, as if [target.p_they()] lacked a mind...")
+ return FALSE
+ if(target.isloyal())
+ user.visible_message("You hear a faint buzzing from a device inside [target]'s brain, and the brainwashing is erased.")
+ return FALSE
+ user.visible_message("[user] successfully brainwashes [target]!", "You succeed in brainwashing [target].")
+ to_chat(target, "A new compulsion fills your mind... you feel forced to obey it!")
+ brainwash(target, objective)
+ message_admins("[key_name_admin(user)] surgically brainwashed [key_name_admin(target)] with the objective '[objective]'.")
+ log_game("[key_name(user)] surgically brainwashed [key_name(target)] with the objective '[objective]'.")
+ return TRUE
+
+/datum/surgery_step/brainwash/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ if(target.getorganslot(ORGAN_SLOT_BRAIN))
+ user.visible_message("[user] damages some brain tissue!", "You bruise some brain tissue!")
+ target.adjustBrainLoss(40)
+ else
+ user.visible_message("[user] suddenly notices that the brain [user.p_they()] [user.p_were()] working on is not there anymore.", "You suddenly notice that the brain you were working on is not there anymore.")
+ return FALSE
\ No newline at end of file
diff --git a/code/modules/surgery/advanced/lobotomy.dm b/code/modules/surgery/advanced/lobotomy.dm
new file mode 100644
index 0000000000..1e2db03e09
--- /dev/null
+++ b/code/modules/surgery/advanced/lobotomy.dm
@@ -0,0 +1,68 @@
+/obj/item/disk/surgery/lobotomy
+ desc = "The disk provides instructions on how to perform a lobotomy, to cure the most resilient brain ailments."
+ surgeries = list(/datum/surgery/advanced/lobotomy)
+
+/datum/surgery/advanced/lobotomy
+ name = "lobotomy"
+ steps = list(
+ /datum/surgery_step/incise,
+ /datum/surgery_step/retract_skin,
+ /datum/surgery_step/saw,
+ /datum/surgery_step/clamp_bleeders,
+ /datum/surgery_step/lobotomize,
+ /datum/surgery_step/close)
+
+ species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+ possible_locs = list("head")
+ requires_bodypart_type = 0
+
+/datum/surgery/advanced/lobotomy/can_start(mob/user, mob/living/carbon/target)
+ if(!..())
+ return FALSE
+ var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN)
+ if(!B)
+ return FALSE
+ return TRUE
+
+/datum/surgery_step/lobotomize
+ name = "perform lobotomy"
+ implements = list(/obj/item/scalpel = 85, /obj/item/melee/transforming/energy/sword = 55, /obj/item/kitchen/knife = 35,
+ /obj/item/shard = 25, /obj/item = 20)
+ time = 100
+
+/datum/surgery_step/lobotomize/tool_check(mob/user, obj/item/tool)
+ if(implement_type == /obj/item && !tool.is_sharp())
+ return FALSE
+ return TRUE
+
+/datum/surgery_step/lobotomize/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] begins to cut a piece of [target]'s brain.", "You begin to cut a piece of [target]'s brain...")
+
+/datum/surgery_step/lobotomize/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] successfully lobotomizes [target]!", "You succeed in lobotomizing [target].")
+ target.cure_all_traumas(TRAUMA_RESILIENCE_LOBOTOMY)
+ if(target.mind && target.mind.has_antag_datum(/datum/antagonist/brainwashed))
+ target.mind.remove_antag_datum(/datum/antagonist/brainwashed)
+ switch(rand(1,4))//Now let's see what hopefully-not-important part of the brain we cut off
+ if(1)
+ target.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_MAGIC)
+ if(2)
+ target.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_MAGIC)
+ if(3)
+ target.gain_trauma_type(BRAIN_TRAUMA_SPECIAL, TRAUMA_RESILIENCE_MAGIC)
+ return TRUE
+
+/datum/surgery_step/lobotomize/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ if(target.getorganslot(ORGAN_SLOT_BRAIN))
+ user.visible_message("[user] removes the wrong part, causing more damage!", "You remove the wrong part, causing more damage!")
+ target.adjustBrainLoss(80)
+ switch(rand(1,3))
+ if(1)
+ target.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_MAGIC)
+ if(2)
+ target.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_MAGIC)
+ if(3)
+ target.gain_trauma_type(BRAIN_TRAUMA_SPECIAL, TRAUMA_RESILIENCE_MAGIC)
+ else
+ user.visible_message("[user] suddenly notices that the brain [user.p_they()] [user.p_were()] working on is not there anymore.", "You suddenly notice that the brain you were working on is not there anymore.")
+ return FALSE
\ No newline at end of file
diff --git a/code/modules/surgery/advanced/necrotic_revival.dm b/code/modules/surgery/advanced/necrotic_revival.dm
new file mode 100644
index 0000000000..877fd40adf
--- /dev/null
+++ b/code/modules/surgery/advanced/necrotic_revival.dm
@@ -0,0 +1,38 @@
+/obj/item/disk/surgery/necrotic_revival
+ desc = "The disk provides instructions on how to make bodies keep working past death."
+ surgeries = list(/datum/surgery/advanced/necrotic_revival)
+
+/datum/surgery/advanced/necrotic_revival
+ name = "necrotic revival"
+ steps = list(/datum/surgery_step/incise,
+ /datum/surgery_step/retract_skin,
+ /datum/surgery_step/saw,
+ /datum/surgery_step/clamp_bleeders,
+ /datum/surgery_step/bionecrosis,
+ /datum/surgery_step/close)
+
+ possible_locs = list("head")
+
+/datum/surgery/advanced/necrotic_revival/can_start(mob/user, mob/living/carbon/target)
+ . = ..()
+ var/obj/item/organ/zombie_infection/ZI = target.getorganslot(ORGAN_SLOT_ZOMBIE)
+ if(ZI)
+ return FALSE
+
+/datum/surgery_step/bionecrosis
+ name = "start bionecrosis"
+ implements = list(/obj/item/hemostat = 100, /obj/item/screwdriver = 35, /obj/item/pen = 15)
+ time = 50
+
+/datum/surgery_step/bionecrosis/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] begins to stimulate [target]'s brain.", "You begin to stimulate [target]'s brain...")
+
+/datum/surgery_step/bionecrosis/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ if(!target.reagents.has_reagent("zombiepowder", 5) && !target.reagents.has_reagent("rezadone", 5))
+ user.visible_message("[target]'s brain seems unaffected.", "[target]'s body must be dosed with zombie powder or rezadone to complete the surgery!")
+ return FALSE
+ user.visible_message("[user] successfully grows a necrotic tumor on [target]'s brain!", "You succeed in growing a necrotic tumor on [target]'s brain.")
+ if(!target.getorganslot(ORGAN_SLOT_ZOMBIE))
+ var/obj/item/organ/zombie_infection/ZI = new()
+ ZI.Insert(target)
+ return TRUE
\ No newline at end of file
diff --git a/code/modules/surgery/advanced/pacification.dm b/code/modules/surgery/advanced/pacification.dm
new file mode 100644
index 0000000000..f692e12fce
--- /dev/null
+++ b/code/modules/surgery/advanced/pacification.dm
@@ -0,0 +1,40 @@
+/obj/item/disk/surgery/pacification
+ desc = "The disk provides instructions on how to suppress violence by manipulating the patient's brain."
+ surgeries = list(/datum/surgery/advanced/pacify)
+
+/datum/surgery/advanced/pacify
+ name = "violence neutralization"
+ steps = list(/datum/surgery_step/incise,
+ /datum/surgery_step/retract_skin,
+ /datum/surgery_step/saw,
+ /datum/surgery_step/clamp_bleeders,
+ /datum/surgery_step/pacify,
+ /datum/surgery_step/close)
+
+ species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+ possible_locs = list("head")
+ requires_bodypart_type = 0
+
+/datum/surgery/advanced/pacify/can_start(mob/user, mob/living/carbon/target)
+ . = ..()
+ var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN)
+ if(!B)
+ return FALSE
+
+/datum/surgery_step/pacify
+ name = "rewire brain"
+ implements = list(/obj/item/hemostat = 100, /obj/item/screwdriver = 35, /obj/item/pen = 15)
+ time = 40
+
+/datum/surgery_step/pacify/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] begins to reshape [target]'s brain.", "You begin to reshape [target]'s brain...")
+
+/datum/surgery_step/pacify/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] reshapes [target]'s brain!", "You succeed in reshaping [target]'s brain.")
+ target.gain_trauma(/datum/brain_trauma/severe/pacifism, TRAUMA_RESILIENCE_LOBOTOMY)
+ return TRUE
+
+/datum/surgery_step/pacify/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] reshapes [target]'s brain!", "You screwed up, and rewired [target]'s brain the wrong way around...")
+ target.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_LOBOTOMY)
+ return FALSE
\ No newline at end of file
diff --git a/code/modules/surgery/advanced/reconstruction.dm b/code/modules/surgery/advanced/reconstruction.dm
new file mode 100644
index 0000000000..39758a4b98
--- /dev/null
+++ b/code/modules/surgery/advanced/reconstruction.dm
@@ -0,0 +1,38 @@
+/obj/item/disk/surgery/reconstruction
+ desc = "The disk provides instructions on how to repair a body without the use of chemicals."
+ surgeries = list(/datum/surgery/advanced/reconstruction)
+
+/datum/surgery/advanced/reconstruction
+ name = "body reconstruction"
+ steps = list(/datum/surgery_step/incise,
+ /datum/surgery_step/incise,
+ /datum/surgery_step/retract_skin,
+ /datum/surgery_step/incise,
+ /datum/surgery_step/clamp_bleeders,
+ /datum/surgery_step/incise,
+ /datum/surgery_step/retract_skin,
+ /datum/surgery_step/reconstruct,
+ /datum/surgery_step/close)
+
+ species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+ possible_locs = list("chest")
+ requires_bodypart_type = 0
+
+/datum/surgery_step/reconstruct
+ name = "repair body"
+ implements = list(/obj/item/hemostat = 100, /obj/item/screwdriver = 35, /obj/item/pen = 15)
+ repeatable = TRUE
+ time = 25
+
+/datum/surgery_step/reconstruct/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] starts knitting some of [target]'s flesh back together.", "You start knitting some of [target]'s flesh back together.")
+
+/datum/surgery_step/reconstruct/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] fixes some of [target]'s wounds.", "You succeed in fixing some of [target]'s wounds.")
+ target.heal_bodypart_damage(10,10)
+ return TRUE
+
+/datum/surgery_step/reconstruct/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] screws up!", "You screwed up!")
+ target.take_bodypart_damage(5,0)
+ return FALSE
\ No newline at end of file
diff --git a/code/modules/surgery/advanced/revival.dm b/code/modules/surgery/advanced/revival.dm
new file mode 100644
index 0000000000..eb48968a0c
--- /dev/null
+++ b/code/modules/surgery/advanced/revival.dm
@@ -0,0 +1,78 @@
+/obj/item/disk/surgery/revival
+ desc = "The disk provides instructions on how to bring a corpse back to life."
+ surgeries = list(/datum/surgery/advanced/revival)
+
+/datum/surgery/advanced/revival
+ name = "revival"
+ steps = list(/datum/surgery_step/incise,
+ /datum/surgery_step/retract_skin,
+ /datum/surgery_step/saw,
+ /datum/surgery_step/clamp_bleeders,
+ /datum/surgery_step/incise,
+ /datum/surgery_step/revive,
+ /datum/surgery_step/close)
+
+ species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+ possible_locs = list("head")
+ requires_bodypart_type = 0
+
+/datum/surgery/advanced/revival/can_start(mob/user, mob/living/carbon/target)
+ if(!..())
+ return FALSE
+ if(target.stat != DEAD)
+ return FALSE
+ if(target.suiciding || target.has_trait(TRAIT_NOCLONE) || target.hellbound)
+ return FALSE
+ var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN)
+ if(!B)
+ return FALSE
+ return TRUE
+
+/datum/surgery_step/revive
+ name = "repair body"
+ implements = list(/obj/item/twohanded/shockpaddles = 100, /obj/item/melee/baton = 75, /obj/item/gun/energy = 60)
+ time = 120
+
+/datum/surgery_step/revive/tool_check(mob/user, obj/item/tool)
+ . = TRUE
+ if(istype(tool, /obj/item/twohanded/shockpaddles))
+ var/obj/item/twohanded/shockpaddles/S = tool
+ if((S.req_defib && !S.defib.powered) || !S.wielded || S.cooldown || S.busy)
+ to_chat(user, "You need to wield both paddles, and [S.defib] must be powered!")
+ return FALSE
+ if(istype(tool, /obj/item/melee/baton))
+ var/obj/item/melee/baton/B = tool
+ if(!B.status)
+ to_chat(user, "[B] needs to be active!")
+ return FALSE
+ if(istype(tool, /obj/item/gun/energy))
+ var/obj/item/gun/energy/E = tool
+ if(E.chambered && istype(E.chambered, /obj/item/ammo_casing/energy/electrode))
+ return TRUE
+ else
+ to_chat(user, "You need an electrode for this!")
+ return FALSE
+
+/datum/surgery_step/revive/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] prepares to shock [target]'s brain with [tool].", "You prepare to give [target]'s brain the spark of life with [tool].")
+ target.notify_ghost_cloning("Someone is trying to zap your brain. Re-enter your corpse if you want to be revived!", source = target)
+
+/datum/surgery_step/revive/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] send a powerful shock to [target]'s brain with [tool]...", "You successfully shock [target]'s brain with [tool]...")
+ playsound(get_turf(target), 'sound/magic/lightningbolt.ogg', 50, 1)
+ target.adjustOxyLoss(-50, 0)
+ target.updatehealth()
+ if(target.revive())
+ user.visible_message("...[target] wakes up, alive and aware!", "IT'S ALIVE!")
+ target.emote("gasp")
+ target.adjustBrainLoss(50, 199) //MAD SCIENCE
+ return TRUE
+ else
+ user.visible_message("...[target.p_they()] convulses, then lies still.")
+ return FALSE
+
+/datum/surgery_step/revive/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] send a powerful shock to [target]'s brain with [tool], but [target.p_they()] doesn't react.", "You shock [target]'s brain with [tool], but [target.p_they()] doesn't react.")
+ playsound(get_turf(target), 'sound/magic/lightningbolt.ogg', 50, 1)
+ target.adjustBrainLoss(15, 199)
+ return FALSE
\ No newline at end of file
diff --git a/code/modules/surgery/advanced/viral_bonding.dm b/code/modules/surgery/advanced/viral_bonding.dm
new file mode 100644
index 0000000000..bf1e90622b
--- /dev/null
+++ b/code/modules/surgery/advanced/viral_bonding.dm
@@ -0,0 +1,61 @@
+/obj/item/disk/surgery/viral_bonding
+ desc = "The disk provides instructions on how to force symbiosis between a virus and its host."
+ surgeries = list(/datum/surgery/advanced/viral_bonding)
+
+/datum/surgery/advanced/viral_bonding
+ name = "viral bonding"
+ steps = list(/datum/surgery_step/incise,
+ /datum/surgery_step/retract_skin,
+ /datum/surgery_step/clamp_bleeders,
+ /datum/surgery_step/incise,
+ /datum/surgery_step/viral_bond,
+ /datum/surgery_step/close)
+
+ species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+ possible_locs = list("chest")
+
+/datum/surgery/advanced/viral_bonding/can_start(mob/user, mob/living/carbon/target)
+ if(!..())
+ return FALSE
+ if(!LAZYLEN(target.viruses))
+ return FALSE
+ return TRUE
+
+/datum/surgery_step/viral_bond
+ name = "viral bond"
+ implements = list(/obj/item/cautery = 100, /obj/item/weldingtool = 50,
+ /obj/item/lighter = 35, /obj/item/match = 30)
+ time = 100
+
+/datum/surgery_step/viral_bond/tool_check(mob/user, obj/item/tool)
+ if(istype(tool, /obj/item/cautery))
+ return TRUE
+
+ if(istype(tool, /obj/item/weldingtool))
+ var/obj/item/weldingtool/WT = tool
+ if(WT.isOn())
+ return TRUE
+
+ else if(istype(tool, /obj/item/lighter))
+ var/obj/item/lighter/L = tool
+ if(L.lit)
+ return TRUE
+
+ else if(istype(tool, /obj/item/match))
+ var/obj/item/match/M = tool
+ if(M.lit)
+ return TRUE
+ return FALSE
+
+/datum/surgery_step/viral_bond/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] starts heating [target]'s bone marrow with [tool]...", "You start heating [target]'s bone marrow with [tool]...")
+
+/datum/surgery_step/viral_bond/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ if(!target.reagents.has_reagent("spaceacillin", 5) || !target.reagents.has_reagent("virusfood", 5) || !target.reagents.has_reagent("formaldehyde", 5))
+ user.visible_message("[target]'s seems unaffected.", "[target]'s body must be dosed with spaceacillin, virus food and formaldehyde to complete the surgery!")
+ return FALSE
+ user.visible_message("[target]'s bone marrow begins pulsing slowly.", "[target]'s bone marrow begins pulsing slowly. The viral bonding is complete.")
+ for(var/X in target.viruses)
+ var/datum/disease/D = X
+ D.carrier = TRUE
+ return TRUE
\ No newline at end of file
diff --git a/code/modules/surgery/brain_surgery.dm b/code/modules/surgery/brain_surgery.dm
index f2884d1da8..840c40a102 100644
--- a/code/modules/surgery/brain_surgery.dm
+++ b/code/modules/surgery/brain_surgery.dm
@@ -20,7 +20,6 @@
/datum/surgery/brain_surgery/can_start(mob/user, mob/living/carbon/target)
var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN)
if(!B)
- to_chat(user, "It's hard to do surgery on someone's brain when they don't have one.")
return FALSE
return TRUE
@@ -29,14 +28,17 @@
/datum/surgery_step/fix_brain/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
user.visible_message("[user] successfully fixes [target]'s brain!", "You succeed in fixing [target]'s brain.")
+ if(target.mind && target.mind.has_antag_datum(/datum/antagonist/brainwashed))
+ target.mind.remove_antag_datum(/datum/antagonist/brainwashed)
target.adjustBrainLoss(-60)
- target.cure_all_traumas()
+ target.cure_all_traumas(TRAUMA_RESILIENCE_SURGERY)
return TRUE
/datum/surgery_step/fix_brain/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
if(target.getorganslot(ORGAN_SLOT_BRAIN))
user.visible_message("[user] screws up, causing more damage!", "You screw up, causing more damage!")
- target.adjustBrainLoss(80)
+ target.adjustBrainLoss(60)
+ target.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_LOBOTOMY)
else
user.visible_message("[user] suddenly notices that the brain [user.p_they()] [user.p_were()] working on is not there anymore.", "You suddenly notice that the brain you were working on is not there anymore.")
return FALSE
\ No newline at end of file
diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm
index e293d7c401..7b40b790fa 100644
--- a/code/modules/surgery/surgery.dm
+++ b/code/modules/surgery/surgery.dm
@@ -38,14 +38,17 @@
// put special restrictions here
return 1
-
-/datum/surgery/proc/next_step(mob/user)
+/datum/surgery/proc/next_step(mob/user, intent)
if(step_in_progress)
return 1
+ var/try_to_fail = FALSE
+ if(intent == INTENT_DISARM)
+ try_to_fail = TRUE
+
var/datum/surgery_step/S = get_surgery_step()
if(S)
- if(S.try_op(user, target, user.zone_selected, user.get_active_held_item(), src))
+ if(S.try_op(user, target, user.zone_selected, user.get_active_held_item(), src, try_to_fail))
return 1
return 0
@@ -78,8 +81,44 @@
return propability + success_multiplier
+/datum/surgery/advanced
+ name = "advanced surgery"
+/datum/surgery/advanced/can_start(mob/user, mob/living/carbon/target)
+ if(!..())
+ return FALSE
+ //Abductor scientists need no instructions
+ if(isabductor(user))
+ var/mob/living/carbon/human/H = user
+ var/datum/species/abductor/S = H.dna.species
+ if(S.scientist)
+ return TRUE
+ var/turf/T = get_turf(target)
+ var/obj/structure/table/optable/table = locate(/obj/structure/table/optable, T)
+ if(!table || !table.computer)
+ return FALSE
+ if(table.computer.stat & (NOPOWER|BROKEN))
+ return FALSE
+ if(type in table.computer.advanced_surgeries)
+ return TRUE
+
+/obj/item/disk/surgery
+ name = "Surgery Procedure Disk"
+ desc = "A disk that contains advanced surgery procedures, must be loaded into an Operating Console."
+ icon_state = "datadisk1"
+ materials = list(MAT_METAL=300, MAT_GLASS=100)
+ var/list/surgeries
+
+/obj/item/disk/surgery/debug
+ name = "Debug Surgery Disk"
+ desc = "A disk that contains all existing surgery procedures."
+ icon_state = "datadisk1"
+ materials = list(MAT_METAL=300, MAT_GLASS=100)
+
+/obj/item/disk/surgery/debug/Initialize()
+ . = ..()
+ surgeries = subtypesof(/datum/surgery/advanced)
//INFO
//Check /mob/living/carbon/attackby for how surgery progresses, and also /mob/living/carbon/attack_hand.
diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm
index fa9e45ca4b..d392190cd8 100644
--- a/code/modules/surgery/surgery_step.dm
+++ b/code/modules/surgery/surgery_step.dm
@@ -1,108 +1,108 @@
-/datum/surgery_step
- var/name
- var/list/implements = list() //format is path = probability of success. alternatively
- var/implement_type = null //the current type of implement used. This has to be stored, as the actual typepath of the tool may not match the list type.
- var/accept_hand = 0 //does the surgery step require an open hand? If true, ignores implements. Compatible with accept_any_item.
- var/accept_any_item = 0 //does the surgery step accept any item? If true, ignores implements. Compatible with require_hand.
- var/time = 10 //how long does the step take?
- var/repeatable = 0 //does this step may be repeated? Make shure it isn't last step, or it used in surgery with `can_cancel = 1`. Or surgion will be stuck in the loop
-
-
-/datum/surgery_step/proc/try_op(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- var/success = FALSE
- if(accept_hand)
- if(!tool)
- success = TRUE
-
- if(accept_any_item)
- if(tool && tool_check(user, tool))
- success = TRUE
-
- else if(tool)
- for(var/key in implements)
- var/match = FALSE
-
- if(ispath(key) && istype(tool, key))
- match = TRUE
- else if(tool.tool_behaviour == key)
- match = TRUE
-
- if(match)
- implement_type = key
- if(tool_check(user, tool))
- success = TRUE
- break
-
- if(success)
- if(target_zone == surgery.location)
- if(get_location_accessible(target, target_zone) || surgery.ignore_clothes)
- initiate(user, target, target_zone, tool, surgery)
- return 1
- else
- to_chat(user, "You need to expose [target]'s [parse_zone(target_zone)] to perform surgery on it!")
- return 1 //returns 1 so we don't stab the guy in the dick or wherever.
-
- if(repeatable)
- var/datum/surgery_step/next_step = surgery.get_surgery_next_step()
- if(next_step)
- surgery.status++
- if(next_step.try_op(user, target, user.zone_selected, user.get_active_held_item(), surgery))
- return 1
- else
- surgery.status--
-
- if(iscyborg(user) && user.a_intent != INTENT_HARM) //to save asimov borgs a LOT of heartache
- return 1
-
- return 0
-
-
-/datum/surgery_step/proc/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- surgery.step_in_progress = 1
-
- var/speed_mod = 1
-
- if(preop(user, target, target_zone, tool, surgery) == -1)
- surgery.step_in_progress = 0
- return
-
- if(tool)
- speed_mod = tool.toolspeed
-
- if(do_after(user, time * speed_mod, target = target))
- var/advance = 0
- var/prob_chance = 100
-
- if(implement_type) //this means it isn't a require hand or any item step.
- prob_chance = implements[implement_type]
- prob_chance *= surgery.get_propability_multiplier()
-
- if(prob(prob_chance) || iscyborg(user))
- if(success(user, target, target_zone, tool, surgery))
- advance = 1
- else
- if(failure(user, target, target_zone, tool, surgery))
- advance = 1
-
- if(advance && !repeatable)
- surgery.status++
- if(surgery.status > surgery.steps.len)
- surgery.complete()
-
- surgery.step_in_progress = 0
-
-
-/datum/surgery_step/proc/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- user.visible_message("[user] begins to perform surgery on [target].", "You begin to perform surgery on [target]...")
-
-
-/datum/surgery_step/proc/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- user.visible_message("[user] succeeds!", "You succeed.")
- return 1
-
-/datum/surgery_step/proc/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- user.visible_message("[user] screws up!", "You screw up!")
- return 0
-
-/datum/surgery_step/proc/tool_check(mob/user, obj/item/tool)
- return 1
+/datum/surgery_step
+ var/name
+ var/list/implements = list() //format is path = probability of success. alternatively
+ var/implement_type = null //the current type of implement used. This has to be stored, as the actual typepath of the tool may not match the list type.
+ var/accept_hand = 0 //does the surgery step require an open hand? If true, ignores implements. Compatible with accept_any_item.
+ var/accept_any_item = 0 //does the surgery step accept any item? If true, ignores implements. Compatible with require_hand.
+ var/time = 10 //how long does the step take?
+ var/repeatable = 0 //does this step may be repeated? Make shure it isn't last step, or it used in surgery with `can_cancel = 1`. Or surgion will be stuck in the loop
+
+
+/datum/surgery_step/proc/try_op(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
+ var/success = FALSE
+ if(accept_hand)
+ if(!tool)
+ success = TRUE
+
+ if(accept_any_item)
+ if(tool && tool_check(user, tool))
+ success = TRUE
+
+ else if(tool)
+ for(var/key in implements)
+ var/match = FALSE
+
+ if(ispath(key) && istype(tool, key))
+ match = TRUE
+ else if(tool.tool_behaviour == key)
+ match = TRUE
+
+ if(match)
+ implement_type = key
+ if(tool_check(user, tool))
+ success = TRUE
+ break
+
+ if(success)
+ if(target_zone == surgery.location)
+ if(get_location_accessible(target, target_zone) || surgery.ignore_clothes)
+ initiate(user, target, target_zone, tool, surgery, try_to_fail)
+ return 1
+ else
+ to_chat(user, "You need to expose [target]'s [parse_zone(target_zone)] to perform surgery on it!")
+ return 1 //returns 1 so we don't stab the guy in the dick or wherever.
+
+ if(repeatable)
+ var/datum/surgery_step/next_step = surgery.get_surgery_next_step()
+ if(next_step)
+ surgery.status++
+ if(next_step.try_op(user, target, user.zone_selected, user.get_active_held_item(), surgery))
+ return 1
+ else
+ surgery.status--
+
+ if(iscyborg(user) && user.a_intent != INTENT_HARM) //to save asimov borgs a LOT of heartache
+ return 1
+
+ return 0
+
+
+/datum/surgery_step/proc/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
+ surgery.step_in_progress = 1
+
+ var/speed_mod = 1
+
+ if(preop(user, target, target_zone, tool, surgery) == -1)
+ surgery.step_in_progress = 0
+ return
+
+ if(tool)
+ speed_mod = tool.toolspeed
+
+ if(do_after(user, time * speed_mod, target = target))
+ var/advance = 0
+ var/prob_chance = 100
+
+ if(implement_type) //this means it isn't a require hand or any item step.
+ prob_chance = implements[implement_type]
+ prob_chance *= surgery.get_propability_multiplier()
+
+ if((prob(prob_chance) || iscyborg(user)) && !try_to_fail)
+ if(success(user, target, target_zone, tool, surgery))
+ advance = 1
+ else
+ if(failure(user, target, target_zone, tool, surgery))
+ advance = 1
+
+ if(advance && !repeatable)
+ surgery.status++
+ if(surgery.status > surgery.steps.len)
+ surgery.complete()
+
+ surgery.step_in_progress = 0
+
+
+/datum/surgery_step/proc/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] begins to perform surgery on [target].", "You begin to perform surgery on [target]...")
+
+
+/datum/surgery_step/proc/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] succeeds!", "You succeed.")
+ return 1
+
+/datum/surgery_step/proc/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] screws up!", "You screw up!")
+ return 0
+
+/datum/surgery_step/proc/tool_check(mob/user, obj/item/tool)
+ return 1
diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm
index d02ee0373d..89983a946e 100644
--- a/code/modules/uplink/uplink_items.dm
+++ b/code/modules/uplink/uplink_items.dm
@@ -710,7 +710,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
name = "Chameleon Kit"
desc = "A set of items that contain chameleon technology allowing you to disguise as pretty much anything on the station, and more!"
item = /obj/item/storage/box/syndie_kit/chameleon
- cost = 2
+ cost = 2
exclude_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/stealthy_tools/syndigaloshes
@@ -879,6 +879,14 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
item = /obj/item/storage/backpack/duffelbag/syndie/surgery
cost = 3
+/datum/uplink_item/device_tools/brainwash_disk
+ name = "Brainwashing Surgery Program"
+ desc = "A disk containing the procedure to perform a brainwashing surgery, allowing you to implant an objective onto a target. \
+ Insert into an Operating Console to enable the procedure."
+ item = /obj/item/disk/surgery/brainwashing
+ restricted_roles = list("Medical Doctor")
+ cost = 5
+
/datum/uplink_item/device_tools/military_belt
name = "Chest Rig"
desc = "A robust seven-slot set of webbing that is capable of holding all manner of tactical equipment."
diff --git a/tgstation.dme b/tgstation.dme
index cb9e557f2b..4052c7ee8e 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -1113,6 +1113,7 @@
#include "code\modules\antagonists\blob\blob\blobs\node.dm"
#include "code\modules\antagonists\blob\blob\blobs\resource.dm"
#include "code\modules\antagonists\blob\blob\blobs\shield.dm"
+#include "code\modules\antagonists\brainwashing\brainwashing.dm"
#include "code\modules\antagonists\brother\brother.dm"
#include "code\modules\antagonists\changeling\cellular_emporium.dm"
#include "code\modules\antagonists\changeling\changeling.dm"
@@ -1860,6 +1861,7 @@
#include "code\modules\mob\living\carbon\human\interactive.dm"
#include "code\modules\mob\living\carbon\human\inventory.dm"
#include "code\modules\mob\living\carbon\human\life.dm"
+#include "code\modules\mob\living\carbon\human\physiology.dm"
#include "code\modules\mob\living\carbon\human\say.dm"
#include "code\modules\mob\living\carbon\human\species.dm"
#include "code\modules\mob\living\carbon\human\status_procs.dm"
@@ -2430,6 +2432,18 @@
#include "code\modules\surgery\surgery.dm"
#include "code\modules\surgery\surgery_step.dm"
#include "code\modules\surgery\tools.dm"
+#include "code\modules\surgery\advanced\brainwashing.dm"
+#include "code\modules\surgery\advanced\lobotomy.dm"
+#include "code\modules\surgery\advanced\necrotic_revival.dm"
+#include "code\modules\surgery\advanced\pacification.dm"
+#include "code\modules\surgery\advanced\reconstruction.dm"
+#include "code\modules\surgery\advanced\revival.dm"
+#include "code\modules\surgery\advanced\viral_bonding.dm"
+#include "code\modules\surgery\advanced\bioware\bioware.dm"
+#include "code\modules\surgery\advanced\bioware\bioware_surgery.dm"
+#include "code\modules\surgery\advanced\bioware\nerve_grounding.dm"
+#include "code\modules\surgery\advanced\bioware\nerve_splicing.dm"
+#include "code\modules\surgery\advanced\bioware\vein_threading.dm"
#include "code\modules\surgery\bodyparts\bodyparts.dm"
#include "code\modules\surgery\bodyparts\dismemberment.dm"
#include "code\modules\surgery\bodyparts\head.dm"