diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm
index 96f9c11e17..c53ba430e0 100644
--- a/code/modules/research/designs/medical_designs.dm
+++ b/code/modules/research/designs/medical_designs.dm
@@ -725,12 +725,22 @@
var/surgery
/datum/design/surgery/experimental_dissection
- name = "Experimental Dissection"
- desc = "A surgical procedure which deeply analyzes the biology of a corpse, and automatically adds new findings to the research database."
- id = "surgery_exp_dissection"
- surgery = /datum/surgery/experimental_dissection
+ name = "Advanced Dissection"
+ desc = "A surgical procedure which analyzes the biology of a corpse, and automatically adds new findings to the research database."
+ id = "surgery_adv_dissection"
+ surgery = /datum/surgery/advanced/experimental_dissection/adv
research_icon_state = "surgery_chest"
+/datum/design/surgery/experimental_dissection/exp
+ name = "Experimental Dissection"
+ id = "surgery_exp_dissection"
+ surgery = /datum/surgery/advanced/experimental_dissection/exp
+
+/datum/design/surgery/experimental_dissection/exp
+ name = "Extraterrestrial Dissection"
+ id = "surgery_ext_dissection"
+ surgery = /datum/surgery/advanced/experimental_dissection/alien
+
/datum/design/surgery/lobotomy
name = "Lobotomy"
desc = "An invasive surgical procedure which guarantees removal of almost all brain traumas, but might cause another permanent trauma in return."
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index 93370af547..cb5112353e 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -115,7 +115,7 @@
display_name = "Advanced Surgery"
description = "When simple medicine doesn't cut it."
prereq_ids = list("adv_biotech")
- design_ids = list("surgery_lobotomy", "surgery_reconstruction", "surgery_toxinhealing", "organbox")
+ design_ids = list("surgery_lobotomy", "surgery_reconstruction", "surgery_toxinhealing", "organbox", "surgery_adv_dissection")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
@@ -124,7 +124,7 @@
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_ligament_hook","surgery_ligament_reinforcement","surgery_viral_bond")
+ design_ids = list("surgery_revival","surgery_pacify","surgery_vein_thread","surgery_nerve_splice","surgery_nerve_ground","surgery_ligament_hook","surgery_ligament_reinforcement","surgery_viral_bond", "surgery_exp_dissection")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
export_price = 5000
@@ -133,7 +133,7 @@
display_name = "Alien Surgery"
description = "Abductors did nothing wrong."
prereq_ids = list("exp_surgery", "alientech")
- design_ids = list("surgery_brainwashing","surgery_zombie")
+ design_ids = list("surgery_brainwashing","surgery_zombie", "surgery_ext_dissection")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000)
export_price = 5000
diff --git a/code/modules/surgery/experimental_dissection.dm b/code/modules/surgery/experimental_dissection.dm
index c8daf9412e..6dc9441b0c 100644
--- a/code/modules/surgery/experimental_dissection.dm
+++ b/code/modules/surgery/experimental_dissection.dm
@@ -1,61 +1,87 @@
-/datum/surgery/experimental_dissection
- name = "Experimental Dissection"
- desc = "A surgical procedure which deeply analyzes the biology of a corpse, and automatically adds new findings to the research database."
+#define BASE_HUMAN_REWARD 500
+#define EXPDIS_FAIL_MSG "You dissect [target], but do not find anything particularly interesting."
+
+/datum/surgery/advanced/experimental_dissection
+ name = "Dissection"
+ desc = "A surgical procedure which analyzes the biology of a corpse, and automatically adds new findings to the research database."
steps = list(/datum/surgery_step/incise,
/datum/surgery_step/retract_skin,
/datum/surgery_step/clamp_bleeders,
- /datum/surgery_step/incise,
/datum/surgery_step/dissection,
+ /datum/surgery_step/clamp_bleeders,
/datum/surgery_step/close)
possible_locs = list(BODY_ZONE_CHEST)
- target_mobtypes = list(/mob/living/carbon) //Feel free to dissect devils but they're magic.
+ target_mobtypes = list(/mob/living) //Feel free to dissect devils but they're magic.
+ replaced_by = /datum/surgery/advanced/experimental_dissection/adv
+ requires_tech = FALSE
+ var/value_multiplier = 1
-/datum/surgery/experimental_dissection/can_start(mob/user, mob/living/carbon/target)
+/datum/surgery/advanced/experimental_dissection/can_start(mob/user, mob/living/target)
. = ..()
- if(HAS_TRAIT(target, TRAIT_DISSECTED))
+ if(HAS_TRAIT_FROM(target, TRAIT_DISSECTED,"[name]"))
return FALSE
- if(iscyborg(user))
- return FALSE //robots cannot be creative
- //(also this surgery shouldn't be consistently successful, and cyborgs have a 100% success rate on surgery)
if(target.stat != DEAD)
return FALSE
/datum/surgery_step/dissection
name = "dissection"
- implements = list(/obj/item/scalpel = 60, /obj/item/kitchen/knife = 30, /obj/item/shard = 15)
+ implements = list(/obj/item/scalpel/augment = 75, /obj/item/scalpel/advanced = 60, /obj/item/scalpel = 45, /obj/item/kitchen/knife = 20, /obj/item/shard = 10)// special tools not only cut down time but also improve probability
time = 125
+ silicons_obey_prob = TRUE
+ repeatable = TRUE
/datum/surgery_step/dissection/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "You start dissecting [target].",
"[user] starts dissecting [target].",
"[user] starts dissecting [target].")
-/datum/surgery_step/dissection/proc/check_value(mob/living/carbon/target)
+/datum/surgery_step/dissection/proc/check_value(mob/living/target, datum/surgery/advanced/experimental_dissection/ED)
+ var/cost = BASE_HUMAN_REWARD
+ var/multi_surgery_adjust = 0
+
+ //determine bonus applied
if(isalienroyal(target))
- return 10000
+ cost = (BASE_HUMAN_REWARD*10)
else if(isalienadult(target))
- return 5000
+ cost = (BASE_HUMAN_REWARD*5)
else if(ismonkey(target))
- return 1000
+ cost = (BASE_HUMAN_REWARD*0.5)
else if(ishuman(target))
var/mob/living/carbon/human/H = target
- if(H.dna && H.dna.species)
+ if(H?.dna?.species)
if(isabductor(H))
- return 8000
- if(isgolem(H) || iszombie(H))
- return 4000
- if(isjellyperson(H) || ispodperson(H))
- return 3000
- return 2000
+ cost = (BASE_HUMAN_REWARD*4)
+ else if(isgolem(H) || iszombie(H))
+ cost = (BASE_HUMAN_REWARD*3)
+ /*else if(isjellyperson(H) || ispodperson(H)) CITADEL CHANGE: jelly and pod being available roundstart shouldn't give additional points
+ cost = (BASE_HUMAN_REWARD*2)*/
+ else
+ cost = (BASE_HUMAN_REWARD * 0.6)
-/datum/surgery_step/dissection/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- display_results(user, target, "You dissect [target], and add your discoveries to the research database!",
- "[user] dissects [target], adding [user.p_their()] discoveries to the research database!",
+
+
+ //now we do math for surgeries already done (no double dipping!).
+ for(var/i in typesof(/datum/surgery/advanced/experimental_dissection))
+ var/datum/surgery/advanced/experimental_dissection/cringe = i
+ if(HAS_TRAIT_FROM(target,TRAIT_DISSECTED,"[initial(cringe.name)]"))
+ multi_surgery_adjust = max(multi_surgery_adjust,initial(cringe.value_multiplier)) - 1
+
+ multi_surgery_adjust *= cost
+
+ //multiply by multiplier in surgery
+ cost *= ED.value_multiplier
+ return (cost-multi_surgery_adjust)
+
+/datum/surgery_step/dissection/success(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ var/points_earned = check_value(target, surgery)
+ display_results(user, target, "You dissect [target], and add your [points_earned] point\s worth of discoveries to the research database!",
+ "[user] dissects [target], discovering [points_earned] point\s of data!",
"[user] dissects [target]!")
- SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = check_value(target)))
+ SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = points_earned))
var/obj/item/bodypart/L = target.get_bodypart(BODY_ZONE_CHEST)
target.apply_damage(80, BRUTE, L)
- ADD_TRAIT(target, TRAIT_DISSECTED, "surgery")
+ ADD_TRAIT(target, TRAIT_DISSECTED, "[surgery.name]")
+ repeatable = FALSE
return TRUE
/datum/surgery_step/dissection/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -63,7 +89,28 @@
"[user] dissects [target], however it seems [user.p_they()] didn't find anything useful.",
"[user] dissects [target], but looks a little dissapointed.")
SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = (check_value(target) * 0.2)))
+ SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = (round(check_value(target, surgery) * 0.01))))
var/obj/item/bodypart/L = target.get_bodypart(BODY_ZONE_CHEST)
target.apply_damage(80, BRUTE, L)
- ADD_TRAIT(target, TRAIT_DISSECTED, "surgery")
- return TRUE
\ No newline at end of file
+ return TRUE
+
+/datum/surgery/advanced/experimental_dissection/adv
+ name = "Thorough Dissection"
+ value_multiplier = 2
+ replaced_by = /datum/surgery/advanced/experimental_dissection/exp
+ requires_tech = TRUE
+
+/datum/surgery/advanced/experimental_dissection/exp
+ name = "Experimental Dissection"
+ value_multiplier = 5
+ replaced_by = /datum/surgery/advanced/experimental_dissection/alien
+ requires_tech = TRUE
+
+/datum/surgery/advanced/experimental_dissection/alien
+ name = "Extraterrestrial Dissection"
+ value_multiplier = 10
+ requires_tech = TRUE
+
+
+#undef BASE_HUMAN_REWARD
+#undef EXPDIS_FAIL_MSG
diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm
index ccf5ad4386..a220abba6c 100644
--- a/code/modules/surgery/surgery.dm
+++ b/code/modules/surgery/surgery.dm
@@ -1,3 +1,4 @@
+<<<<<<< HEAD
/datum/surgery
var/name = "surgery"
var/desc = "surgery description"
@@ -154,3 +155,179 @@
//RESOLVED ISSUES //"Todo" jobs that have been completed
//combine hands/feet into the arms - Hands/feet were removed - RR
//surgeries (not steps) that can be initiated on any body part (corresponding with damage locations) - Call this one done, see possible_locs var - c0
+=======
+/datum/surgery
+ var/name = "surgery"
+ var/desc = "surgery description"
+ var/status = 1
+ var/list/steps = list() //Steps in a surgery
+ var/step_in_progress = FALSE //Actively performing a Surgery
+ var/can_cancel = TRUE //Can cancel this surgery after step 1 with cautery
+ var/list/target_mobtypes = list(/mob/living/carbon/human) //Acceptable Species
+ var/location = BODY_ZONE_CHEST //Surgery location
+ var/requires_bodypart_type = BODYPART_ORGANIC //Prevents you from performing an operation on incorrect limbs. 0 for any limb type
+ var/list/possible_locs = list() //Multiple locations
+ var/ignore_clothes = FALSE //This surgery ignores clothes
+ var/mob/living/carbon/target //Operation target mob
+ var/obj/item/bodypart/operated_bodypart //Operable body part
+ var/requires_bodypart = TRUE //Surgery available only when a bodypart is present, or only when it is missing.
+ var/success_multiplier = 0 //Step success propability multiplier
+ var/requires_real_bodypart = FALSE //Some surgeries don't work on limbs that don't really exist
+ var/lying_required = TRUE //Does the vicitm needs to be lying down.
+ var/self_operable = FALSE //Can the surgery be performed on yourself.
+ var/requires_tech = FALSE //handles techweb-oriented surgeries, previously restricted to the /advanced subtype (You still need to add designs)
+ var/replaced_by //type; doesn't show up if this type exists. Set to /datum/surgery if you want to hide a "base" surgery (useful for typing parents IE healing.dm just make sure to null it out again)
+
+/datum/surgery/New(surgery_target, surgery_location, surgery_bodypart)
+ ..()
+ if(surgery_target)
+ target = surgery_target
+ target.surgeries += src
+ if(surgery_location)
+ location = surgery_location
+ if(surgery_bodypart)
+ operated_bodypart = surgery_bodypart
+
+/datum/surgery/Destroy()
+ if(target)
+ target.surgeries -= src
+ target = null
+ operated_bodypart = null
+ return ..()
+
+
+/datum/surgery/proc/can_start(mob/user, mob/living) //FALSE to not show in list
+ . = TRUE
+ if(replaced_by == /datum/surgery)
+ return FALSE
+
+ if(HAS_TRAIT(user, TRAIT_SURGEON) || HAS_TRAIT(user.mind, TRAIT_SURGEON))
+ if(replaced_by)
+ return FALSE
+ else
+ return TRUE
+
+ if(!requires_tech && !replaced_by)
+ return TRUE
+ // True surgeons (like abductor scientists) need no instructions
+
+ if(requires_tech)
+ . = FALSE
+
+ if(iscyborg(user))
+ var/mob/living/silicon/robot/R = user
+ var/obj/item/surgical_processor/SP = locate() in R.module.modules
+ if(!SP || (replaced_by in SP.advanced_surgeries))
+ return FALSE
+ if(type in SP.advanced_surgeries)
+ return TRUE
+
+
+ var/turf/T = get_turf(target)
+ var/obj/structure/table/optable/table = locate(/obj/structure/table/optable, T)
+ if(table)
+ if(!table.computer)
+ return FALSE
+ if(table.computer.stat & (NOPOWER|BROKEN) || (replaced_by in table.computer.advanced_surgeries))
+ return FALSE
+ if(type in table.computer.advanced_surgeries)
+ return TRUE
+
+
+/datum/surgery/proc/next_step(mob/user, intent)
+ if(step_in_progress)
+ return TRUE
+
+ var/try_to_fail = FALSE
+ if(intent == INTENT_DISARM)
+ try_to_fail = TRUE
+
+ var/datum/surgery_step/S = get_surgery_step()
+ if(S)
+ var/obj/item/tool = user.get_active_held_item()
+ if(S.try_op(user, target, user.zone_selected, tool, src, try_to_fail))
+ return TRUE
+ if(iscyborg(user) && user.a_intent != INTENT_HARM) //to save asimov borgs a LOT of heartache
+ return TRUE
+ if(tool.item_flags & SURGICAL_TOOL) //Just because you used the wrong tool it doesn't mean you meant to whack the patient with it
+ to_chat(user, "This step requires a different tool!")
+ return TRUE
+ return FALSE
+
+/datum/surgery/proc/get_surgery_step()
+ var/step_type = steps[status]
+ return new step_type
+
+/datum/surgery/proc/get_surgery_next_step()
+ if(status < steps.len)
+ var/step_type = steps[status + 1]
+ return new step_type
+ else
+ return null
+
+/datum/surgery/proc/complete()
+ SSblackbox.record_feedback("tally", "surgeries_completed", 1, type)
+ qdel(src)
+
+/datum/surgery/proc/get_propability_multiplier()
+ var/propability = 0.5
+ var/turf/T = get_turf(target)
+
+ if(locate(/obj/structure/table/optable, T))
+ propability = 1
+ else if(locate(/obj/machinery/stasis, T))
+ propability = 0.9
+ else if(locate(/obj/structure/table, T))
+ propability = 0.8
+ else if(locate(/obj/structure/bed, T))
+ propability = 0.7
+
+ return propability + success_multiplier
+
+/datum/surgery/advanced
+ name = "advanced surgery"
+ requires_tech = 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 = list()
+ var/list/req_tech_surgeries = subtypesof(/datum/surgery)
+ for(var/i in req_tech_surgeries)
+ var/datum/surgery/beep = i
+ if(beep.requires_tech)
+ surgeries += beep
+
+//INFO
+//Check /mob/living/carbon/attackby for how surgery progresses, and also /mob/living/carbon/attack_hand.
+//As of Feb 21 2013 they are in code/modules/mob/living/carbon/carbon.dm, lines 459 and 51 respectively.
+//Other important variables are var/list/surgeries (/mob/living) and var/list/internal_organs (/mob/living/carbon)
+// var/list/bodyparts (/mob/living/carbon/human) is the LIMBS of a Mob.
+//Surgical procedures are initiated by attempt_initiate_surgery(), which is called by surgical drapes and bedsheets.
+
+
+//TODO
+//specific steps for some surgeries (fluff text)
+//more interesting failure options
+//randomised complications
+//more surgeries!
+//add a probability modifier for the state of the surgeon- health, twitching, etc. blindness, god forbid.
+//helper for converting a zone_sel.selecting to body part (for damage)
+
+
+//RESOLVED ISSUES //"Todo" jobs that have been completed
+//combine hands/feet into the arms - Hands/feet were removed - RR
+//surgeries (not steps) that can be initiated on any body part (corresponding with damage locations) - Call this one done, see possible_locs var - c0
+>>>>>>> 8fcf42eff9... Experimental Cobbisection [150+ Hours and Ready] (#44821)
diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm
index c5a944fbb2..71f813a5b5 100644
--- a/code/modules/surgery/surgery_step.dm
+++ b/code/modules/surgery/surgery_step.dm
@@ -8,7 +8,9 @@
var/repeatable = FALSE //can this step 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
var/list/chems_needed = list() //list of chems needed to complete the step. Even on success, the step will have no effect if there aren't the chems required in the mob.
var/require_all_chems = TRUE //any on the list or all on the list?
-/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/silicons_obey_prob = FALSE
+
+/datum/surgery_step/proc/try_op(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
var/success = FALSE
if(accept_hand)
if(!tool)
@@ -46,7 +48,8 @@
else
surgery.status--
return FALSE
-/datum/surgery_step/proc/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
+
+/datum/surgery_step/proc/initiate(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
surgery.step_in_progress = TRUE
var/speed_mod = 1
var/advance = FALSE
@@ -60,7 +63,8 @@
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)) && chem_check(target) && !try_to_fail)
+
+ if((prob(prob_chance) || (iscyborg(user) && !silicons_obey_prob)) && chem_check(target) && !try_to_fail)
if(success(user, target, target_zone, tool, surgery))
advance = TRUE
else
@@ -73,19 +77,18 @@
surgery.step_in_progress = FALSE
return advance
-
-/datum/surgery_step/proc/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+/datum/surgery_step/proc/preop(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "You begin to perform surgery on [target]...",
"[user] begins to perform surgery on [target].",
"[user] begins to perform surgery on [target].")
-/datum/surgery_step/proc/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+/datum/surgery_step/proc/success(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "You succeed.",
"[user] succeeds!",
"[user] finishes.")
return TRUE
-/datum/surgery_step/proc/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+/datum/surgery_step/proc/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "You screw up!",
"[user] screws up!",
"[user] finishes.", TRUE) //By default the patient will notice if the wrong thing has been cut
@@ -93,7 +96,8 @@
/datum/surgery_step/proc/tool_check(mob/user, obj/item/tool)
return TRUE
-/datum/surgery_step/proc/chem_check(mob/living/carbon/target)
+
+/datum/surgery_step/proc/chem_check(mob/living/target)
if(!LAZYLEN(chems_needed))
return TRUE
if(require_all_chems)