mirror of
https://github.com/KabKebab/GS13.git
synced 2026-07-17 10:58:19 +01:00
Surgery ports 1
This commit is contained in:
@@ -44,6 +44,7 @@
|
||||
owner.assigned_role = "[name] [sub_role]"
|
||||
owner.objectives += team.objectives
|
||||
finalize_abductor()
|
||||
ADD_TRAIT(owner, TRAIT_ABDUCTOR_TRAINING, ABDUCTOR_ANTAGONIST)
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/abductor/on_removal()
|
||||
@@ -51,6 +52,7 @@
|
||||
if(owner.current)
|
||||
to_chat(owner.current,"<span class='userdanger'>You are no longer the [owner.special_role]!</span>")
|
||||
owner.special_role = null
|
||||
REMOVE_TRAIT(owner, TRAIT_ABDUCTOR_TRAINING, ABDUCTOR_ANTAGONIST)
|
||||
return ..()
|
||||
|
||||
/datum/antagonist/abductor/greet()
|
||||
@@ -74,11 +76,15 @@
|
||||
|
||||
update_abductor_icons_added(owner,"abductor")
|
||||
|
||||
/datum/antagonist/abductor/scientist/finalize_abductor()
|
||||
..()
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
var/datum/species/abductor/A = H.dna.species
|
||||
A.scientist = TRUE
|
||||
/datum/antagonist/abductor/scientist/on_gain()
|
||||
ADD_TRAIT(owner, TRAIT_ABDUCTOR_SCIENTIST_TRAINING, ABDUCTOR_ANTAGONIST)
|
||||
ADD_TRAIT(owner, TRAIT_SURGEON, ABDUCTOR_ANTAGONIST)
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/abductor/scientist/on_removal()
|
||||
REMOVE_TRAIT(owner, TRAIT_ABDUCTOR_SCIENTIST_TRAINING, ABDUCTOR_ANTAGONIST)
|
||||
REMOVE_TRAIT(owner, TRAIT_SURGEON, ABDUCTOR_ANTAGONIST)
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/abductor/admin_add(datum/mind/new_owner,mob/admin)
|
||||
var/list/current_teams = list()
|
||||
@@ -213,4 +219,4 @@
|
||||
/datum/antagonist/proc/update_abductor_icons_removed(datum/mind/alien_mind)
|
||||
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_ABDUCTOR]
|
||||
hud.leave_hud(alien_mind.current)
|
||||
set_antag_hud(alien_mind.current, null)
|
||||
set_antag_hud(alien_mind.current, null)
|
||||
|
||||
@@ -132,22 +132,24 @@
|
||||
/obj/item/abductor
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
|
||||
/obj/item/abductor/proc/AbductorCheck(user)
|
||||
if(isabductor(user))
|
||||
/obj/item/abductor/proc/AbductorCheck(mob/user)
|
||||
if(HAS_TRAIT(user, TRAIT_ABDUCTOR_TRAINING))
|
||||
return TRUE
|
||||
to_chat(user, "<span class='warning'>You can't figure how this works!</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/item/abductor/proc/ScientistCheck(user)
|
||||
if(!AbductorCheck(user))
|
||||
return FALSE
|
||||
/obj/item/abductor/proc/ScientistCheck(mob/user)
|
||||
var/training = HAS_TRAIT(user, TRAIT_ABDUCTOR_TRAINING)
|
||||
var/sci_training = HAS_TRAIT(user, TRAIT_ABDUCTOR_SCIENTIST_TRAINING)
|
||||
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/datum/species/abductor/S = H.dna.species
|
||||
if(S.scientist)
|
||||
return TRUE
|
||||
to_chat(user, "<span class='warning'>You're not trained to use this!</span>")
|
||||
return FALSE
|
||||
if(training && !sci_training)
|
||||
to_chat(user, "<span class='warning'>You're not trained to use this!</span>")
|
||||
. = FALSE
|
||||
else if(!training && !sci_training)
|
||||
to_chat(user, "<span class='warning'>You can't figure how this works!</span>")
|
||||
. = FALSE
|
||||
else
|
||||
. = TRUE
|
||||
|
||||
/obj/item/abductor/gizmo
|
||||
name = "science tool"
|
||||
@@ -681,7 +683,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
|
||||
desc = "Abduct with style - spiky style. Prevents digital tracking."
|
||||
icon_state = "alienhelmet"
|
||||
item_state = "alienhelmet"
|
||||
blockTracking = 1
|
||||
blockTracking = TRUE
|
||||
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
|
||||
|
||||
// Operating Table / Beds / Lockers
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
icon_state = "gland"
|
||||
status = ORGAN_ROBOTIC
|
||||
beating = TRUE
|
||||
var/true_name = "baseline placebo referencer"
|
||||
var/cooldown_low = 300
|
||||
var/cooldown_high = 300
|
||||
var/next_activation = 0
|
||||
@@ -16,6 +17,11 @@
|
||||
var/mind_control_duration = 1800
|
||||
var/active_mind_control = FALSE
|
||||
|
||||
/obj/item/organ/heart/gland/examine(mob/user)
|
||||
. = ..()
|
||||
if(HAS_TRAIT(user, TRAIT_ABDUCTOR_SCIENTIST_TRAINING) || isobserver(user))
|
||||
to_chat(user, "<span class='notice'>It is \a [true_name].</span>")
|
||||
|
||||
/obj/item/organ/heart/gland/proc/ownerCheck()
|
||||
if(ishuman(owner))
|
||||
return TRUE
|
||||
@@ -95,6 +101,7 @@
|
||||
return
|
||||
|
||||
/obj/item/organ/heart/gland/heals
|
||||
true_name = "coherency harmonizer"
|
||||
cooldown_low = 200
|
||||
cooldown_high = 400
|
||||
uses = -1
|
||||
@@ -109,6 +116,7 @@
|
||||
owner.adjustOxyLoss(-20)
|
||||
|
||||
/obj/item/organ/heart/gland/slime
|
||||
true_name = "gastric animation galvanizer"
|
||||
cooldown_low = 600
|
||||
cooldown_high = 1200
|
||||
uses = -1
|
||||
@@ -130,6 +138,7 @@
|
||||
Slime.Leader = owner
|
||||
|
||||
/obj/item/organ/heart/gland/mindshock
|
||||
true_name = "neural crosstalk uninhibitor"
|
||||
cooldown_low = 400
|
||||
cooldown_high = 700
|
||||
uses = -1
|
||||
@@ -156,6 +165,7 @@
|
||||
H.hallucination += 60
|
||||
|
||||
/obj/item/organ/heart/gland/pop
|
||||
true_name = "anthropmorphic translocator"
|
||||
cooldown_low = 900
|
||||
cooldown_high = 1800
|
||||
uses = -1
|
||||
@@ -171,6 +181,7 @@
|
||||
owner.set_species(species)
|
||||
|
||||
/obj/item/organ/heart/gland/ventcrawling
|
||||
true_name = "pliant cartilage enabler"
|
||||
cooldown_low = 1800
|
||||
cooldown_high = 2400
|
||||
uses = 1
|
||||
@@ -183,6 +194,7 @@
|
||||
owner.ventcrawler = VENTCRAWLER_ALWAYS
|
||||
|
||||
/obj/item/organ/heart/gland/viral
|
||||
true_name = "contamination incubator"
|
||||
cooldown_low = 1800
|
||||
cooldown_high = 2400
|
||||
uses = 1
|
||||
@@ -217,6 +229,7 @@
|
||||
return A
|
||||
|
||||
/obj/item/organ/heart/gland/trauma
|
||||
true_name = "white matter randomiser"
|
||||
cooldown_low = 800
|
||||
cooldown_high = 1200
|
||||
uses = 5
|
||||
@@ -235,6 +248,7 @@
|
||||
owner.gain_trauma_type(BRAIN_TRAUMA_MILD, rand(TRAUMA_RESILIENCE_BASIC, TRAUMA_RESILIENCE_LOBOTOMY))
|
||||
|
||||
/obj/item/organ/heart/gland/spiderman
|
||||
true_name = "araneae cloister accelerator"
|
||||
cooldown_low = 450
|
||||
cooldown_high = 900
|
||||
uses = -1
|
||||
@@ -249,6 +263,7 @@
|
||||
S.directive = "Protect your nest inside [owner.real_name]."
|
||||
|
||||
/obj/item/organ/heart/gland/egg
|
||||
true_name = "roe/enzymatic synthesizer"
|
||||
cooldown_low = 300
|
||||
cooldown_high = 400
|
||||
uses = -1
|
||||
@@ -264,6 +279,7 @@
|
||||
new /obj/item/reagent_containers/food/snacks/egg/gland(T)
|
||||
|
||||
/obj/item/organ/heart/gland/electric
|
||||
true_name = "electron accumulator/discharger"
|
||||
cooldown_low = 800
|
||||
cooldown_high = 1200
|
||||
uses = -1
|
||||
@@ -289,6 +305,7 @@
|
||||
playsound(get_turf(owner), 'sound/magic/lightningshock.ogg', 50, 1)
|
||||
|
||||
/obj/item/organ/heart/gland/chem
|
||||
true_name = "intrinsic pharma-provider"
|
||||
cooldown_low = 50
|
||||
cooldown_high = 50
|
||||
uses = -1
|
||||
@@ -308,6 +325,7 @@
|
||||
..()
|
||||
|
||||
/obj/item/organ/heart/gland/plasma
|
||||
true_name = "effluvium sanguine-synonym emitter"
|
||||
cooldown_low = 1200
|
||||
cooldown_high = 1800
|
||||
uses = -1
|
||||
|
||||
@@ -55,8 +55,7 @@
|
||||
actions += set_droppoint_action
|
||||
|
||||
/obj/machinery/computer/camera_advanced/abductor/proc/IsScientist(mob/living/carbon/human/H)
|
||||
var/datum/species/abductor/S = H.dna.species
|
||||
return S.scientist
|
||||
return HAS_TRAIT(H, TRAIT_ABDUCTOR_SCIENTIST_TRAINING)
|
||||
|
||||
/datum/action/innate/teleport_in
|
||||
name = "Send To"
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(!isabductor(user))
|
||||
if(!HAS_TRAIT(user, TRAIT_ABDUCTOR_TRAINING))
|
||||
to_chat(user, "<span class='warning'>You start mashing alien buttons at random!</span>")
|
||||
if(do_after(user,100, target = src))
|
||||
TeleporterSend()
|
||||
|
||||
@@ -53,4 +53,4 @@
|
||||
. = ..()
|
||||
var/datum/effect_system/spark_spread/S = new
|
||||
S.set_up(10,0,loc)
|
||||
S.start()
|
||||
S.start()
|
||||
|
||||
@@ -92,7 +92,8 @@
|
||||
. += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly unsimian manner."
|
||||
|
||||
if(combatmode)
|
||||
. += "[t_He] [t_is] visibly tense[resting ? "." : ", and [t_is] standing in combative stance."]"
|
||||
. += "[t_He] [t_is] visibly tense[resting ? "." : ", and [t_is] standing in combative stance."]\n"
|
||||
. += common_trait_examine()
|
||||
|
||||
var/datum/component/mood/mood = src.GetComponent(/datum/component/mood)
|
||||
if(mood)
|
||||
|
||||
@@ -352,6 +352,7 @@
|
||||
|
||||
if (length(msg))
|
||||
. += "<span class='warning'>[msg.Join("")]</span>"
|
||||
msg += common_trait_examine()
|
||||
|
||||
var/traitstring = get_trait_string()
|
||||
if(ishuman(user))
|
||||
|
||||
@@ -1,22 +1,18 @@
|
||||
/datum/species/abductor
|
||||
name = "Abductor"
|
||||
id = "abductor"
|
||||
say_mod = "gibbers"
|
||||
sexes = FALSE
|
||||
species_traits = list(NOBLOOD,NOEYES,NOGENITALS,NOAROUSAL)
|
||||
inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NOGUNS,TRAIT_NOHUNGER,TRAIT_NOBREATH)
|
||||
mutanttongue = /obj/item/organ/tongue/abductor
|
||||
var/scientist = FALSE // vars to not pollute spieces list with castes
|
||||
|
||||
/datum/species/abductor/copy_properties_from(datum/species/abductor/old_species)
|
||||
scientist = old_species.scientist
|
||||
|
||||
/datum/species/abductor/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
. = ..()
|
||||
var/datum/atom_hud/abductor_hud = GLOB.huds[DATA_HUD_ABDUCTOR]
|
||||
abductor_hud.add_hud_to(C)
|
||||
|
||||
/datum/species/abductor/on_species_loss(mob/living/carbon/C)
|
||||
. = ..()
|
||||
var/datum/atom_hud/abductor_hud = GLOB.huds[DATA_HUD_ABDUCTOR]
|
||||
abductor_hud.remove_hud_from(C)
|
||||
/datum/species/abductor
|
||||
name = "Abductor"
|
||||
id = "abductor"
|
||||
say_mod = "gibbers"
|
||||
sexes = FALSE
|
||||
species_traits = list(NOBLOOD,NOEYES,NOGENITALS,NOAROUSAL)
|
||||
inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NOGUNS,TRAIT_NOHUNGER,TRAIT_NOBREATH)
|
||||
mutanttongue = /obj/item/organ/tongue/abductor
|
||||
|
||||
/datum/species/abductor/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
. = ..()
|
||||
var/datum/atom_hud/abductor_hud = GLOB.huds[DATA_HUD_ABDUCTOR]
|
||||
abductor_hud.add_hud_to(C)
|
||||
|
||||
/datum/species/abductor/on_species_loss(mob/living/carbon/C)
|
||||
. = ..()
|
||||
var/datum/atom_hud/abductor_hud = GLOB.huds[DATA_HUD_ABDUCTOR]
|
||||
abductor_hud.remove_hud_from(C)
|
||||
|
||||
@@ -719,7 +719,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
/mob/living/carbon/proc/liver_failure()
|
||||
reagents.end_metabolization(src, keep_liverless = TRUE) //Stops trait-based effects on reagents, to prevent permanent buffs
|
||||
reagents.metabolize(src, can_overdose=FALSE, liverless = TRUE)
|
||||
if(HAS_TRAIT(src, TRAIT_STABLEHEART))
|
||||
if(HAS_TRAIT(src, TRAIT_STABLELIVER))
|
||||
return
|
||||
adjustToxLoss(4, TRUE, TRUE)
|
||||
if(prob(30))
|
||||
|
||||
+537
-526
File diff suppressed because it is too large
Load Diff
@@ -1294,9 +1294,11 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M)
|
||||
/datum/reagent/medicine/corazone/on_mob_metabolize(mob/living/M)
|
||||
..()
|
||||
ADD_TRAIT(M, TRAIT_STABLEHEART, type)
|
||||
ADD_TRAIT(M, TRAIT_STABLELIVER, type)
|
||||
|
||||
/datum/reagent/medicine/corazone/on_mob_end_metabolize(mob/living/M)
|
||||
REMOVE_TRAIT(M, TRAIT_STABLEHEART, type)
|
||||
REMOVE_TRAIT(M, TRAIT_STABLELIVER, type)
|
||||
..()
|
||||
|
||||
/datum/reagent/medicine/muscle_stimulant
|
||||
|
||||
@@ -749,12 +749,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/advanced/bioware/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/ext
|
||||
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."
|
||||
@@ -825,6 +835,13 @@
|
||||
surgery = /datum/surgery/advanced/bioware/vein_threading
|
||||
research_icon_state = "surgery_chest"
|
||||
|
||||
/datum/design/surgery/muscled_veins
|
||||
name = "Vein Muscle Membrane"
|
||||
desc = "A surgical procedure which adds a muscled membrane to blood vessels, allowing them to pump blood without a heart."
|
||||
id = "surgery_muscled_veins"
|
||||
surgery = /datum/surgery/advanced/bioware/muscled_veins
|
||||
research_icon_state = "surgery_chest"
|
||||
|
||||
/datum/design/surgery/ligament_hook
|
||||
name = "Ligament Hook"
|
||||
desc = "A surgical procedure which reshapes the connections between torso and limbs, making it so limbs can be attached manually if severed. \
|
||||
|
||||
@@ -135,7 +135,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", "surgery_exp_dissection")
|
||||
design_ids = list("surgery_lobotomy", "surgery_reconstruction", "surgery_toxinhealing", "organbox", "surgery_adv_dissection")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
|
||||
export_price = 5000
|
||||
|
||||
@@ -144,7 +144,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_ligament_hook","surgery_ligament_reinforcement","surgery_nerve_ground","surgery_viral_bond")
|
||||
design_ids = list("surgery_revival","surgery_pacify","surgery_vein_thread","surgery_muscled_veins","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
|
||||
|
||||
@@ -153,7 +153,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
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
/datum/surgery/advanced/bioware/can_start(mob/user, mob/living/carbon/human/target)
|
||||
if(!..())
|
||||
return FALSE
|
||||
if(!istype(target))
|
||||
return FALSE
|
||||
for(var/X in target.bioware)
|
||||
var/datum/bioware/B = X
|
||||
if(B.mod_type == bioware_target)
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/datum/surgery/advanced/bioware/muscled_veins
|
||||
name = "Vein Muscle Membrane"
|
||||
desc = "A surgical procedure which adds a muscled membrane to blood vessels, allowing them to pump blood without a heart."
|
||||
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/muscled_veins,
|
||||
/datum/surgery_step/close)
|
||||
possible_locs = list(BODY_ZONE_CHEST)
|
||||
bioware_target = BIOWARE_CIRCULATION
|
||||
|
||||
/datum/surgery_step/muscled_veins
|
||||
name = "shape vein muscles"
|
||||
accept_hand = TRUE
|
||||
time = 125
|
||||
|
||||
/datum/surgery_step/muscled_veins/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, "<span class='notice'>You start wrapping muscles around [target]'s circulatory system.</span>",
|
||||
"[user] starts wrapping muscles around [target]'s circulatory system.",
|
||||
"[user] starts manipulating [target]'s circulatory system.")
|
||||
|
||||
/datum/surgery_step/muscled_veins/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, "<span class='notice'>You reshape [target]'s circulatory system, adding a muscled membrane!</span>",
|
||||
"[user] reshapes [target]'s circulatory system, adding a muscled membrane!",
|
||||
"[user] finishes manipulating [target]'s circulatory system.")
|
||||
new /datum/bioware/muscled_veins(target)
|
||||
return TRUE
|
||||
|
||||
/datum/bioware/muscled_veins
|
||||
name = "Threaded Veins"
|
||||
desc = "The circulatory system is woven into a mesh, severely reducing the amount of blood lost from wounds."
|
||||
mod_type = BIOWARE_CIRCULATION
|
||||
|
||||
/datum/bioware/muscled_veins/on_gain()
|
||||
..()
|
||||
ADD_TRAIT(owner, TRAIT_STABLEHEART, "muscled_veins")
|
||||
|
||||
/datum/bioware/muscled_veins/on_lose()
|
||||
..()
|
||||
REMOVE_TRAIT(owner, TRAIT_STABLEHEART, "muscled_veins")
|
||||
@@ -13,8 +13,9 @@
|
||||
/datum/surgery_step/brainwash,
|
||||
/datum/surgery_step/close)
|
||||
|
||||
species = list(/mob/living/carbon/human)
|
||||
target_mobtypes = list(/mob/living/carbon/human)
|
||||
possible_locs = list(BODY_ZONE_HEAD)
|
||||
|
||||
/datum/surgery/advanced/brainwashing/can_start(mob/user, mob/living/carbon/target)
|
||||
if(!..())
|
||||
return FALSE
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/datum/surgery_step/lobotomize,
|
||||
/datum/surgery_step/close)
|
||||
|
||||
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
possible_locs = list(BODY_ZONE_HEAD)
|
||||
requires_bodypart_type = 0
|
||||
/datum/surgery/advanced/lobotomy/can_start(mob/user, mob/living/carbon/target)
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
/datum/surgery_step/clamp_bleeders,
|
||||
/datum/surgery_step/pacify,
|
||||
/datum/surgery_step/close)
|
||||
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
|
||||
target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
possible_locs = list(BODY_ZONE_HEAD)
|
||||
requires_bodypart_type = 0
|
||||
/datum/surgery/advanced/pacify/can_start(mob/user, mob/living/carbon/target)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
/datum/surgery_step/reconstruct,
|
||||
/datum/surgery_step/close)
|
||||
|
||||
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
possible_locs = list(BODY_ZONE_CHEST)
|
||||
requires_bodypart_type = 0
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
/datum/surgery_step/incise,
|
||||
/datum/surgery_step/revive,
|
||||
/datum/surgery_step/close)
|
||||
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
|
||||
target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
possible_locs = list(BODY_ZONE_HEAD)
|
||||
requires_bodypart_type = 0
|
||||
/datum/surgery/advanced/revival/can_start(mob/user, mob/living/carbon/target)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
/datum/surgery_step/toxichealing,
|
||||
/datum/surgery_step/close)
|
||||
|
||||
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
possible_locs = list(BODY_ZONE_CHEST)
|
||||
requires_bodypart_type = 0
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
/datum/surgery_step/incise,
|
||||
/datum/surgery_step/viral_bond,
|
||||
/datum/surgery_step/close)
|
||||
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
|
||||
target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
possible_locs = list(BODY_ZONE_CHEST)
|
||||
/datum/surgery/advanced/viral_bonding/can_start(mob/user, mob/living/carbon/target)
|
||||
if(!..())
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/surgery/amputation
|
||||
name = "Amputation"
|
||||
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/sever_limb)
|
||||
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
possible_locs = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG, BODY_ZONE_HEAD)
|
||||
requires_bodypart_type = 0
|
||||
/datum/surgery_step/sever_limb
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
/datum/surgery_step/clamp_bleeders,
|
||||
/datum/surgery_step/fix_brain,
|
||||
/datum/surgery_step/close)
|
||||
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
|
||||
target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
possible_locs = list(BODY_ZONE_HEAD)
|
||||
requires_bodypart_type = 0
|
||||
/datum/surgery_step/fix_brain
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/surgery/breast_augmentation
|
||||
name = "Breast augmentation"
|
||||
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/augment_breasts, /datum/surgery_step/close)
|
||||
species = list(/mob/living/carbon/human)
|
||||
target_mobtypes = list(/mob/living/carbon/human)
|
||||
possible_locs = list(BODY_ZONE_CHEST)
|
||||
|
||||
/datum/surgery_step/augment_breasts
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/surgery/cavity_implant
|
||||
name = "Cavity implant"
|
||||
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/incise, /datum/surgery_step/handle_cavity, /datum/surgery_step/close)
|
||||
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
possible_locs = list(BODY_ZONE_CHEST)
|
||||
//handle cavity
|
||||
/datum/surgery_step/handle_cavity
|
||||
|
||||
@@ -1,39 +1,41 @@
|
||||
/datum/surgery/core_removal
|
||||
name = "Core removal"
|
||||
steps = list(/datum/surgery_step/incise, /datum/surgery_step/extract_core)
|
||||
species = list(/mob/living/simple_animal/slime)
|
||||
possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD)
|
||||
|
||||
/datum/surgery/core_removal/can_start(mob/user, mob/living/target)
|
||||
if(target.stat == DEAD)
|
||||
return 1
|
||||
return 0
|
||||
//extract brain
|
||||
/datum/surgery_step/extract_core
|
||||
name = "extract core"
|
||||
implements = list(/obj/item/hemostat = 100, TOOL_CROWBAR = 100)
|
||||
time = 16
|
||||
|
||||
/datum/surgery_step/extract_core/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, "<span class='notice'>You begin to extract a core from [target]...</span>",
|
||||
"[user] begins to extract a core from [target].",
|
||||
"[user] begins to extract a core from [target].")
|
||||
|
||||
/datum/surgery_step/extract_core/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
var/mob/living/simple_animal/slime/slime = target
|
||||
if(slime.cores > 0)
|
||||
slime.cores--
|
||||
display_results(user, target, "<span class='notice'>You successfully extract a core from [target]. [slime.cores] core\s remaining.</span>",
|
||||
"[user] successfully extracts a core from [target]!",
|
||||
"[user] successfully extracts a core from [target]!")
|
||||
|
||||
new slime.coretype(slime.loc)
|
||||
|
||||
if(slime.cores <= 0)
|
||||
slime.icon_state = "[slime.colour] baby slime dead-nocore"
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
else
|
||||
to_chat(user, "<span class='warning'>There aren't any cores left in [target]!</span>")
|
||||
return 1
|
||||
/datum/surgery/core_removal
|
||||
name = "Core removal"
|
||||
steps = list(/datum/surgery_step/incise, /datum/surgery_step/extract_core)
|
||||
target_mobtypes = list(/mob/living/simple_animal/slime)
|
||||
possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD)
|
||||
lying_required = FALSE
|
||||
ignore_clothes = TRUE
|
||||
|
||||
/datum/surgery/core_removal/can_start(mob/user, mob/living/target)
|
||||
if(target.stat == DEAD)
|
||||
return 1
|
||||
return 0
|
||||
//extract brain
|
||||
/datum/surgery_step/extract_core
|
||||
name = "extract core"
|
||||
implements = list(/obj/item/hemostat = 100, TOOL_CROWBAR = 100)
|
||||
time = 16
|
||||
|
||||
/datum/surgery_step/extract_core/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, "<span class='notice'>You begin to extract a core from [target]...</span>",
|
||||
"[user] begins to extract a core from [target].",
|
||||
"[user] begins to extract a core from [target].")
|
||||
|
||||
/datum/surgery_step/extract_core/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
var/mob/living/simple_animal/slime/slime = target
|
||||
if(slime.cores > 0)
|
||||
slime.cores--
|
||||
display_results(user, target, "<span class='notice'>You successfully extract a core from [target]. [slime.cores] core\s remaining.</span>",
|
||||
"[user] successfully extracts a core from [target]!",
|
||||
"[user] successfully extracts a core from [target]!")
|
||||
|
||||
new slime.coretype(slime.loc)
|
||||
|
||||
if(slime.cores <= 0)
|
||||
slime.icon_state = "[slime.colour] baby slime dead-nocore"
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
else
|
||||
to_chat(user, "<span class='warning'>There aren't any cores left in [target]!</span>")
|
||||
return 1
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/datum/surgery_step/embalming,
|
||||
/datum/surgery_step/close)
|
||||
|
||||
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
possible_locs = list(BODY_ZONE_CHEST)
|
||||
requires_bodypart_type = 0
|
||||
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
#define BASE_HUMAN_REWARD 500
|
||||
|
||||
/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/dissection,
|
||||
/datum/surgery_step/clamp_bleeders,
|
||||
/datum/surgery_step/close)
|
||||
possible_locs = list(BODY_ZONE_CHEST)
|
||||
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/advanced/experimental_dissection/can_start(mob/user, mob/living/target)
|
||||
. = ..()
|
||||
if(HAS_TRAIT_FROM(target, TRAIT_DISSECTED,"[name]"))
|
||||
return FALSE
|
||||
if(target.stat != DEAD)
|
||||
return FALSE
|
||||
|
||||
/datum/surgery_step/dissection
|
||||
name = "dissection"
|
||||
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, doesn't use TOOL_SCALPEL because different scalpels have different probs
|
||||
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, "<span class='notice'>You start dissecting [target].</span>",
|
||||
"[user] starts dissecting [target].",
|
||||
"[user] starts dissecting [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))
|
||||
cost = (BASE_HUMAN_REWARD*10)
|
||||
else if(isalienadult(target))
|
||||
cost = (BASE_HUMAN_REWARD*5)
|
||||
else if(ismonkey(target))
|
||||
cost = (BASE_HUMAN_REWARD*0.5)
|
||||
else if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(H?.dna?.species)
|
||||
if(isabductor(H))
|
||||
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)
|
||||
|
||||
|
||||
|
||||
//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, "<span class='notice'>You dissect [target], and add your [points_earned] point\s worth of discoveries to the research database!</span>",
|
||||
"[user] dissects [target], discovering [points_earned] point\s of data!",
|
||||
"[user] dissects [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.name]")
|
||||
repeatable = FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/surgery_step/dissection/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, "<span class='notice'>You dissect [target], but do not find anything particularly interesting.</span>",
|
||||
"[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 = (round(check_value(target, surgery) * 0.01))))
|
||||
var/obj/item/bodypart/L = target.get_bodypart(BODY_ZONE_CHEST)
|
||||
target.apply_damage(80, BRUTE, L)
|
||||
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
|
||||
replaced_by = null
|
||||
|
||||
//#undef EXPDIS_FAIL_MSG
|
||||
@@ -1,45 +1,45 @@
|
||||
/datum/surgery/eye_surgery
|
||||
name = "Eye surgery"
|
||||
steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/fix_eyes, /datum/surgery_step/close)
|
||||
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
possible_locs = list(BODY_ZONE_PRECISE_EYES)
|
||||
requires_bodypart_type = 0
|
||||
//fix eyes
|
||||
/datum/surgery_step/fix_eyes
|
||||
name = "fix eyes"
|
||||
implements = list(/obj/item/hemostat = 100, TOOL_SCREWDRIVER = 45, /obj/item/pen = 25)
|
||||
time = 64
|
||||
/datum/surgery/eye_surgery/can_start(mob/user, mob/living/carbon/target)
|
||||
var/obj/item/organ/eyes/E = target.getorganslot(ORGAN_SLOT_EYES)
|
||||
if(!E)
|
||||
to_chat(user, "It's hard to do surgery on someone's eyes when [target.p_they()] [target.p_do()]n't have any.")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/surgery_step/fix_eyes/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, "<span class='notice'>You begin to fix [target]'s eyes...</span>",
|
||||
"[user] begins to fix [target]'s eyes.",
|
||||
"[user] begins to perform surgery on [target]'s eyes.")
|
||||
|
||||
/datum/surgery_step/fix_eyes/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, "<span class='notice'>You succeed in fixing [target]'s eyes.</span>",
|
||||
"[user] successfully fixes [target]'s eyes!",
|
||||
"[user] completes the surgery on [target]'s eyes.")
|
||||
target.cure_blind(list(EYE_DAMAGE))
|
||||
target.set_blindness(0)
|
||||
target.cure_nearsighted(list(EYE_DAMAGE))
|
||||
target.blur_eyes(35) //this will fix itself slowly.
|
||||
target.set_eye_damage(0)
|
||||
return TRUE
|
||||
|
||||
/datum/surgery_step/fix_eyes/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
if(target.getorgan(/obj/item/organ/brain))
|
||||
display_results(user, target, "<span class='warning'>You accidentally stab [target] right in the brain!</span>",
|
||||
"<span class='warning'>[user] accidentally stabs [target] right in the brain!</span>",
|
||||
"<span class='warning'>[user] accidentally stabs [target] right in the brain!</span>")
|
||||
target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 70)
|
||||
else
|
||||
display_results(user, target, "<span class='warning'>You accidentally stab [target] right in the brain! Or would have, if [target] had a brain.</span>",
|
||||
"<span class='warning'>[user] accidentally stabs [target] right in the brain! Or would have, if [target] had a brain.</span>",
|
||||
"<span class='warning'>[user] accidentally stabs [target] right in the brain!</span>")
|
||||
return FALSE
|
||||
/datum/surgery/eye_surgery
|
||||
name = "Eye surgery"
|
||||
steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/fix_eyes, /datum/surgery_step/close)
|
||||
target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
possible_locs = list(BODY_ZONE_PRECISE_EYES)
|
||||
requires_bodypart_type = 0
|
||||
//fix eyes
|
||||
/datum/surgery_step/fix_eyes
|
||||
name = "fix eyes"
|
||||
implements = list(/obj/item/hemostat = 100, TOOL_SCREWDRIVER = 45, /obj/item/pen = 25)
|
||||
time = 64
|
||||
/datum/surgery/eye_surgery/can_start(mob/user, mob/living/carbon/target)
|
||||
var/obj/item/organ/eyes/E = target.getorganslot(ORGAN_SLOT_EYES)
|
||||
if(!E)
|
||||
to_chat(user, "It's hard to do surgery on someone's eyes when [target.p_they()] [target.p_do()]n't have any.")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/surgery_step/fix_eyes/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, "<span class='notice'>You begin to fix [target]'s eyes...</span>",
|
||||
"[user] begins to fix [target]'s eyes.",
|
||||
"[user] begins to perform surgery on [target]'s eyes.")
|
||||
|
||||
/datum/surgery_step/fix_eyes/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, "<span class='notice'>You succeed in fixing [target]'s eyes.</span>",
|
||||
"[user] successfully fixes [target]'s eyes!",
|
||||
"[user] completes the surgery on [target]'s eyes.")
|
||||
target.cure_blind(list(EYE_DAMAGE))
|
||||
target.set_blindness(0)
|
||||
target.cure_nearsighted(list(EYE_DAMAGE))
|
||||
target.blur_eyes(35) //this will fix itself slowly.
|
||||
target.set_eye_damage(0)
|
||||
return TRUE
|
||||
|
||||
/datum/surgery_step/fix_eyes/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
if(target.getorgan(/obj/item/organ/brain))
|
||||
display_results(user, target, "<span class='warning'>You accidentally stab [target] right in the brain!</span>",
|
||||
"<span class='warning'>[user] accidentally stabs [target] right in the brain!</span>",
|
||||
"<span class='warning'>[user] accidentally stabs [target] right in the brain!</span>")
|
||||
target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 70)
|
||||
else
|
||||
display_results(user, target, "<span class='warning'>You accidentally stab [target] right in the brain! Or would have, if [target] had a brain.</span>",
|
||||
"<span class='warning'>[user] accidentally stabs [target] right in the brain! Or would have, if [target] had a brain.</span>",
|
||||
"<span class='warning'>[user] accidentally stabs [target] right in the brain!</span>")
|
||||
return FALSE
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/datum/surgery/graft_synthtissue
|
||||
name = "Graft synthtissue"
|
||||
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_GROIN, BODY_ZONE_PRECISE_EYES)
|
||||
steps = list(
|
||||
/datum/surgery_step/incise,
|
||||
|
||||
+175
-171
@@ -1,171 +1,175 @@
|
||||
/proc/attempt_initiate_surgery(obj/item/I, mob/living/M, mob/user)
|
||||
if(!istype(M))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/C
|
||||
var/obj/item/bodypart/affecting
|
||||
var/selected_zone = user.zone_selected
|
||||
|
||||
if(iscarbon(M))
|
||||
C = M
|
||||
affecting = C.get_bodypart(check_zone(selected_zone))
|
||||
|
||||
if(!M.lying && !isslime(M)) //if they're prone or a slime
|
||||
return
|
||||
|
||||
var/datum/surgery/current_surgery
|
||||
|
||||
for(var/datum/surgery/S in M.surgeries)
|
||||
if(S.location == selected_zone)
|
||||
current_surgery = S
|
||||
|
||||
if(!current_surgery)
|
||||
var/list/all_surgeries = GLOB.surgeries_list.Copy()
|
||||
var/list/available_surgeries = list()
|
||||
|
||||
for(var/datum/surgery/S in all_surgeries)
|
||||
if(!S.possible_locs.Find(selected_zone))
|
||||
continue
|
||||
if(affecting)
|
||||
if(!S.requires_bodypart)
|
||||
continue
|
||||
if(S.requires_bodypart_type && affecting.status != S.requires_bodypart_type)
|
||||
continue
|
||||
if(S.requires_real_bodypart && affecting.is_pseudopart)
|
||||
continue
|
||||
else if(C && S.requires_bodypart) //mob with no limb in surgery zone when we need a limb
|
||||
continue
|
||||
if(!S.can_start(user, M))
|
||||
continue
|
||||
for(var/path in S.species)
|
||||
if(istype(M, path))
|
||||
available_surgeries[S.name] = S
|
||||
break
|
||||
|
||||
var/P = input("Begin which procedure?", "Surgery", null, null) as null|anything in available_surgeries
|
||||
if(P && user && user.Adjacent(M) && (I in user))
|
||||
var/datum/surgery/S = available_surgeries[P]
|
||||
|
||||
for(var/datum/surgery/other in M.surgeries)
|
||||
if(other.location == S.location)
|
||||
return //during the input() another surgery was started at the same location.
|
||||
|
||||
//we check that the surgery is still doable after the input() wait.
|
||||
if(C)
|
||||
affecting = C.get_bodypart(check_zone(selected_zone))
|
||||
if(affecting)
|
||||
if(!S.requires_bodypart)
|
||||
return
|
||||
if(S.requires_bodypart_type && affecting.status != S.requires_bodypart_type)
|
||||
return
|
||||
else if(C && S.requires_bodypart)
|
||||
return
|
||||
if(!S.can_start(user, M))
|
||||
return
|
||||
|
||||
if(S.ignore_clothes || get_location_accessible(M, selected_zone))
|
||||
var/datum/surgery/procedure = new S.type(M, selected_zone, affecting)
|
||||
user.visible_message("[user] drapes [I] over [M]'s [parse_zone(selected_zone)] to prepare for surgery.", \
|
||||
"<span class='notice'>You drape [I] over [M]'s [parse_zone(selected_zone)] to prepare for \an [procedure.name].</span>")
|
||||
|
||||
log_combat(user, M, "operated on", null, "(OPERATION TYPE: [procedure.name]) (TARGET AREA: [selected_zone])")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to expose [M]'s [parse_zone(selected_zone)] first!</span>")
|
||||
|
||||
else if(!current_surgery.step_in_progress)
|
||||
attempt_cancel_surgery(current_surgery, I, M, user)
|
||||
|
||||
return 1
|
||||
|
||||
/proc/attempt_cancel_surgery(datum/surgery/S, obj/item/I, mob/living/M, mob/user)
|
||||
var/selected_zone = user.zone_selected
|
||||
if(S.status == 1)
|
||||
M.surgeries -= S
|
||||
user.visible_message("[user] removes [I] from [M]'s [parse_zone(selected_zone)].", \
|
||||
"<span class='notice'>You remove [I] from [M]'s [parse_zone(selected_zone)].</span>")
|
||||
qdel(S)
|
||||
else if(S.can_cancel)
|
||||
var/close_tool_type = /obj/item/cautery
|
||||
var/obj/item/close_tool = user.get_inactive_held_item()
|
||||
var/is_robotic = S.requires_bodypart_type == BODYPART_ROBOTIC
|
||||
if(is_robotic)
|
||||
close_tool_type = /obj/item/screwdriver
|
||||
if(istype(close_tool, close_tool_type) || iscyborg(user))
|
||||
M.surgeries -= S
|
||||
user.visible_message("[user] closes [M]'s [parse_zone(selected_zone)] with [close_tool] and removes [I].", \
|
||||
"<span class='notice'>You close [M]'s [parse_zone(selected_zone)] with [close_tool] and remove [I].</span>")
|
||||
qdel(S)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to hold a [is_robotic ? "screwdriver" : "cautery"] in your inactive hand to stop [M]'s surgery!</span>")
|
||||
|
||||
/proc/get_location_modifier(mob/M)
|
||||
var/turf/T = get_turf(M)
|
||||
if(locate(/obj/structure/table/optable, T))
|
||||
return 1
|
||||
else if(locate(/obj/structure/table, T))
|
||||
return 0.8
|
||||
else if(locate(/obj/structure/bed, T))
|
||||
return 0.7
|
||||
else
|
||||
return 0.5
|
||||
|
||||
|
||||
/proc/get_location_accessible(mob/M, location)
|
||||
var/covered_locations = 0 //based on body_parts_covered
|
||||
var/face_covered = 0 //based on flags_inv
|
||||
var/eyesmouth_covered = 0 //based on flags_cover
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
for(var/obj/item/clothing/I in list(C.back, C.wear_mask, C.head))
|
||||
covered_locations |= I.body_parts_covered
|
||||
face_covered |= I.flags_inv
|
||||
eyesmouth_covered |= I.flags_cover
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
for(var/obj/item/I in list(H.wear_suit, H.w_uniform, H.shoes, H.belt, H.gloves, H.glasses, H.ears))
|
||||
covered_locations |= I.body_parts_covered
|
||||
face_covered |= I.flags_inv
|
||||
eyesmouth_covered |= I.flags_cover
|
||||
|
||||
switch(location)
|
||||
if(BODY_ZONE_HEAD)
|
||||
if(covered_locations & HEAD)
|
||||
return 0
|
||||
if(BODY_ZONE_PRECISE_EYES)
|
||||
if(covered_locations & HEAD || face_covered & HIDEEYES || eyesmouth_covered & GLASSESCOVERSEYES)
|
||||
return 0
|
||||
if(BODY_ZONE_PRECISE_MOUTH)
|
||||
if(covered_locations & HEAD || face_covered & HIDEFACE || eyesmouth_covered & MASKCOVERSMOUTH || eyesmouth_covered & HEADCOVERSMOUTH)
|
||||
return 0
|
||||
if(BODY_ZONE_CHEST)
|
||||
if(covered_locations & CHEST)
|
||||
return 0
|
||||
if(BODY_ZONE_PRECISE_GROIN)
|
||||
if(covered_locations & GROIN)
|
||||
return 0
|
||||
if(BODY_ZONE_L_ARM)
|
||||
if(covered_locations & ARM_LEFT)
|
||||
return 0
|
||||
if(BODY_ZONE_R_ARM)
|
||||
if(covered_locations & ARM_RIGHT)
|
||||
return 0
|
||||
if(BODY_ZONE_L_LEG)
|
||||
if(covered_locations & LEG_LEFT)
|
||||
return 0
|
||||
if(BODY_ZONE_R_LEG)
|
||||
if(covered_locations & LEG_RIGHT)
|
||||
return 0
|
||||
if(BODY_ZONE_PRECISE_L_HAND)
|
||||
if(covered_locations & HAND_LEFT)
|
||||
return 0
|
||||
if(BODY_ZONE_PRECISE_R_HAND)
|
||||
if(covered_locations & HAND_RIGHT)
|
||||
return 0
|
||||
if(BODY_ZONE_PRECISE_L_FOOT)
|
||||
if(covered_locations & FOOT_LEFT)
|
||||
return 0
|
||||
if(BODY_ZONE_PRECISE_R_FOOT)
|
||||
if(covered_locations & FOOT_RIGHT)
|
||||
return 0
|
||||
|
||||
return 1
|
||||
/proc/attempt_initiate_surgery(obj/item/I, mob/living/M, mob/user)
|
||||
if(!istype(M))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/C
|
||||
var/obj/item/bodypart/affecting
|
||||
var/selected_zone = user.zone_selected
|
||||
|
||||
if(iscarbon(M))
|
||||
C = M
|
||||
affecting = C.get_bodypart(check_zone(selected_zone))
|
||||
|
||||
var/datum/surgery/current_surgery
|
||||
|
||||
for(var/datum/surgery/S in M.surgeries)
|
||||
if(S.location == selected_zone)
|
||||
current_surgery = S
|
||||
|
||||
if(!current_surgery)
|
||||
var/list/all_surgeries = GLOB.surgeries_list.Copy()
|
||||
var/list/available_surgeries = list()
|
||||
|
||||
for(var/datum/surgery/S in all_surgeries)
|
||||
if(!S.possible_locs.Find(selected_zone))
|
||||
continue
|
||||
if(affecting)
|
||||
if(!S.requires_bodypart)
|
||||
continue
|
||||
if(S.requires_bodypart_type && affecting.status != S.requires_bodypart_type)
|
||||
continue
|
||||
if(S.requires_real_bodypart && affecting.is_pseudopart)
|
||||
continue
|
||||
else if(C && S.requires_bodypart) //mob with no limb in surgery zone when we need a limb
|
||||
continue
|
||||
if(S.lying_required && !(M.lying))
|
||||
continue
|
||||
if(!S.can_start(user, M))
|
||||
continue
|
||||
for(var/path in S.target_mobtypes)
|
||||
if(istype(M, path))
|
||||
available_surgeries[S.name] = S
|
||||
break
|
||||
|
||||
if(!available_surgeries.len)
|
||||
return
|
||||
|
||||
var/P = input("Begin which procedure?", "Surgery", null, null) as null|anything in available_surgeries
|
||||
if(P && user && user.Adjacent(M) && (I in user))
|
||||
var/datum/surgery/S = available_surgeries[P]
|
||||
|
||||
for(var/datum/surgery/other in M.surgeries)
|
||||
if(other.location == S.location)
|
||||
return //during the input() another surgery was started at the same location.
|
||||
|
||||
//we check that the surgery is still doable after the input() wait.
|
||||
if(C)
|
||||
affecting = C.get_bodypart(check_zone(selected_zone))
|
||||
if(affecting)
|
||||
if(!S.requires_bodypart)
|
||||
return
|
||||
if(S.requires_bodypart_type && affecting.status != S.requires_bodypart_type)
|
||||
return
|
||||
else if(C && S.requires_bodypart)
|
||||
return
|
||||
if(S.lying_required && !(M.lying))
|
||||
return
|
||||
if(!S.can_start(user, M))
|
||||
return
|
||||
|
||||
if(S.ignore_clothes || get_location_accessible(M, selected_zone))
|
||||
var/datum/surgery/procedure = new S.type(M, selected_zone, affecting)
|
||||
user.visible_message("[user] drapes [I] over [M]'s [parse_zone(selected_zone)] to prepare for surgery.", \
|
||||
"<span class='notice'>You drape [I] over [M]'s [parse_zone(selected_zone)] to prepare for \an [procedure.name].</span>")
|
||||
|
||||
log_combat(user, M, "operated on", null, "(OPERATION TYPE: [procedure.name]) (TARGET AREA: [selected_zone])")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to expose [M]'s [parse_zone(selected_zone)] first!</span>")
|
||||
|
||||
else if(!current_surgery.step_in_progress)
|
||||
attempt_cancel_surgery(current_surgery, I, M, user)
|
||||
|
||||
return 1
|
||||
|
||||
/proc/attempt_cancel_surgery(datum/surgery/S, obj/item/I, mob/living/M, mob/user)
|
||||
var/selected_zone = user.zone_selected
|
||||
if(S.status == 1)
|
||||
M.surgeries -= S
|
||||
user.visible_message("[user] removes [I] from [M]'s [parse_zone(selected_zone)].", \
|
||||
"<span class='notice'>You remove [I] from [M]'s [parse_zone(selected_zone)].</span>")
|
||||
qdel(S)
|
||||
else if(S.can_cancel)
|
||||
var/close_tool_type = /obj/item/cautery
|
||||
var/obj/item/close_tool = user.get_inactive_held_item()
|
||||
var/is_robotic = S.requires_bodypart_type == BODYPART_ROBOTIC
|
||||
if(is_robotic)
|
||||
close_tool_type = /obj/item/screwdriver
|
||||
if(istype(close_tool, close_tool_type) || iscyborg(user))
|
||||
M.surgeries -= S
|
||||
user.visible_message("[user] closes [M]'s [parse_zone(selected_zone)] with [close_tool] and removes [I].", \
|
||||
"<span class='notice'>You close [M]'s [parse_zone(selected_zone)] with [close_tool] and remove [I].</span>")
|
||||
qdel(S)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to hold a [is_robotic ? "screwdriver" : "cautery"] in your inactive hand to stop [M]'s surgery!</span>")
|
||||
|
||||
/proc/get_location_modifier(mob/M)
|
||||
var/turf/T = get_turf(M)
|
||||
if(locate(/obj/structure/table/optable, T))
|
||||
return 1
|
||||
else if(locate(/obj/structure/table, T))
|
||||
return 0.8
|
||||
else if(locate(/obj/structure/bed, T))
|
||||
return 0.7
|
||||
else
|
||||
return 0.5
|
||||
|
||||
|
||||
/proc/get_location_accessible(mob/M, location)
|
||||
var/covered_locations = 0 //based on body_parts_covered
|
||||
var/face_covered = 0 //based on flags_inv
|
||||
var/eyesmouth_covered = 0 //based on flags_cover
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
for(var/obj/item/clothing/I in list(C.back, C.wear_mask, C.head))
|
||||
covered_locations |= I.body_parts_covered
|
||||
face_covered |= I.flags_inv
|
||||
eyesmouth_covered |= I.flags_cover
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
for(var/obj/item/I in list(H.wear_suit, H.w_uniform, H.shoes, H.belt, H.gloves, H.glasses, H.ears))
|
||||
covered_locations |= I.body_parts_covered
|
||||
face_covered |= I.flags_inv
|
||||
eyesmouth_covered |= I.flags_cover
|
||||
|
||||
switch(location)
|
||||
if(BODY_ZONE_HEAD)
|
||||
if(covered_locations & HEAD)
|
||||
return 0
|
||||
if(BODY_ZONE_PRECISE_EYES)
|
||||
if(covered_locations & HEAD || face_covered & HIDEEYES || eyesmouth_covered & GLASSESCOVERSEYES)
|
||||
return 0
|
||||
if(BODY_ZONE_PRECISE_MOUTH)
|
||||
if(covered_locations & HEAD || face_covered & HIDEFACE || eyesmouth_covered & MASKCOVERSMOUTH || eyesmouth_covered & HEADCOVERSMOUTH)
|
||||
return 0
|
||||
if(BODY_ZONE_CHEST)
|
||||
if(covered_locations & CHEST)
|
||||
return 0
|
||||
if(BODY_ZONE_PRECISE_GROIN)
|
||||
if(covered_locations & GROIN)
|
||||
return 0
|
||||
if(BODY_ZONE_L_ARM)
|
||||
if(covered_locations & ARM_LEFT)
|
||||
return 0
|
||||
if(BODY_ZONE_R_ARM)
|
||||
if(covered_locations & ARM_RIGHT)
|
||||
return 0
|
||||
if(BODY_ZONE_L_LEG)
|
||||
if(covered_locations & LEG_LEFT)
|
||||
return 0
|
||||
if(BODY_ZONE_R_LEG)
|
||||
if(covered_locations & LEG_RIGHT)
|
||||
return 0
|
||||
if(BODY_ZONE_PRECISE_L_HAND)
|
||||
if(covered_locations & HAND_LEFT)
|
||||
return 0
|
||||
if(BODY_ZONE_PRECISE_R_HAND)
|
||||
if(covered_locations & HAND_RIGHT)
|
||||
return 0
|
||||
if(BODY_ZONE_PRECISE_L_FOOT)
|
||||
if(covered_locations & FOOT_LEFT)
|
||||
return 0
|
||||
if(BODY_ZONE_PRECISE_R_FOOT)
|
||||
if(covered_locations & FOOT_RIGHT)
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
@@ -1,60 +1,60 @@
|
||||
/datum/surgery/implant_removal
|
||||
name = "implant removal"
|
||||
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/extract_implant, /datum/surgery_step/close)
|
||||
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
possible_locs = list(BODY_ZONE_CHEST)
|
||||
//extract implant
|
||||
/datum/surgery_step/extract_implant
|
||||
name = "extract implant"
|
||||
implements = list(/obj/item/hemostat = 100, TOOL_CROWBAR = 65)
|
||||
time = 64
|
||||
var/obj/item/implant/I = null
|
||||
/datum/surgery_step/extract_implant/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
for(var/obj/item/O in target.implants)
|
||||
I = O
|
||||
break
|
||||
if(I)
|
||||
display_results(user, target, "<span class='notice'>You begin to extract [I] from [target]'s [target_zone]...</span>",
|
||||
"[user] begins to extract [I] from [target]'s [target_zone].",
|
||||
"[user] begins to extract something from [target]'s [target_zone].")
|
||||
else
|
||||
display_results(user, target, "<span class='notice'>You look for an implant in [target]'s [target_zone]...</span>",
|
||||
"[user] looks for an implant in [target]'s [target_zone].",
|
||||
"[user] looks for something in [target]'s [target_zone].")
|
||||
|
||||
/datum/surgery_step/extract_implant/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
if(I)
|
||||
display_results(user, target, "<span class='notice'>You successfully remove [I] from [target]'s [target_zone].</span>",
|
||||
"[user] successfully removes [I] from [target]'s [target_zone]!",
|
||||
"[user] successfully removes something from [target]'s [target_zone]!")
|
||||
I.removed(target)
|
||||
|
||||
var/obj/item/implantcase/case
|
||||
for(var/obj/item/implantcase/ic in user.held_items)
|
||||
case = ic
|
||||
break
|
||||
if(!case)
|
||||
case = locate(/obj/item/implantcase) in get_turf(target)
|
||||
if(case && !case.imp)
|
||||
case.imp = I
|
||||
I.forceMove(case)
|
||||
case.update_icon()
|
||||
display_results(user, target, "<span class='notice'>You place [I] into [case].</span>",
|
||||
"[user] places [I] into [case]!",
|
||||
"[user] places it into [case]!")
|
||||
else
|
||||
qdel(I)
|
||||
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't find anything in [target]'s [target_zone]!</span>")
|
||||
return 1
|
||||
/datum/surgery/implant_removal/mechanic
|
||||
name = "implant removal"
|
||||
requires_bodypart_type = BODYPART_ROBOTIC
|
||||
steps = list(
|
||||
/datum/surgery_step/mechanic_open,
|
||||
/datum/surgery_step/open_hatch,
|
||||
/datum/surgery_step/mechanic_unwrench,
|
||||
/datum/surgery_step/extract_implant,
|
||||
/datum/surgery_step/mechanic_wrench,
|
||||
/datum/surgery_step/mechanic_close)
|
||||
/datum/surgery/implant_removal
|
||||
name = "implant removal"
|
||||
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/extract_implant, /datum/surgery_step/close)
|
||||
target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
possible_locs = list(BODY_ZONE_CHEST)
|
||||
//extract implant
|
||||
/datum/surgery_step/extract_implant
|
||||
name = "extract implant"
|
||||
implements = list(/obj/item/hemostat = 100, TOOL_CROWBAR = 65)
|
||||
time = 64
|
||||
var/obj/item/implant/I = null
|
||||
/datum/surgery_step/extract_implant/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
for(var/obj/item/O in target.implants)
|
||||
I = O
|
||||
break
|
||||
if(I)
|
||||
display_results(user, target, "<span class='notice'>You begin to extract [I] from [target]'s [target_zone]...</span>",
|
||||
"[user] begins to extract [I] from [target]'s [target_zone].",
|
||||
"[user] begins to extract something from [target]'s [target_zone].")
|
||||
else
|
||||
display_results(user, target, "<span class='notice'>You look for an implant in [target]'s [target_zone]...</span>",
|
||||
"[user] looks for an implant in [target]'s [target_zone].",
|
||||
"[user] looks for something in [target]'s [target_zone].")
|
||||
|
||||
/datum/surgery_step/extract_implant/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
if(I)
|
||||
display_results(user, target, "<span class='notice'>You successfully remove [I] from [target]'s [target_zone].</span>",
|
||||
"[user] successfully removes [I] from [target]'s [target_zone]!",
|
||||
"[user] successfully removes something from [target]'s [target_zone]!")
|
||||
I.removed(target)
|
||||
|
||||
var/obj/item/implantcase/case
|
||||
for(var/obj/item/implantcase/ic in user.held_items)
|
||||
case = ic
|
||||
break
|
||||
if(!case)
|
||||
case = locate(/obj/item/implantcase) in get_turf(target)
|
||||
if(case && !case.imp)
|
||||
case.imp = I
|
||||
I.forceMove(case)
|
||||
case.update_icon()
|
||||
display_results(user, target, "<span class='notice'>You place [I] into [case].</span>",
|
||||
"[user] places [I] into [case]!",
|
||||
"[user] places it into [case]!")
|
||||
else
|
||||
qdel(I)
|
||||
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't find anything in [target]'s [target_zone]!</span>")
|
||||
return 1
|
||||
/datum/surgery/implant_removal/mechanic
|
||||
name = "implant removal"
|
||||
requires_bodypart_type = BODYPART_ROBOTIC
|
||||
steps = list(
|
||||
/datum/surgery_step/mechanic_open,
|
||||
/datum/surgery_step/open_hatch,
|
||||
/datum/surgery_step/mechanic_unwrench,
|
||||
/datum/surgery_step/extract_implant,
|
||||
/datum/surgery_step/mechanic_wrench,
|
||||
/datum/surgery_step/mechanic_close)
|
||||
|
||||
@@ -1,60 +1,60 @@
|
||||
/////AUGMENTATION SURGERIES//////
|
||||
//SURGERY STEPS
|
||||
/datum/surgery_step/replace
|
||||
name = "sever muscles"
|
||||
implements = list(/obj/item/scalpel = 100, TOOL_WIRECUTTER = 55)
|
||||
time = 32
|
||||
|
||||
|
||||
/datum/surgery_step/replace/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, "<span class ='notice'>You begin to sever the muscles on [target]'s [parse_zone(user.zone_selected)]...</span>",
|
||||
"[user] begins to sever the muscles on [target]'s [parse_zone(user.zone_selected)].",
|
||||
"[user] begins an incision on [target]'s [parse_zone(user.zone_selected)].")
|
||||
|
||||
/datum/surgery_step/replace_limb
|
||||
name = "replace limb"
|
||||
implements = list(/obj/item/bodypart = 100, /obj/item/organ_storage = 100)
|
||||
time = 32
|
||||
var/obj/item/bodypart/L = null // L because "limb"
|
||||
/datum/surgery_step/replace_limb/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
if(istype(tool, /obj/item/organ_storage) && istype(tool.contents[1], /obj/item/bodypart))
|
||||
tool = tool.contents[1]
|
||||
var/obj/item/bodypart/aug = tool
|
||||
if(aug.status != BODYPART_ROBOTIC)
|
||||
to_chat(user, "<span class='warning'>That's not an augment, silly!</span>")
|
||||
return -1
|
||||
if(aug.body_zone != target_zone)
|
||||
to_chat(user, "<span class='warning'>[tool] isn't the right type for [parse_zone(target_zone)].</span>")
|
||||
return -1
|
||||
L = surgery.operated_bodypart
|
||||
if(L)
|
||||
display_results(user, target, "<span class ='notice'>You begin to augment [target]'s [parse_zone(user.zone_selected)]...</span>",
|
||||
"[user] begins to augment [target]'s [parse_zone(user.zone_selected)] with [aug].",
|
||||
"[user] begins to augment [target]'s [parse_zone(user.zone_selected)].")
|
||||
else
|
||||
user.visible_message("[user] looks for [target]'s [parse_zone(user.zone_selected)].", "<span class ='notice'>You look for [target]'s [parse_zone(user.zone_selected)]...</span>")
|
||||
|
||||
//ACTUAL SURGERIES
|
||||
/datum/surgery/augmentation
|
||||
name = "Augmentation"
|
||||
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/replace, /datum/surgery_step/saw, /datum/surgery_step/replace_limb)
|
||||
species = list(/mob/living/carbon/human)
|
||||
possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD)
|
||||
requires_real_bodypart = TRUE
|
||||
//SURGERY STEP SUCCESSES
|
||||
/datum/surgery_step/replace_limb/success(mob/user, mob/living/carbon/target, target_zone, obj/item/bodypart/tool, datum/surgery/surgery)
|
||||
if(L)
|
||||
if(istype(tool, /obj/item/organ_storage))
|
||||
tool.icon_state = initial(tool.icon_state)
|
||||
tool.desc = initial(tool.desc)
|
||||
tool.cut_overlays()
|
||||
tool = tool.contents[1]
|
||||
if(istype(tool) && user.temporarilyRemoveItemFromInventory(tool))
|
||||
tool.replace_limb(target, TRUE)
|
||||
display_results(user, target, "<span class='notice'>You successfully augment [target]'s [parse_zone(target_zone)].</span>",
|
||||
"[user] successfully augments [target]'s [parse_zone(target_zone)] with [tool]!",
|
||||
"[user] successfully augments [target]'s [parse_zone(target_zone)]!")
|
||||
log_combat(user, target, "augmented", addition="by giving him new [parse_zone(target_zone)] INTENT: [uppertext(user.a_intent)]")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[target] has no organic [parse_zone(target_zone)] there!</span>")
|
||||
return TRUE
|
||||
/////AUGMENTATION SURGERIES//////
|
||||
//SURGERY STEPS
|
||||
/datum/surgery_step/replace
|
||||
name = "sever muscles"
|
||||
implements = list(/obj/item/scalpel = 100, TOOL_WIRECUTTER = 55)
|
||||
time = 32
|
||||
|
||||
|
||||
/datum/surgery_step/replace/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, "<span class ='notice'>You begin to sever the muscles on [target]'s [parse_zone(user.zone_selected)]...</span>",
|
||||
"[user] begins to sever the muscles on [target]'s [parse_zone(user.zone_selected)].",
|
||||
"[user] begins an incision on [target]'s [parse_zone(user.zone_selected)].")
|
||||
|
||||
/datum/surgery_step/replace_limb
|
||||
name = "replace limb"
|
||||
implements = list(/obj/item/bodypart = 100, /obj/item/organ_storage = 100)
|
||||
time = 32
|
||||
var/obj/item/bodypart/L = null // L because "limb"
|
||||
/datum/surgery_step/replace_limb/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
if(istype(tool, /obj/item/organ_storage) && istype(tool.contents[1], /obj/item/bodypart))
|
||||
tool = tool.contents[1]
|
||||
var/obj/item/bodypart/aug = tool
|
||||
if(aug.status != BODYPART_ROBOTIC)
|
||||
to_chat(user, "<span class='warning'>That's not an augment, silly!</span>")
|
||||
return -1
|
||||
if(aug.body_zone != target_zone)
|
||||
to_chat(user, "<span class='warning'>[tool] isn't the right type for [parse_zone(target_zone)].</span>")
|
||||
return -1
|
||||
L = surgery.operated_bodypart
|
||||
if(L)
|
||||
display_results(user, target, "<span class ='notice'>You begin to augment [target]'s [parse_zone(user.zone_selected)]...</span>",
|
||||
"[user] begins to augment [target]'s [parse_zone(user.zone_selected)] with [aug].",
|
||||
"[user] begins to augment [target]'s [parse_zone(user.zone_selected)].")
|
||||
else
|
||||
user.visible_message("[user] looks for [target]'s [parse_zone(user.zone_selected)].", "<span class ='notice'>You look for [target]'s [parse_zone(user.zone_selected)]...</span>")
|
||||
|
||||
//ACTUAL SURGERIES
|
||||
/datum/surgery/augmentation
|
||||
name = "Augmentation"
|
||||
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/replace, /datum/surgery_step/saw, /datum/surgery_step/replace_limb)
|
||||
target_mobtypes = list(/mob/living/carbon/human)
|
||||
possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD)
|
||||
requires_real_bodypart = TRUE
|
||||
//SURGERY STEP SUCCESSES
|
||||
/datum/surgery_step/replace_limb/success(mob/user, mob/living/carbon/target, target_zone, obj/item/bodypart/tool, datum/surgery/surgery)
|
||||
if(L)
|
||||
if(istype(tool, /obj/item/organ_storage))
|
||||
tool.icon_state = initial(tool.icon_state)
|
||||
tool.desc = initial(tool.desc)
|
||||
tool.cut_overlays()
|
||||
tool = tool.contents[1]
|
||||
if(istype(tool) && user.temporarilyRemoveItemFromInventory(tool))
|
||||
tool.replace_limb(target, TRUE)
|
||||
display_results(user, target, "<span class='notice'>You successfully augment [target]'s [parse_zone(target_zone)].</span>",
|
||||
"[user] successfully augments [target]'s [parse_zone(target_zone)] with [tool]!",
|
||||
"[user] successfully augments [target]'s [parse_zone(target_zone)]!")
|
||||
log_combat(user, target, "augmented", addition="by giving him new [parse_zone(target_zone)] INTENT: [uppertext(user.a_intent)]")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[target] has no organic [parse_zone(target_zone)] there!</span>")
|
||||
return TRUE
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/surgery/organ_manipulation
|
||||
name = "Organ manipulation"
|
||||
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
name = "organ manipulation"
|
||||
target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD)
|
||||
requires_real_bodypart = 1
|
||||
steps = list(
|
||||
@@ -26,7 +26,7 @@
|
||||
/datum/surgery/organ_manipulation/alien
|
||||
name = "Alien organ manipulation"
|
||||
possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD, BODY_ZONE_PRECISE_GROIN, BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)
|
||||
species = list(/mob/living/carbon/alien/humanoid)
|
||||
target_mobtypes = list(/mob/living/carbon/alien/humanoid)
|
||||
steps = list(
|
||||
/datum/surgery_step/saw,
|
||||
/datum/surgery_step/incise,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/surgery/penis_augmentation
|
||||
name = "Penis augmentation"
|
||||
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/augment_penis, /datum/surgery_step/close)
|
||||
species = list(/mob/living/carbon/human)
|
||||
target_mobtypes = list(/mob/living/carbon/human)
|
||||
possible_locs = list(BODY_ZONE_PRECISE_GROIN)
|
||||
|
||||
/datum/surgery_step/augment_penis
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/surgery/prosthetic_replacement
|
||||
name = "Prosthetic replacement"
|
||||
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/add_prosthetic)
|
||||
species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
|
||||
possible_locs = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG, BODY_ZONE_HEAD)
|
||||
requires_bodypart = FALSE //need a missing limb
|
||||
requires_bodypart_type = 0
|
||||
|
||||
+174
-157
@@ -1,157 +1,174 @@
|
||||
/datum/surgery
|
||||
var/name = "surgery"
|
||||
var/desc = "surgery description"
|
||||
var/status = 1
|
||||
var/list/steps = list() //Steps in a surgery
|
||||
var/step_in_progress = 0 //Actively performing a Surgery
|
||||
var/can_cancel = 1 //Can cancel this surgery after step 1 with cautery
|
||||
var/list/species = 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 = 0 //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 = 0 //Some surgeries don't work on limbs that don't really exist
|
||||
|
||||
/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/carbon/target)
|
||||
// if 0 surgery wont show up in list
|
||||
// put special restrictions here
|
||||
return 1
|
||||
|
||||
/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)
|
||||
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, "<span class='warning'>This step requires a different tool!</span>")
|
||||
return TRUE
|
||||
|
||||
/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/structure/table, T))
|
||||
propability = 0.8
|
||||
else if(locate(/obj/machinery/stasis, T))
|
||||
propability = 0.9
|
||||
else if(locate(/obj/structure/bed, T))
|
||||
propability = 0.7
|
||||
|
||||
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
|
||||
|
||||
if(iscyborg(user))
|
||||
var/mob/living/silicon/robot/R = user
|
||||
var/obj/item/surgical_processor/SP = locate() in R.module.modules
|
||||
if(!SP)
|
||||
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 || !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.
|
||||
//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
|
||||
/datum/surgery
|
||||
var/name = "surgery"
|
||||
var/desc = "surgery description"
|
||||
var/status = 1
|
||||
var/list/steps = list() //Steps in a surgery
|
||||
var/step_in_progress = 0 //Actively performing a Surgery
|
||||
var/can_cancel = 1 //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 = 0 //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 = 0 //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/requires_tech = FALSE
|
||||
var/replaced_by
|
||||
|
||||
/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/patient) //FALSE to not show in list
|
||||
. = TRUE
|
||||
if(replaced_by == /datum/surgery)
|
||||
return FALSE
|
||||
|
||||
if(HAS_TRAIT(user, 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)
|
||||
if (replaced_by in SP.advanced_surgeries)
|
||||
return FALSE
|
||||
if(type in SP.advanced_surgeries)
|
||||
return TRUE
|
||||
|
||||
|
||||
var/turf/T = get_turf(patient)
|
||||
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))
|
||||
return .
|
||||
if(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 1
|
||||
|
||||
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, "<span class='warning'>This step requires a different tool!</span>")
|
||||
return TRUE
|
||||
|
||||
/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/structure/table, T))
|
||||
propability = 0.8
|
||||
else if(locate(/obj/machinery/stasis, T))
|
||||
propability = 0.9
|
||||
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(initial(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
|
||||
@@ -1,126 +1,130 @@
|
||||
/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 = FALSE //does the surgery step require an open hand? If true, ignores implements. Compatible with accept_any_item.
|
||||
var/accept_any_item = FALSE //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 = 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/success = FALSE
|
||||
if(accept_hand)
|
||||
if(!tool)
|
||||
success = TRUE
|
||||
if(iscyborg(user))
|
||||
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)
|
||||
return initiate(user, target, target_zone, tool, surgery, try_to_fail)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to expose [target]'s [parse_zone(target_zone)] to perform surgery on it!</span>")
|
||||
return TRUE //returns TRUE 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 TRUE
|
||||
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)
|
||||
surgery.step_in_progress = TRUE
|
||||
var/speed_mod = 1
|
||||
var/advance = FALSE
|
||||
if(preop(user, target, target_zone, tool, surgery) == -1)
|
||||
surgery.step_in_progress = FALSE
|
||||
return FALSE
|
||||
if(tool)
|
||||
speed_mod = tool.toolspeed
|
||||
if(do_after(user, time * speed_mod, target = target))
|
||||
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)) && chem_check(target) && !try_to_fail)
|
||||
if(success(user, target, target_zone, tool, surgery))
|
||||
advance = TRUE
|
||||
else
|
||||
if(failure(user, target, target_zone, tool, surgery))
|
||||
advance = TRUE
|
||||
if(advance && !repeatable)
|
||||
surgery.status++
|
||||
if(surgery.status > surgery.steps.len)
|
||||
surgery.complete()
|
||||
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)
|
||||
display_results(user, target, "<span class='notice'>You begin to perform surgery on [target]...</span>",
|
||||
"[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)
|
||||
display_results(user, target, "<span class='notice'>You succeed.</span>",
|
||||
"[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)
|
||||
display_results(user, target, "<span class='warning'>You screw up!</span>",
|
||||
"<span class='warning'>[user] screws up!</span>",
|
||||
"[user] finishes.", TRUE) //By default the patient will notice if the wrong thing has been cut
|
||||
return FALSE
|
||||
|
||||
/datum/surgery_step/proc/tool_check(mob/user, obj/item/tool)
|
||||
return TRUE
|
||||
/datum/surgery_step/proc/chem_check(mob/living/carbon/target)
|
||||
if(!LAZYLEN(chems_needed))
|
||||
return TRUE
|
||||
if(require_all_chems)
|
||||
. = TRUE
|
||||
for(var/R in chems_needed)
|
||||
if(!target.reagents.has_reagent(R))
|
||||
return FALSE
|
||||
else
|
||||
. = FALSE
|
||||
for(var/R in chems_needed)
|
||||
if(target.reagents.has_reagent(R))
|
||||
return TRUE
|
||||
/datum/surgery_step/proc/get_chem_list()
|
||||
if(!LAZYLEN(chems_needed))
|
||||
return
|
||||
var/list/chems = list()
|
||||
for(var/R in chems_needed)
|
||||
var/datum/reagent/temp = GLOB.chemical_reagents_list[R]
|
||||
if(temp)
|
||||
var/chemname = temp.name
|
||||
chems += chemname
|
||||
return english_list(chems, and_text = require_all_chems ? " and " : " or ")
|
||||
|
||||
//Replaces visible_message during operations so only people looking over the surgeon can tell what they're doing, allowing for shenanigans.
|
||||
/datum/surgery_step/proc/display_results(mob/user, mob/living/carbon/target, self_message, detailed_message, vague_message, target_detailed = FALSE)
|
||||
var/list/detailed_mobs = get_hearers_in_view(1, user) //Only the surgeon and people looking over his shoulder can see the operation clearly
|
||||
if(!target_detailed)
|
||||
detailed_mobs -= target //The patient can't see well what's going on, unless it's something like getting cut
|
||||
user.visible_message(detailed_message, self_message, vision_distance = 1, ignored_mobs = target_detailed ? null : target)
|
||||
user.visible_message(vague_message, "", ignored_mobs = detailed_mobs)
|
||||
/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 = FALSE //does the surgery step require an open hand? If true, ignores implements. Compatible with accept_any_item.
|
||||
var/accept_any_item = FALSE //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 = 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?
|
||||
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)
|
||||
success = TRUE
|
||||
if(iscyborg(user))
|
||||
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)
|
||||
return initiate(user, target, target_zone, tool, surgery, try_to_fail)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to expose [target]'s [parse_zone(target_zone)] to perform surgery on it!</span>")
|
||||
return TRUE //returns TRUE 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 TRUE
|
||||
else
|
||||
surgery.status--
|
||||
return 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
|
||||
if(preop(user, target, target_zone, tool, surgery) == -1)
|
||||
surgery.step_in_progress = FALSE
|
||||
return FALSE
|
||||
if(tool)
|
||||
speed_mod = tool.toolspeed
|
||||
if(do_after(user, time * speed_mod, target = target))
|
||||
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) && !silicons_obey_prob)) && chem_check(target) && !try_to_fail)
|
||||
if(success(user, target, target_zone, tool, surgery))
|
||||
advance = TRUE
|
||||
else
|
||||
if(failure(user, target, target_zone, tool, surgery))
|
||||
advance = TRUE
|
||||
if(advance && !repeatable)
|
||||
surgery.status++
|
||||
if(surgery.status > surgery.steps.len)
|
||||
surgery.complete()
|
||||
surgery.step_in_progress = FALSE
|
||||
return advance
|
||||
|
||||
/datum/surgery_step/proc/preop(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, "<span class='notice'>You begin to perform surgery on [target]...</span>",
|
||||
"[user] begins to perform surgery on [target].",
|
||||
"[user] begins to perform surgery on [target].")
|
||||
|
||||
/datum/surgery_step/proc/success(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, "<span class='notice'>You succeed.</span>",
|
||||
"[user] succeeds!",
|
||||
"[user] finishes.")
|
||||
return TRUE
|
||||
|
||||
/datum/surgery_step/proc/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
display_results(user, target, "<span class='warning'>You screw up!</span>",
|
||||
"<span class='warning'>[user] screws up!</span>",
|
||||
"[user] finishes.", TRUE) //By default the patient will notice if the wrong thing has been cut
|
||||
return FALSE
|
||||
|
||||
/datum/surgery_step/proc/tool_check(mob/user, obj/item/tool)
|
||||
return TRUE
|
||||
|
||||
/datum/surgery_step/proc/chem_check(mob/living/target)
|
||||
if(!LAZYLEN(chems_needed))
|
||||
return TRUE
|
||||
if(require_all_chems)
|
||||
. = TRUE
|
||||
for(var/R in chems_needed)
|
||||
if(!target.reagents.has_reagent(R))
|
||||
return FALSE
|
||||
else
|
||||
. = FALSE
|
||||
for(var/R in chems_needed)
|
||||
if(target.reagents.has_reagent(R))
|
||||
return TRUE
|
||||
/datum/surgery_step/proc/get_chem_list()
|
||||
if(!LAZYLEN(chems_needed))
|
||||
return
|
||||
var/list/chems = list()
|
||||
for(var/R in chems_needed)
|
||||
var/datum/reagent/temp = GLOB.chemical_reagents_list[R]
|
||||
if(temp)
|
||||
var/chemname = temp.name
|
||||
chems += chemname
|
||||
return english_list(chems, and_text = require_all_chems ? " and " : " or ")
|
||||
|
||||
//Replaces visible_message during operations so only people looking over the surgeon can tell what they're doing, allowing for shenanigans.
|
||||
/datum/surgery_step/proc/display_results(mob/user, mob/living/carbon/target, self_message, detailed_message, vague_message, target_detailed = FALSE)
|
||||
var/list/detailed_mobs = get_hearers_in_view(1, user) //Only the surgeon and people looking over his shoulder can see the operation clearly
|
||||
if(!target_detailed)
|
||||
detailed_mobs -= target //The patient can't see well what's going on, unless it's something like getting cut
|
||||
user.visible_message(detailed_message, self_message, vision_distance = 1, ignored_mobs = target_detailed ? null : target)
|
||||
user.visible_message(vague_message, "", ignored_mobs = detailed_mobs)
|
||||
|
||||
Reference in New Issue
Block a user