[MIRROR] Various Surgery & Medical fixes, QoL, and adjustments (#11949)

Co-authored-by: Cameron Lennox <killer65311@gmail.com>
This commit is contained in:
CHOMPStation2StaffMirrorBot
2025-11-08 21:23:20 -07:00
committed by GitHub
parent 56b99cc173
commit a6dcc16233
35 changed files with 500 additions and 216 deletions

View File

@@ -52,12 +52,6 @@
#define ANTIBIO_OD 2
#define ANTIBIO_SUPER 3
// Chemistry lists.
var/list/tachycardics = list(REAGENT_ID_COFFEE, REAGENT_ID_INAPROVALINE, REAGENT_ID_HYPERZINE, REAGENT_ID_NITROGLYCERIN,REAGENT_ID_THIRTEENLOKO, REAGENT_ID_NICOTINE) // Increase heart rate.
var/list/bradycardics = list(REAGENT_ID_NEUROTOXIN, REAGENT_ID_CRYOXADONE, REAGENT_ID_CLONEXADONE, REAGENT_ID_BLISS, REAGENT_ID_STOXIN, REAGENT_ID_AMBROSIAEXTRACT) // Decrease heart rate.
var/list/heartstopper = list(REAGENT_ID_POTASSIUMCHLOROPHORIDE, REAGENT_ID_ZOMBIEPOWDER) // This stops the heart.
var/list/cheartstopper = list(REAGENT_ID_POTASSIUMCHLORIDE) // This stops the heart when overdose is met. -- c = conditional
#define MAX_PILL_SPRITE 24 //max icon state of the pill sprites
#define MAX_BOTTLE_SPRITE 4 //max icon state of the pill sprites
#define MAX_PATCH_SPRITE 4 //max icon state of the patch sprites, CHOMPedit

View File

@@ -51,7 +51,7 @@
#define ROBOLIMB_REPAIR_CAP 60 //CHOMPedit, bumping it up to 60 to keep consistency with our global cap of 60
#define ORGAN_FLESH 0 // Normal organic organs.
#define ORGAN_ASSISTED 1 // Like pacemakers, not robotic
#define ORGAN_ASSISTED 1 // Like an LVAD - No pulse, but still organic.
#define ORGAN_ROBOT 2 // Fully robotic, no organic parts
#define ORGAN_LIFELIKE 3 // Robotic, made to appear organic
#define ORGAN_NANOFORM 4 // Fully nanoswarm organ

View File

@@ -44,42 +44,6 @@
#define MUTE 0x2
#define DEAF 0x4
#define SPINE 0x8
/* Traitgenes (Blocks have finally been retired, huzzah!
// The way blocks are handled badly needs a rewrite, this is horrible.
// Too much of a project to handle at the moment, TODO for later.)
var/BLINDBLOCK = 0
var/DEAFBLOCK = 0
var/HULKBLOCK = 0
var/TELEBLOCK = 0
var/FIREBLOCK = 0
var/XRAYBLOCK = 0
var/CLUMSYBLOCK = 0
var/FAKEBLOCK = 0
var/COUGHBLOCK = 0
var/GLASSESBLOCK = 0
var/EPILEPSYBLOCK = 0
var/TWITCHBLOCK = 0
var/NERVOUSBLOCK = 0
var/MONKEYBLOCK = STRUCDNASIZE
var/BLOCKADD = 0
var/DIFFMUT = 0
var/HEADACHEBLOCK = 0
var/NOBREATHBLOCK = 0
var/REMOTEVIEWBLOCK = 0
var/REGENERATEBLOCK = 0
var/INCREASERUNBLOCK = 0
var/REMOTETALKBLOCK = 0
var/MORPHBLOCK = 0
var/BLENDBLOCK = 0
var/HALLUCINATIONBLOCK = 0
var/NOPRINTSBLOCK = 0
var/SHOCKIMMUNITYBLOCK = 0
var/SMALLSIZEBLOCK = 0
*/
// Define block bounds (off-low,off-high,on-low,on-high)
// Used in setupgame.dm
#define DNA_DEFAULT_BOUNDS list(1,2049,2050,4095)

View File

@@ -1387,3 +1387,34 @@ GLOBAL_LIST_INIT(material_synth_list, list(
))
GLOBAL_LIST_EMPTY(virusDB) // Stores discovered viruses
///Medications that speed up your heartrate
GLOBAL_LIST_INIT(tachycardics, list(
REAGENT_ID_COFFEE,
REAGENT_ID_INAPROVALINE,
REAGENT_ID_HYPERZINE,
REAGENT_ID_NITROGLYCERIN,
REAGENT_ID_THIRTEENLOKO,
REAGENT_ID_NICOTINE
))
///Medications that slow down your heartrate
GLOBAL_LIST_INIT(bradycardics, list(
REAGENT_ID_NEUROTOXIN,
REAGENT_ID_CRYOXADONE,
REAGENT_ID_CLONEXADONE,
REAGENT_ID_BLISS,
REAGENT_ID_STOXIN,
REAGENT_ID_AMBROSIAEXTRACT
))
///Medications that stop your heart
GLOBAL_LIST_INIT(heartstopper, list(
REAGENT_ID_POTASSIUMCHLOROPHORIDE,
REAGENT_ID_ZOMBIEPOWDER
))
///Medications that stop your heart under certain conditions.
GLOBAL_LIST_INIT(cheartstopper, list(
REAGENT_ID_POTASSIUMCHLORIDE
))

View File

@@ -1121,16 +1121,23 @@ GLOBAL_LIST_INIT(common_tools, list(
return .
// Returns an instance of a valid surgery surface.
/mob/living/proc/get_surgery_surface()
if(!lying)
return null // Not lying down means no surface.
var/obj/surface = null
/mob/living/proc/get_surgery_cleanliness(mob/living/user)
if(!lying && user != src)
return null // Not lying down means no surface (blocks surgery)
var/cleanliness = 0
for(var/obj/O in loc) // Looks for the best surface.
if(O.surgery_odds)
if(!surface || surface.surgery_odds < O.surgery_odds)
surface = O
if(surface)
return surface
if(O.surgery_cleanliness)
if(!cleanliness || cleanliness < O.surgery_cleanliness)
cleanliness = O.surgery_cleanliness
if(!cleanliness) //We have no good objects on the turf. Time to check the floor!
var/turf/T = get_turf(src)
if(T.was_bloodied) //floor is contaminated
return 0
//Turf generally start with a germ level of 110 and cap out at 200.
//Can use sterilizine to lower germs of the floor, or space cleaner.
cleanliness = CLAMP(100 - T.germ_level, 0, 25)
return cleanliness
/proc/reverse_direction(dir)
return GLOB.reverse_dir[dir]

View File

@@ -9,7 +9,7 @@
use_power = USE_POWER_IDLE
idle_power_usage = 1
active_power_usage = 5
surgery_odds = 100
surgery_cleanliness = 100
throwpass = 1
var/mob/living/carbon/human/victim = null
var/strapped = 0.0

View File

@@ -186,7 +186,7 @@
problems |= ALCOHOL_POISONING
if(our_user.chem_effects[CE_ALCOHOL])
is_drunk = TRUE
if(our_user.vessel.total_volume < our_user.vessel.maximum_volume) //Bloodloss
if(our_user.vessel.total_volume < (our_user.vessel.maximum_volume*0.95)) //Bloodloss. Only happens at below 95% blood.
problems |= BLOODLOSS
if(!problems) //Minor stuff that we really don't care much about, but can be annoying! So let's tell people how to fix it. But only if they don't have a health crisis going on!

View File

@@ -395,8 +395,10 @@
return
//set oxyloss so that the patient is just barely in crit, if possible
var/barely_in_crit = H.get_crit_point() - 1
var/barely_in_crit = -(H.get_crit_point() - 1) //Assume get_crit_point will return -50, so we take the inverse of it.
var/adjust_health = barely_in_crit - H.health //need to increase health by this much
if(adjust_health < 0) //We got a negative value. Safety in case of weird fuckery.
adjust_health *= -1
H.adjustOxyLoss(-adjust_health)
if(H.isSynthetic())

View File

@@ -223,7 +223,7 @@
icon = 'icons/obj/rollerbed.dmi'
icon_state = "rollerbed"
anchored = FALSE
surgery_odds = 50 //VOREStation Edit
surgery_cleanliness = 60
var/bedtype = /obj/structure/bed/roller
var/rollertype = /obj/item/roller
flippable = FALSE
@@ -231,6 +231,7 @@
/obj/structure/bed/roller/adv
name = "advanced roller bed"
icon_state = "rollerbedadv"
surgery_cleanliness = 75
bedtype = /obj/structure/bed/roller/adv
rollertype = /obj/item/roller/adv

View File

@@ -240,50 +240,96 @@
var/sound = "heartbeat"
var/sound_strength = "cannot hear"
var/heartbeat = 0
var/obj/item/organ/internal/heart/heart = M.internal_organs_by_name[O_HEART]
if(heart && !(heart.robotic >= ORGAN_ROBOT))
heartbeat = 1
if(M.stat == DEAD || (M.status_flags & FAKEDEATH))
sound_strength = "cannot hear"
sound = "anything"
else
switch(body_part)
//TORSO:
//ORGANS INVENTORY: Heart, Lungs, Spleen, Voicebox,
if(BP_TORSO)
//Chompstation edit start
for(var/belly in M.vore_organs) //Pervy edit.
for(var/belly in M.vore_organs) //Pervy edit. //CHOMPEdit Start
var/obj/belly/B = belly
for(var/mob/living/carbon/human/H in B)
if(H.size_multiplier < 0.5)
beat_size = pick("quiet ", "hushed " ,"low " ,"hushed ")
message_holder = pick("You can hear disparate heartbeats as well.", "You can hear a different [beat_size]heartbeat too.", "It sounds like there is more than one heartbeat." ,"You can pick up a [beat_size]heatbeat along with everything else.")
if(M.nutrition > 900) //dead
message_holder2 = pick("Your listening is troubled by the occasional deep groan of their body.", "There is some moderate bubbling in the background.", "They seem to have a healthy metabolism as well.")
//Chompstation edit end
message_holder2 = pick("Your listening is troubled by the occasional deep groan of their body.", "There is some moderate bubbling in the background.", "They seem to have a healthy metabolism as well.") //CHOMPEdit End
var/obj/item/organ/internal/heart/heart = M.internal_organs_by_name[O_HEART]
sound_strength = "hear"
sound = "no heartbeat"
if(heartbeat)
if(heart.is_bruised() || M.getOxyLoss() > 50)
sound = "[pick("odd noises in","weak")] heartbeat"
if(heart)
if(heart.is_bruised())
sound = span_warning("muffled heart sounds, as if fluid is around the heart") //yes this shows over the heart beinng robotic.
else if(heart.robotic) //They have JUST a heart but no heartbeat
if(heart.robotic == ORGAN_ASSISTED) //LVAD
sound = "a loud, continual, electronic hum"
else if(heart.robotic == ORGAN_ROBOT || heart.robotic == ORGAN_LIFELIKE)
sound = "a light, rhythmic, mechanical clicking"
else
sound = "a healthy heartbeat" //Vorestation edit
sound = span_warning("no heartbeat")
else
switch(M.pulse)
if(PULSE_NONE)
sound = "no heartbeat"
if(PULSE_SLOW)
sound = "a slow heartbeat"
if(PULSE_NORM)
sound = "a normal, healthy heartbeat"
if(PULSE_FAST)
sound = "a rapid heartbeat"
if(PULSE_2FAST)
sound = span_info("a very rapid heartbeat")
if(PULSE_THREADY)
sound = span_warning("an extremely rapid, thready, irregular heartbeat")
var/obj/item/organ/internal/heart/L = M.internal_organs_by_name[O_LUNGS]
var/obj/item/organ/internal/lungs/L = M.internal_organs_by_name[O_LUNGS]
if(!L || M.losebreath)
sound += " and no respiration"
sound += span_warning(" and no respiration")
else if(M.is_lung_ruptured() || M.getOxyLoss() > 50)
sound += " and [pick("wheezing","gurgling")] sounds"
sound += span_warning(" and [pick("wheezing","gurgling")] sounds")
else
sound += " and healthy respiration"
if(O_EYES,O_MOUTH)
//GROIN
//ORGANS INVENTORY: Appendix, Intestines, Kidneys, Liver, Spleen, Stomach.
//Of these, the Intestines, Stomach, Liver, and Kidneys make noise.
if(BP_GROIN)
var/obj/item/organ/internal/intestine/intestine = M.internal_organs_by_name[O_INTESTINE]
var/obj/item/organ/internal/stomach/stomach = M.internal_organs_by_name[O_STOMACH]
var/obj/item/organ/internal/kidneys/kidneys = M.internal_organs_by_name[O_KIDNEYS]
var/obj/item/organ/internal/liver/liver = M.internal_organs_by_name[O_LIVER]
sound_strength = "hear"
sound = span_warning("no gastric sounds,")
if(intestine)
if(intestine.is_bruised())
sound = span_warning("slowed intestinal sounds")
else
sound = "normal intestinal sounds,"
if(stomach)
if(stomach.is_bruised())
sound += span_warning(" slowed digestive sounds,")
else
sound += " with normal digestive sounds,"
else
sound += span_warning(" no digestive sounds,")
if(kidneys && kidneys.is_bruised())
sound += span_warning(" renal bruits,") //I don't really know how to convey this without using medical terminology.
else
sound += " no renal sounds,"
if(liver) //yeah, I didn't know your liver could make sounds either.
if(liver.is_bruised())
sound += span_warning(" and abnormal liver sounds.")
else
sound += " and normal liver sounds."
else
sound_strength = "cannot hear"
sound = "anything"
else
if(heartbeat)
sound_strength = "hear a weak"
sound = "pulse"
user.visible_message("[user] places [src] against [M]'s [body_part] and listens attentively.", "You place [src] against [their] [body_part]. You [sound_strength] [sound]. [message_holder] [message_holder2]") //Chomp edit. ([message holder] & [message_holder2])
return

View File

@@ -216,12 +216,21 @@
status += "MISSING"
if(org.status & ORGAN_MUTATED)
status += "weirdly shapen"
if(org.dislocated == 1) //VOREStation Edit Bugfix
if(org.dislocated == 1)
status += "dislocated"
if(org.status & ORGAN_BROKEN)
status += "hurts when touched"
//infection stuff
if(org.status & ORGAN_DEAD)
status += "is bruised and necrotic"
status += "necrotic"
else if(org.germ_level > INFECTION_LEVEL_TWO)
status += "feels like it's on fire!"
else if(org.germ_level > INFECTION_LEVEL_TWO-INFECTION_LEVEL_ONE) //Early warning
status += "warm to the touch"
if(LAZYLEN(org.wounds))
for(var/datum/wound/W in org.wounds)
if(!W.internal)
status += "hurting with a slowly growing bruise"
if(!org.is_usable() || org.is_dislocated())
status += "dangling uselessly"
if(status.len)

View File

@@ -286,7 +286,8 @@
if (src.stat)
msg += span_warning("[p_Theyre()] not responding to anything around [p_they()] and seems to be asleep.")
if((stat == 2 || src.losebreath) && get_dist(user, src) <= 3)
var/obj/item/organ/internal/lungs/L = internal_organs_by_name[O_LUNGS]
if(((stat == 2 || src.losebreath) || !L) && get_dist(user, src) <= 3)
msg += span_warning("[p_They()] [user.p_do()] not appear to be breathing.")
if(ishuman(user) && !user.stat && Adjacent(user))
user.visible_message(span_infoplain(span_bold("[user]") + " checks [src]'s pulse."), span_infoplain("You check [src]'s pulse."))

View File

@@ -2028,30 +2028,47 @@
temp = max(0, temp + modifier_shift) // No negative pulses.
if(Pump)
for(var/datum/reagent/R in reagents.reagent_list)
if(R.id in bradycardics)
if(temp <= Pump.standard_pulse_level + 3 && temp >= Pump.standard_pulse_level)
temp--
if(R.id in tachycardics)
if(temp <= Pump.standard_pulse_level + 1 && temp >= PULSE_NONE)
///Prevents duplicating a reagent if it's in our gut and blood
var/list/current_medications = list()
//Stuff in our stomach, such as coffee, nicotine, 13loko, etc.
for(var/datum/reagent/R in ingested.reagent_list)
if((R.id in GLOB.tachycardics) && !(R.id in current_medications))
if(temp < PULSE_THREADY && temp != PULSE_NONE) //If we really push it, we can get our pulse to thready.
temp++
if(R.id in heartstopper) //To avoid using fakedeath
current_medications += R.id
if((R.id in GLOB.bradycardics) && !(R.id in current_medications))
if(temp >= PULSE_NORM)
temp--
current_medications += R.id
//Stuff in our bloodstream. This is checked AFTER stomach so the heartstoppers can have their fun.
for(var/datum/reagent/R in reagents.reagent_list)
if((R.id in GLOB.tachycardics) && !(R.id in current_medications))
if(temp < PULSE_THREADY && temp != PULSE_NONE) //We can reach a thready pulse, but only if we actually have a pulse.
temp++
current_medications += R.id
if((R.id in GLOB.bradycardics) && !(R.id in current_medications))
if(temp >= PULSE_NORM) //Can get to PULSE_SLOW but never PULSE_NONE
temp--
current_medications += R.id
if(R.id in GLOB.heartstopper) //To avoid using fakedeath
temp = PULSE_NONE
if(R.id in cheartstopper) //Conditional heart-stoppage
break //No amount of medications is getting you out of this.
if(R.id in GLOB.cheartstopper) //Conditional heart-stoppage
if(R.volume >= R.overdose)
temp = PULSE_NONE
break //No amount of medications is getting you out of this.
return temp * brain_modifier
//handles different chems' influence on pulse
for(var/datum/reagent/R in reagents.reagent_list)
if(R.id in bradycardics)
if(R.id in GLOB.bradycardics)
if(temp <= PULSE_THREADY && temp >= PULSE_NORM)
temp--
if(R.id in tachycardics)
if(R.id in GLOB.tachycardics)
if(temp <= PULSE_FAST && temp >= PULSE_NONE)
temp++
if(R.id in heartstopper) //To avoid using fakedeath
if(R.id in GLOB.heartstopper) //To avoid using fakedeath
temp = PULSE_NONE
if(R.id in cheartstopper) //Conditional heart-stoppage
if(R.id in GLOB.cheartstopper) //Conditional heart-stoppage
if(R.volume >= R.overdose)
temp = PULSE_NONE

View File

@@ -470,6 +470,7 @@
return result
///Use this proc to get the damage in which the mob will be put into critical condition (hardcrit)
///Will return a NEGATIVE value. Ex: MaxHealth of 100 returns -50
/mob/living/proc/get_crit_point()
return -(getMaxHealth()*0.5)

View File

@@ -9,7 +9,7 @@
user.visible_message(span_notice("[user] starts inspecting [affecting]'s [E.name] carefully."))
if(!do_after(user, 1 SECOND, H))
to_chat(user, span_notice("You must stand still to inspect [E] for wounds."))
else if(E.wounds.len)
else if(LAZYLEN(E.wounds))
to_chat(user, span_warning("You find [E.get_wounds_desc()]"))
else
to_chat(user, span_notice("You find no visible wounds."))
@@ -17,6 +17,8 @@
to_chat(user, span_notice("Checking bones now..."))
if(!do_after(user, 2 SECONDS, H))
to_chat(user, span_notice("You must stand still to feel [E] for fractures."))
if(E.nonsolid && E.cannot_break) //boneless!
to_chat(user, span_warning("You are unable to feel any bones in the [E.name]!"))
else if(E.status & ORGAN_BROKEN)
to_chat(user, span_warning("The [E.encased ? E.encased : "bone in the [E.name]"] moves slightly when you poke it!"))
H.custom_pain("Your [E.name] hurts where it's poked.", 40)
@@ -37,9 +39,81 @@
if(E.status & ORGAN_DEAD)
to_chat(user, span_warning("[E] is decaying!"))
bad = 1
if(E.status & ORGAN_DEAD) //this is also infection level 3
to_chat(user, span_bolddanger("[H]'s [E.name] is gangreous and completely dead!"))
bad = 1
else if(E.germ_level > INFECTION_LEVEL_ONE)
if(E.germ_level > INFECTION_LEVEL_TWO)
to_chat(user, span_danger("[H]'s [E.name] shows signs of a severe infection!"))
bad = 1
else
to_chat(user, span_warning("[H] shows signs of infection in the [E.name]."))
bad = 1
if(LAZYLEN(E.wounds))
for(var/datum/wound/W in E.wounds)
if(W.internal)
to_chat(user, span_danger("You find a large, swelling hematoma in the skin")) //INTERNAL BLEEDING, BE VERY AFRAID.
break
if(!bad)
to_chat(user, span_notice("[H]'s skin is normal."))
var/body_part = parse_zone(target_zone)
if(body_part == BP_GROIN || body_part == BP_TORSO || body_part == BP_HEAD)
to_chat(user, span_notice("Checking for internal injury now..."))
if(!do_after(user, 5 SECONDS, H))
to_chat(user, span_notice("You must stand still to check [H]'s [E.name] for internal injury."))
else
///If we have a bad organ down here. Very non-specific. Doctor should ask how badly it hurt.
var/bad_organs = 0
///If we have appendicitis or not.
var/appendicitis = FALSE
switch(body_part)
if(BP_GROIN)
var/obj/item/organ/internal/intestine/intestine = H.internal_organs_by_name[O_INTESTINE]
var/obj/item/organ/internal/stomach/stomach = H.internal_organs_by_name[O_STOMACH]
var/obj/item/organ/internal/kidneys/kidneys = H.internal_organs_by_name[O_KIDNEYS]
var/obj/item/organ/internal/liver/liver = H.internal_organs_by_name[O_LIVER]
var/obj/item/organ/internal/spleen/spleen = H.internal_organs_by_name[O_SPLEEN]
var/obj/item/organ/internal/appendix/appendix = H.internal_organs_by_name[O_APPENDIX]
if(intestine && intestine.is_bruised())
bad_organs++
if(stomach && stomach.is_bruised())
bad_organs++
if(kidneys && kidneys.is_bruised())
bad_organs++
if(liver && liver.is_bruised())
bad_organs++
if(spleen && spleen.is_bruised())
bad_organs++
if(appendix && (appendix.is_bruised() || appendix.inflamed))
bad_organs++
appendicitis = TRUE
if(BP_TORSO)
var/obj/item/organ/internal/lungs/lungs = H.internal_organs_by_name[O_LUNGS]
var/obj/item/organ/internal/heart/heart = H.internal_organs_by_name[O_HEART]
if(lungs && lungs.is_bruised())
bad_organs++
if(heart && heart.is_bruised())
bad_organs++
if(BP_HEAD)
var/obj/item/organ/internal/voicebox/voicebox = H.internal_organs_by_name[O_VOICE]
if(voicebox && voicebox.is_bruised())
bad_organs++
if(bad_organs)
to_chat(user, span_warning("[H]'s [E.name] appears to be tender when you press on it, indicating an internal injury."))
H.custom_pain("Your [E.name] hurts where it's poked.", bad_organs*20)
if(appendicitis)
var/pain_check = (H.stat && (H.can_feel_pain() || H.synth_cosmetic_pain) && H.chem_effects[CE_PAINKILLER] < 60)
if(pain_check) //They can feel pain.
to_chat(user, span_danger("[H] jolts when you let go of their [E.name], indicating appendicitis!"))
H.custom_pain("You feel pure agony as [src] pushes down on your [E.name]!", 200)
/obj/item/grab/proc/jointlock(mob/living/carbon/human/target, mob/attacker, var/target_zone)
if(state < GRAB_AGGRESSIVE)
to_chat(attacker, span_warning("You require a better grab to do this."))

View File

@@ -120,7 +120,7 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain)
brainmob.add_modifier(M.type)
if(H.mind)
H.mind.transfer_to(brainmob)
H.mind.transfer_to(brainmob) //mAYBE MAKE THIS FORCE....
brainmob.languages = H.languages
@@ -146,7 +146,7 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain)
var/obj/item/organ/internal/brain/B = src
if(istype(B) && owner)
if(istype(owner, /mob/living/carbon) && owner.ckey)
if(istype(owner, /mob/living/carbon) && (owner.ckey || owner.original_player))
B.transfer_identity(owner)
..()
@@ -159,8 +159,10 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain)
if(brainmob)
if(brainmob.mind)
brainmob.mind.transfer_to(target)
target.languages = brainmob.languages
else
target.key = brainmob.key
target.languages = brainmob.languages
..()
/obj/item/organ/internal/brain/proc/get_control_efficiency()

View File

@@ -9,8 +9,6 @@
var/acidtype = REAGENT_ID_STOMACID // Incase you want some stomach organ with, say, polyacid instead, or sulphuric.
var/max_acid_volume = 30
var/deadly_hold = TRUE // Does the stomach do damage to mobs eaten by its owner? Xenos should probably have this FALSE.
/obj/item/organ/internal/stomach/Initialize(mapload)
. = ..()
if(reagents)

View File

@@ -212,12 +212,20 @@ var/list/organ_cache = list()
/// Infection damage
//If the organ is dead, for the sake of organs that may have died due to non-infection, we'll only do damage if they have at least L1 infection (built up below)
if((status & ORGAN_DEAD) && antibiotics < ANTIBIO_OD && germ_level >= INFECTION_LEVEL_ONE)
infection_damage = max(1, 1 + round((germ_level - INFECTION_LEVEL_THREE)/200,0.25)) //1 Tox plus a little based on germ level
//If the organ is dead, for the sake of organs that may have died due to non-infection, we'll only do damage if they have at least L2 infection (built up below)
//A dead organ is bad, so you start getting flooded with toxins faster.
if((status & ORGAN_DEAD) && antibiotics < ANTIBIO_OD && germ_level >= INFECTION_LEVEL_TWO)
infection_damage = CLAMP(round((germ_level - INFECTION_LEVEL_TWO)/1000), 0.25, 1) //Between 0.25 to 1 tox per tick.
//Ideally, we want them to either: A. Reach Medical or B. have their organ die. Dying to toxins is lame.
//With this math: Toxins goes up by 0.001 per 2 seconds, up to 0.1. This means 200 seconds to reach 0.1 toxins per tick (germ level is now 700).
//Limb death happens at germ level 1000. This means another 600 seconds to reach there if untreated.
//Your kidneys helps purge toxins if you have 10% or less of your maxhealth in toxins damage. This is RNG though. (See kidneys/handle_organ_proc_special)
//So you COULD get really lucky and keep healing your toxins away until your limb dies, or you could get unlucky die to toxins first.
//Nonetheless, this should give a much more reasonable window for treatment.
else if(germ_level > INFECTION_LEVEL_TWO && antibiotics < ANTIBIO_OD)
infection_damage = max(0.25, 0.25 + round((germ_level - INFECTION_LEVEL_TWO)/200,0.25))
infection_damage = CLAMP(round((germ_level - INFECTION_LEVEL_TWO)/1000), 0, 0.1)
if(infection_damage)
owner.adjustToxLoss(infection_damage)

View File

@@ -82,6 +82,7 @@
var/cavity = 0
var/burn_stage = 0 //Surgical repair stage for burn.
var/brute_stage = 0 //Surgical repair stage for brute.
var/remove_necrosis = 0 //Surgical stage for necrosis removal.
// HUD element variable, see organ_icon.dm get_damage_hud_image()
var/image/hud_damage_image

View File

@@ -284,7 +284,7 @@
var/mob/living/carbon/human/H = target
var/target_zone = ran_zone(check_zone(user.zone_sel.selecting, target))
var/target_zone = get_zone_with_miss_chance(check_zone(user.zone_sel.selecting, target))
var/obj/item/organ/external/affecting = H.get_organ(target_zone)
if (!affecting || affecting.is_stump())
@@ -296,7 +296,8 @@
if((user != target) && H.check_shields(7, src, user, "\the [src]"))
return
if (target != user && H.getarmor(target_zone, "melee") > 5 && prob(50))
var/armor_val = H.getarmor(target_zone, "melee")
if(target != user && armor_val >= 5 && prob(50+armor_val)) // High armor can deflect syringe stabs
for(var/mob/O in viewers(world.view, user))
O.show_message(span_bolddanger("[user] tries to stab [target] in \the [hit_area] with [src.name], but the attack is deflected by armor!"), 1)
user.remove_from_mob(src)

View File

@@ -1342,7 +1342,7 @@
/datum/reagent/sterilizine
name = REAGENT_STERILIZINE
id = REAGENT_ID_STERILIZINE
description = "Sterilizes wounds in preparation for surgery and thoroughly removes blood."
description = "Sterilizes wounds in preparation for surgery and thoroughly removes blood. Can additionally be used to prepare a surface for surgery to lower risk of infection."
taste_description = "bitterness"
reagent_state = LIQUID
color = "#C8A5DC"
@@ -1367,12 +1367,12 @@
/datum/reagent/sterilizine/touch_obj(var/obj/O)
..()
O.germ_level -= min(volume*20, O.germ_level)
O.germ_level -= min(volume*200, O.germ_level)
O.was_bloodied = null
/datum/reagent/sterilizine/touch_turf(var/turf/T)
..()
T.germ_level -= min(volume*20, T.germ_level)
T.germ_level -= min(volume*200, T.germ_level)
for(var/obj/item/I in T.contents)
I.was_bloodied = null
for(var/obj/effect/decal/cleanable/blood/B in T)

View File

@@ -157,7 +157,7 @@
/obj/item/surgical/bonegel = 100
)
allowed_procs = list(IS_SCREWDRIVER = 75)
allowed_procs = list(IS_SCREWDRIVER = 90) //this is what we actually use irl!
can_infect = 1
blood_level = 1
@@ -216,7 +216,7 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if(coverage_check(user, target, affected, tool))
return 0
return affected && (affected.robotic < ORGAN_ROBOT) && affected.open >= 2 && affected.stage == 0
return affected && (affected.status & ORGAN_BROKEN) && (affected.robotic < ORGAN_ROBOT) && affected.open >= 2 && affected.stage == 0
/datum/surgery_step/clamp_bone/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)

View File

@@ -28,8 +28,10 @@
/obj/item/material/knife/machete/hatchet = 75
)
min_duration = 50 //CHOMPedit
max_duration = 50 //CHOMPedit
allowed_procs = list(IS_CROWBAR = 50)
min_duration = 50
max_duration = 50 //CHOMPEdit
/datum/surgery_step/open_encased/saw/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if(!ishuman(target))

View File

@@ -2,7 +2,7 @@
//////////////////////////////////////////////////////////////////
// LIMB REPAIR SURGERY //
//////////////////////////////////////////////////////////////////
/datum/surgery_step/repairflesh/
/datum/surgery_step/repairflesh
surgery_name = "Repair Flesh"
priority = 1
can_infect = 1
@@ -10,10 +10,6 @@
req_open = 1
/datum/surgery_step/repairflesh/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
/* VOREStation Removal for Mlem Reasons(TM)
if (target.stat == DEAD) // Sorry defibs, your subjects need to have pumping fluids for these to work.
return 0
*/
if (isslime(target))
return 0
if (target_zone == O_EYES || target_zone == O_MOUTH)
@@ -40,7 +36,7 @@
surgery_name = "Scan Injury"
allowed_tools = list(
/obj/item/autopsy_scanner = 100,
/obj/item/analyzer = 10
/obj/item/analyzer = 25
)
priority = 2
@@ -84,7 +80,6 @@
user.visible_message(span_warning("[user]'s hand slips, dropping \the [tool] onto [target]'s [affected]!") , \
span_warning("Your hand slips, dropping \the [tool] onto [target]'s [affected]!") )
user.balloon_alert_visible("slips, dropping \the [tool].", "your hand slips, dropping \the [tool] onto \the [affected].")
affected.createwound(BRUISE, 10)
//////////////////////////////////////////////////////////////////
// BURN STEP //
@@ -149,8 +144,7 @@
user.visible_message(span_danger("[user]'s hand slips, tearing up [target]'s [affected] with \the [tool]."), \
span_danger("Your hand slips, tearing up [target]'s [affected] with \the [tool]."))
user.balloon_alert_visible("slips, tearing up \the [affected]", "you slip, tearing up \the [affected]")
affected.createwound(BRUISE, 10)
affected.createwound(CUT, 5)
affected.createwound(BRUISE, 5)
if(istype(tool, /obj/item/stack) && prob(30))
var/obj/item/stack/T = tool
T.use(1)
@@ -219,8 +213,7 @@
user.visible_message(span_danger("[user]'s hand slips, tearing up [target]'s [affected] with \the [tool]."), \
span_danger("Your hand slips, tearing up [target]'s [affected] with \the [tool]."))
user.balloon_alert_visible("slips, tearing up \the [affected]", "your hand slips, tearing up \the [affected]")
affected.createwound(BRUISE, 10)
affected.createwound(CUT, 5)
affected.createwound(BRUISE, 5)
if(istype(tool, /obj/item/stack) && prob(30))
var/obj/item/stack/T = tool
T.use(1)

View File

@@ -54,7 +54,7 @@
user.visible_message(span_danger("[user]'s hand slips, slicing [target]'s throat with \the [tool]!") , \
span_danger("Your hand slips, slicing [target]'s throat wth \the [tool]!") )
user.balloon_alert_visible("slips, slicing [target]'s throat.", "your hand slips, slicing [target]'s throat.")
affected.createwound(CUT, 60)
affected.createwound(CUT, 10)
target.AdjustLosebreath(10)
///////////////////////////////////////////////////////////////
@@ -66,7 +66,7 @@
allowed_tools = list(
/obj/item/surgical/hemostat = 100, \
/obj/item/stack/cable_coil = 75, \
/obj/item/assembly/mousetrap = 10 //I don't know. Don't ask me. But I'm leaving it because hilarity.
/obj/item/assembly/mousetrap = 25 //I don't know. Don't ask me. But I'm leaving it because hilarity.
)
min_duration = 50 //CHOMPedit
@@ -129,7 +129,7 @@
user.visible_message(span_danger("[user]'s hand slips, tearing skin on [target]'s face with \the [tool]!"), \
span_danger("Your hand slips, tearing skin on [target]'s face with \the [tool]!"))
user.balloon_alert_visible("slips, tearing skin on [target]'s face.", "your hand slips, tearing skin on the face.")
target.apply_damage(10, BRUTE, affected, sharp = TRUE, sharp = TRUE)
target.apply_damage(10, BRUTE, affected, sharp = TRUE)
///////////////////////////////////////////////////////////////
// Face Cauterizing Surgery
@@ -139,6 +139,7 @@
surgery_name = "Cauterize Face"
allowed_tools = list(
/obj/item/surgical/cautery = 100, \
/obj/item/clothing/mask/smokable/cigarette/cigar = 90, \
/obj/item/clothing/mask/smokable/cigarette = 75, \
/obj/item/flame/lighter = 50, \
/obj/item/weldingtool = 25

View File

@@ -82,7 +82,7 @@
/obj/item/surgical/scalpel/laser3 = 100, \
/obj/item/surgical/scalpel/laser2 = 100, \
/obj/item/surgical/scalpel/laser1 = 100, \
/obj/item/melee/energy/sword = 5
/obj/item/melee/energy/sword = 75
)
priority = 2
req_open = 0
@@ -131,7 +131,7 @@
span_danger("Your hand slips as the blade sputters, searing a long gash in [target]'s [affected.name] with \the [tool]!"))
user.balloon_alert_visible("slips, searing a long gash on \the [affected.name]", "your hand slips, searing a long gash on [affected.name].")
affected.createwound(CUT, 7.5)
affected.createwound(BURN, 12.5)
affected.createwound(BURN, 7.5)
///////////////////////////////////////////////////////////////
// Incision Management Surgery
@@ -192,8 +192,9 @@
surgery_name = "Clamp Bleeders"
allowed_tools = list(
/obj/item/surgical/hemostat = 100, \
/obj/item/material/twohanded/fireaxe = 99, \
/obj/item/stack/cable_coil = 75, \
/obj/item/assembly/mousetrap = 20
/obj/item/assembly/mousetrap = 25
)
min_duration = 30 //CHOMPedit

View File

@@ -190,7 +190,7 @@
surgery_name = "Remove Implant"
allowed_tools = list(
/obj/item/surgical/hemostat = 100, \
/obj/item/material/kitchen/utensil/fork = 20
/obj/item/material/kitchen/utensil/fork = 50
)
allowed_procs = list(IS_WIRECUTTER = 75)
@@ -264,7 +264,7 @@
worm.detatch()
worm.leave_host()
else
obj.loc = get_turf(target)
obj.forceMove(get_turf(target))
obj.add_blood(target)
obj.update_icon()
if(istype(obj,/obj/item/implant))
@@ -282,11 +282,13 @@
/datum/surgery_step/cavity/implant_removal/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
..()
var/obj/item/organ/external/chest/affected = target.get_organ(target_zone)
if (affected.implants.len)
if(LAZYLEN(affected.implants))
var/fail_prob = 10
fail_prob += 100 - tool_quality(tool)
if(prob(fail_prob))
var/obj/item/implant/imp = affected.implants[1]
if(!istype(imp))
return
user.visible_message(span_danger(" Something beeps inside [target]'s [affected.name]!"))
playsound(imp, 'sound/items/countdown.ogg', 75, 1, -3)
spawn(25)

View File

@@ -94,7 +94,7 @@
allowed_tools = list(
/obj/item/surgical/hemostat = 100, \
/obj/item/stack/cable_coil = 75, \
/obj/item/assembly/mousetrap = 20
/obj/item/assembly/mousetrap = 25
)
can_infect = 1

View File

@@ -28,8 +28,8 @@
priority = 1
allowed_tools = list(
/obj/item/surgical/FixOVein = 100,
/obj/item/stack/cable_coil = 40,
/obj/item/assembly/mousetrap = 5)
/obj/item/stack/cable_coil = 50,
/obj/item/assembly/mousetrap = 25)
min_duration = 80
max_duration = 100
@@ -66,8 +66,8 @@
priority = 3 //Do this instead of expanding the skull cavity
allowed_tools = list(
/obj/item/surgical/surgicaldrill = 100,
/obj/item/melee/changeling/arm_blade = 15,
/obj/item/pickaxe = 5
/obj/item/melee/changeling/arm_blade = 90,
/obj/item/pickaxe = 15
)
allowed_procs = list(IS_SCREWDRIVER = 75)
@@ -113,7 +113,7 @@
priority = 3 //Do this instead of picking around for implants.
allowed_tools = list(
/obj/item/surgical/hemostat = 100,
/obj/item/melee/changeling/claw = 40) //Surprisingly, claws are kind of okay at picking things out.
/obj/item/melee/changeling/claw = 90) //Surprisingly, claws are kind of okay at picking things out.
allowed_procs = list(IS_WIRECUTTER = 60)
@@ -156,9 +156,9 @@
priority = 1 //Do this after IB.
allowed_tools = list(
/obj/item/surgical/FixOVein = 100,
/obj/item/stack/nanopaste = 50,
/obj/item/stack/cable_coil = 40,
/obj/item/assembly/mousetrap = 5)
/obj/item/stack/nanopaste = 99,
/obj/item/stack/cable_coil = 75,
/obj/item/assembly/mousetrap = 25)
min_duration = 100
max_duration = 100 //CHOMPedit
@@ -200,8 +200,8 @@
priority = 3 //Do this instead of fixing bones.
allowed_tools = list(
/obj/item/surgical/bonegel = 100,
/obj/item/stack/nanopaste = 50,
/obj/item/tape_roll = 5)
/obj/item/stack/nanopaste = 99,
/obj/item/tape_roll = 50)
min_duration = 100
max_duration = 100 //CHOMPedit
@@ -242,7 +242,7 @@
priority = 3 //Do this instead of searching for objects in the skull.
allowed_tools = list(
/obj/item/surgical/hemostat = 100,
/obj/item/melee/changeling/claw = 20) //Claws. Good for digging, not so much for moving.
/obj/item/melee/changeling/claw = 99) //Technically this step isn't even NEEDED.
allowed_procs = list(IS_WIRECUTTER = 60)

View File

@@ -171,8 +171,6 @@
priority = 3
blood_level = 3
min_duration = 40 //CHOMPedit
max_duration = 40 //CHOMPedit
excludes_steps = list(/datum/surgery_step/generic/cut_open)

View File

@@ -97,9 +97,9 @@
return
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(span_warning("[user]'s hand slips, getting mess and tearing the inside of [target]'s [affected.name] with \the [tool]!"), \
span_warning("Your hand slips, getting mess and tearing the inside of [target]'s [affected.name] with \the [tool]!"))
user.balloon_alert_visible("slips, gettng mess and tearing the inside of [target]'s [affected.name]", "your hand slips, getting mess and tearng the [affected.name]'s insides")
user.visible_message(span_warning("[user]'s hand slips, getting messy and tearing the inside of [target]'s [affected.name] with \the [tool]!"), \
span_warning("Your hand slips, getting messy and tearing the inside of [target]'s [affected.name] with \the [tool]!"))
user.balloon_alert_visible("slips, getting messy and tearing the inside of [target]'s [affected.name]", "your hand slips, getting mess and tearing the [affected.name]'s insides")
var/dam_amt = 2
if (istype(tool, /obj/item/stack/medical/advanced/bruise_pack))
@@ -273,7 +273,7 @@
allowed_tools = list(
/obj/item/surgical/hemostat = 100, \
/obj/item/material/kitchen/utensil/fork = 20
/obj/item/material/kitchen/utensil/fork = 50
)
allowed_procs = list(IS_WIRECUTTER = 100) //FBP code also uses this, so let's be nice. Roboticists won't know to use hemostats.

View File

@@ -61,25 +61,27 @@
user.balloon_alert_visible("slips, smearing [tool] in the incision in [target]'s [affected.name]", "your hand slips, smearing [tool] in the incisiom in [affected.name]")
affected.take_damage(5, 0)
///Has multiple stages. At or past stage 1, peridaxon can immediately treat it.
///0 = Not started
///1 = Dead tissue removed (Can use bioregen)
///2 = Flesh Rejuvenated (Can use hemostat)
///3 = Flesh Rearranged (Can use bioregen)
///////////////////////////////////////////////////////////////
// Necrosis Surgery Step 1
///////////////////////////////////////////////////////////////
/datum/surgery_step/fix_dead_tissue //Debridement
surgery_name = "Remove Dead Tissue"
priority = 2
allowed_tools = list(
/obj/item/surgical/scalpel = 100, \
/obj/item/material/knife = 75, \
/obj/item/material/shard = 50, \
)
can_infect = 1
blood_level = 1
/datum/surgery_step/necrotic
surgery_name = "Dehusk"
priority = 1
can_infect = 0 //It's already fully infected.
blood_level = 0 //Already gone.
min_duration = 50 //CHOMPedit
max_duration = 50 //CHOMPedit
/datum/surgery_step/fix_dead_tissue/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
/datum/surgery_step/necrotic/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if(!ishuman(target))
return 0
@@ -92,7 +94,22 @@
return affected && affected.open >= 2 && (affected.status & ORGAN_DEAD)
/datum/surgery_step/fix_dead_tissue/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
/datum/surgery_step/necrotic/fix_dead_tissue //Debridement
surgery_name = "Remove Dead Tissue"
allowed_tools = list(
/obj/item/surgical/scalpel = 100, \
/obj/item/material/knife = 75, \
/obj/item/material/shard = 50, \
)
min_duration = 110
max_duration = 160
/datum/surgery_step/necrotic/fix_dead_tissue/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
return affected && affected.open >= 1 && (affected.status & ORGAN_DEAD)
/datum/surgery_step/necrotic/fix_dead_tissue/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(span_filter_notice("[user] starts cutting away necrotic tissue in [target]'s [affected.name] with \the [tool].") , \
span_filter_notice("You start cutting away necrotic tissue in [target]'s [affected.name] with \the [tool]."))
@@ -100,14 +117,15 @@
target.custom_pain("The pain in [affected.name] is unbearable!", 100)
..()
/datum/surgery_step/fix_dead_tissue/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
/datum/surgery_step/necrotic/fix_dead_tissue/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(span_notice("[user] has cut away necrotic tissue in [target]'s [affected.name] with \the [tool]."), \
span_notice("You have cut away necrotic tissue in [target]'s [affected.name] with \the [tool]."))
user.balloon_alert_visible("cuts away necrotic tissue in [target]'s [affected.name]", "cut away necrotic tissue in \the [affected.name]")
affected.open = 3
affected.remove_necrosis = 1
/datum/surgery_step/fix_dead_tissue/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
/datum/surgery_step/necrotic/fix_dead_tissue/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(span_danger("[user]'s hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!"), \
span_danger("Your hand slips, slicing an artery inside [target]'s [affected.name] with \the [tool]!"))
@@ -117,7 +135,7 @@
///////////////////////////////////////////////////////////////
// Necrosis Surgery Step 2
///////////////////////////////////////////////////////////////
/datum/surgery_step/treat_necrosis
/datum/surgery_step/necrotic/treat_necrosis
surgery_name = "Treat Necrosis"
priority = 2
allowed_tools = list(
@@ -134,26 +152,11 @@
min_duration = 40 //CHOMPedit
max_duration = 40 //CHOMPedit
/datum/surgery_step/treat_necrosis/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if (!istype(tool, /obj/item/reagent_containers))
return 0
var/obj/item/reagent_containers/container = tool
if(!container.reagents.has_reagent(REAGENT_ID_PERIDAXON))
return 0
if(!ishuman(target))
return 0
if (target_zone == O_MOUTH || target_zone == O_EYES)
return 0
/datum/surgery_step/necrotic/treat_necrosis/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if(coverage_check(user, target, affected, tool))
return 0
return affected && affected.open == 3 && (affected.status & ORGAN_DEAD)
return ..() && affected.open >= 3 && affected.remove_necrosis >= 1
/datum/surgery_step/treat_necrosis/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
/datum/surgery_step/necrotic/treat_necrosis/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(span_filter_notice("[user] starts applying medication to the affected tissue in [target]'s [affected.name] with \the [tool].") , \
span_filter_notice("You start applying medication to the affected tissue in [target]'s [affected.name] with \the [tool]."))
@@ -161,7 +164,7 @@
target.custom_pain("Something in your [affected.name] is causing you a lot of pain!", 50)
..()
/datum/surgery_step/treat_necrosis/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
/datum/surgery_step/necrotic/treat_necrosis/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if (!istype(tool, /obj/item/reagent_containers))
@@ -171,14 +174,16 @@
var/trans = container.reagents.trans_to_mob(target, container.amount_per_transfer_from_this, CHEM_BLOOD) //technically it's contact, but the reagents are being applied to internal tissue
if (trans > 0)
affected.germ_level = 0 //CURE THE INFECTION
affected.status &= ~ORGAN_DEAD
affected.owner.update_icons_body()
user.visible_message(span_notice("[user] applies [trans] units of the solution to affected tissue in [target]'s [affected.name]."), \
span_notice("You apply [trans] units of the solution to affected tissue in [target]'s [affected.name] with \the [tool]."))
user.balloon_alert_visible("applies [trans] units of the solution to affected tissue in [target]'s [affected.name]", "applied [trans] units of the solution to afected tissue in [affected.name]")
affected.remove_necrosis = 0
/datum/surgery_step/treat_necrosis/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
/datum/surgery_step/necrotic/treat_necrosis/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if (!istype(tool, /obj/item/reagent_containers))
@@ -195,6 +200,129 @@
//no damage or anything, just wastes medicine
///////////////////////////////////////////////////////////////
// Necrosis Surgery Alternative Step 2
///////////////////////////////////////////////////////////////
/datum/surgery_step/necrotic/rejuvenate_dead_tissue
surgery_name = "Rejuvenate Dead Tissue"
allowed_tools = list(/obj/item/surgical/bioregen = 100)
min_duration = 110
max_duration = 160
/datum/surgery_step/necrotic/rejuvenate_dead_tissue/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
return ..() && affected.open >= 3 && affected.remove_necrosis == 1
/datum/surgery_step/necrotic/rejuvenate_dead_tissue/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(span_filter_notice("[user] starts rejuvenating necrotic tissue in [target]'s [affected.name] with \the [tool].") , \
span_filter_notice("You start rejuvenating necrotic tissue in [target]'s [affected.name] with \the [tool]."))
user.balloon_alert_visible("starts rejuvenating necrotic tissue in [target]'s [affected.name]", "rejuvenating necrotic tissue in \the [affected.name]")
target.custom_pain("The pain in [affected.name] is unbearable!", 100)
..()
/datum/surgery_step/necrotic/rejuvenate_dead_tissue/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(span_notice("[user] has rejuvenated necrotic tissue in [target]'s [affected.name] with \the [tool]."), \
span_notice("You have rejuvenated necrotic tissue in [target]'s [affected.name] with \the [tool]."))
user.balloon_alert_visible("rejuvenated necrotic tissue in [target]'s [affected.name]", "rejuvenated necrotic tissue in \the [affected.name]")
affected.open = 3
affected.remove_necrosis = 2
/datum/surgery_step/necrotic/rejuvenate_dead_tissue/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(span_danger("[user]'s hand slips, bruising the muscle inside of [target]'s [affected.name] with \the [tool]!"), \
span_danger("Your hand slips, bruising the muscle inside of [target]'s [affected.name] with \the [tool]!"))
user.balloon_alert_visible("slips, bruising the muscle inside of [target]'s [affected.name]", "your hand slips, bruising the muscle inside of \the [affected.name]")
affected.createwound(BRUISE, 20, 1)
///////////////////////////////////////////////////////////////
// Necrosis Surgery Step 3
///////////////////////////////////////////////////////////////
/datum/surgery_step/necrotic/rearrange_dead_tissue
surgery_name = "Rearrange Tissue"
allowed_tools = list(
/obj/item/surgical/hemostat = 100, \
/obj/item/stack/cable_coil = 75, \
/obj/item/assembly/mousetrap = 20
)
min_duration = 110
max_duration = 160
/datum/surgery_step/necrotic/rearrange_dead_tissue/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
return ..() && affected.open >= 3 && affected.remove_necrosis == 2
/datum/surgery_step/necrotic/rearrange_dead_tissue/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(span_filter_notice("[user] starts rearranging rejuvinated tissue in [target]'s [affected.name] with \the [tool].") , \
span_filter_notice("You start rearranging rejuvinated tissue in [target]'s [affected.name] with \the [tool]."))
user.balloon_alert_visible("starts rearranging rejuvinated tissue in [target]'s [affected.name]", "rejuvinated tissue in \the [affected.name]")
target.custom_pain("The pain in [affected.name] is unbearable!", 100)
..()
/datum/surgery_step/necrotic/rearrange_dead_tissue/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(span_notice("[user] has rearranging rejuvinated tissue in [target]'s [affected.name] with \the [tool]."), \
span_notice("You have rearranging rejuvinated tissue in [target]'s [affected.name] with \the [tool]."))
user.balloon_alert_visible("rearranging rejuvinated tissue in [target]'s [affected.name]", "rearranging rejuvinated tissue in \the [affected.name]")
affected.open = 3
affected.remove_necrosis = 3
/datum/surgery_step/necrotic/rearrange_dead_tissue/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(span_danger("[user]'s hand slips, slicing the fresh tissue on [target]'s [affected.name] with \the [tool]!"), \
span_danger("Your hand slips, slicing the fresh tissue on [target]'s [affected.name] with \the [tool]!"))
user.balloon_alert_visible("slips, slicing the fresh tissue on [target]'s [affected.name]", "your hand slips, slicing the fresh tissue on \the [affected.name]")
affected.createwound(CUT, 10, 1)
///////////////////////////////////////////////////////////////
// Necrosis Surgery Step 4
///////////////////////////////////////////////////////////////
/datum/surgery_step/necrotic/fix_necrotic_vessel
surgery_name = "Reroute Blood Vessels"
allowed_tools = list(
/obj/item/surgical/bioregen = 100, \
/obj/item/surgical/FixOVein = 100, \
/obj/item/stack/cable_coil = 75
)
min_duration = 110
max_duration = 160
/datum/surgery_step/necrotic/fix_necrotic_vessel/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
return ..() && affected.open >= 3 && affected.remove_necrosis == 3
/datum/surgery_step/necrotic/fix_necrotic_vessel/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(span_filter_notice("[user] starts rerouting the vessels in [target]'s [affected.name] with \the [tool].") , \
span_filter_notice("You start rerouting the vessels in [target]'s [affected.name] with \the [tool]."))
user.balloon_alert_visible("starts rerouting the vessels in [target]'s [affected.name]", "rerouting vessels in \the [affected.name]")
target.custom_pain("The pain in [affected.name] is unbearable!", 100)
..()
/datum/surgery_step/necrotic/fix_necrotic_vessel/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(span_notice("[user] has rerouted the vessels in [target]'s [affected.name] with \the [tool]."), \
span_notice("You have rerouted the vessels in [target]'s [affected.name] with \the [tool]."))
user.balloon_alert_visible("rerouted the vessels in [target]'s [affected.name]", "rerouted the vessels in \the [affected.name]")
//the actual heal stuffs
affected.germ_level = 0
affected.status &= ~ORGAN_DEAD
affected.owner.update_icons_body()
affected.remove_necrosis = 0
/datum/surgery_step/necrotic/fix_necrotic_vessel/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message(span_danger("[user]'s hand slips, slicing the fresh tissue on [target]'s [affected.name] with \the [tool]!"), \
span_danger("Your hand slips, slicing the fresh tissue on [target]'s [affected.name] with \the [tool]!"))
user.balloon_alert_visible("slips, slicing the fresh tissue on [target]'s [affected.name]", "your hand slips, slicing the fresh tissue on \the [affected.name]")
affected.createwound(CUT, 10, 1)
///////////////////////////////////////////////////////////////
// Hardsuit Removal Surgery
///////////////////////////////////////////////////////////////
@@ -202,9 +330,9 @@
/datum/surgery_step/hardsuit
surgery_name = "Remove Hardsuit"
allowed_tools = list(
/obj/item/pickaxe/plasmacutter = 100,
/obj/item/weldingtool = 80,
/obj/item/surgical/circular_saw = 60,
/obj/item/pickaxe/plasmacutter = 100
)
req_open = 0
@@ -254,10 +382,10 @@
// De-Husking Surgery //
/////////////////////////////////////////
/datum/surgery_status/
/datum/surgery_status
var/dehusk = 0
/datum/surgery_step/dehusk/
/datum/surgery_step/dehusk
surgery_name = "Dehusk"
priority = 1
can_infect = 0
@@ -276,7 +404,8 @@
/datum/surgery_step/dehusk/structinitial
surgery_name = "Create Structure"
allowed_tools = list(
/obj/item/surgical/bioregen = 100
/obj/item/surgical/bioregen = 100,
/obj/item/tape_roll = 25
)
min_duration = 60 //CHOMPedit
max_duration = 60 //CHOMPedit
@@ -346,7 +475,8 @@
surgery_name = "Finish Structure"
allowed_tools = list(
/obj/item/surgical/bioregen = 100, \
/obj/item/surgical/FixOVein = 30
/obj/item/surgical/FixOVein = 100, \
/obj/item/stack/cable_coil = 75
)
min_duration = 60 //CHOMPedit
max_duration = 60 //CHOMPedit
@@ -398,7 +528,7 @@
max_duration = 40 //CHOMPedit
/datum/surgery_step/internal/detoxify/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
return ..() && target_zone == BP_TORSO && (target.toxloss > 25 || target.oxyloss > 25)
return ..() && target_zone == BP_TORSO && (target.toxloss || target.oxyloss)
/datum/surgery_step/internal/detoxify/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message(span_notice("[user] begins to pull toxins from, and restore oxygen to [target]'s musculature and organs with \the [tool]."), \
@@ -410,9 +540,7 @@
user.visible_message(span_notice("[user] finishes pulling toxins from, and restoring oxygen to [target]'s musculature and organs with \the [tool]."), \
span_notice("You finish pulling toxins from, and restoring oxygen to [target]'s musculature and organs with \the [tool]."))
user.balloon_alert_visible("finishes pulling toxins and restoring oxygen to [target]'s organs", "pulled toxins from and restored oxygen to the organs")
if(target.toxloss>25)
target.adjustToxLoss(-20)
if(target.oxyloss>25)
target.adjustOxyLoss(-20)
..()

View File

@@ -64,6 +64,8 @@
/datum/surgery_step/robotics/unscrew_hatch/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if(istype(tool, /obj/item/coin))
user.drop_item()
user.visible_message(span_warning("[user]'s [tool.name] slips, failing to unscrew [target]'s [affected.name]."), \
span_warning("Your [tool] slips, failing to unscrew [target]'s [affected.name]."))
user.balloon_alert_visible("slips, failing to unscrew [target]'s [affected.name]", "your [tool] slips, failing to unscrew \the [affected.name]")

View File

@@ -1,7 +1,8 @@
/* SURGERY STEPS */
/obj/
var/surgery_odds = 0 // Used for tables/etc which can have surgery done of them.
///How clean an object is for surgery purposes. Cleaner = less chance of infection.
var/surgery_cleanliness = 0 // Used for tables/etc which can have surgery done of them.
/datum/surgery_step
var/priority = 0 //steps with higher priority would be attempted first
@@ -135,19 +136,21 @@
/obj/item/proc/do_surgery(mob/living/carbon/M, mob/living/user)
if(!can_do_surgery(M, user))
return 0
return FALSE
if(!istype(M))
return 0
return FALSE
if (user.a_intent == I_HURT) //check for Hippocratic Oath
//Insert intentional hurt medical code here.
return 0
return FALSE
var/zone = user.zone_sel.selecting
if(zone in M.op_stage.in_progress) //Can't operate on someone repeatedly.
to_chat(user, span_warning("You can't operate on this area while surgery is already in progress."))
return 1
var/obj/surface = M.get_surgery_surface(user)
if(!surface || !surface.surgery_odds) // If the surface has a chance of 0% surgery odds (ground), don't even bother trying to do surgery.
return 0 // This is meant to prevent the 'glass shard mouth 60 damage click' exploit. Also saves CPU by doing it here!
return TRUE
///How 'clean' the surace we're doing surgery on is.
///100 = fully clean, 0 = filthy
var/cleanliness = M.get_surgery_cleanliness(user)
if(isnull(cleanliness)) //They're standing upright.
return FALSE
var/list/datum/surgery_step/available_surgeries = list()
for(var/datum/surgery_step/S in GLOB.surgery_steps)
@@ -181,7 +184,7 @@
if(M == user) // Once we determine if we can actually do a step at all, give a slight delay to self-surgery to confirm attempts.
to_chat(user, span_critical("You focus on attempting to perform surgery upon yourself."))
if(!do_after(user, 3 SECONDS, target = M))
return 0
return FALSE
var/datum/surgery_step/selected_surgery
if(available_surgeries.len > 1) //More than one possible? Ask them which one.
@@ -190,16 +193,14 @@
selected_surgery = pick(available_surgeries)
if(isnull(selected_surgery)) //They clicked 'cancel'
return 1
selected_surgery = available_surgeries[selected_surgery] //Sets the name they selected to be the datum.
// VOREstation edit start
if(istype(selected_surgery,/datum/surgery_step/generic/amputate))
return TRUE
var/obj/item/organ/external/affected = M.get_organ(zone)
selected_surgery = available_surgeries[selected_surgery] //Sets the name they selected to be the datum.
if(istype(selected_surgery,/datum/surgery_step/generic/amputate))
to_chat(user, span_danger("You are preparing to amputate \the [M]'s [affected.name]!"))
if(!do_after(user, 3 SECONDS, target = M))
to_chat(user, span_warning("You reconsider performing an amputation..."))
return 0
// VOREstation edit end
return FALSE
M.op_stage.in_progress += zone
selected_surgery.begin_step(user, M, zone, src) //start on it
var/success = TRUE
@@ -208,13 +209,10 @@
if(!prob(selected_surgery.tool_quality(src)))
success = FALSE
// Bad surface may mean failure as well.
if(!prob(surface.surgery_odds))
success = FALSE
// Not staying still fails you too.
if(success)
var/calc_duration = rand(selected_surgery.min_duration, selected_surgery.max_duration)
calc_duration *= CLAMP((100-cleanliness)/10 + 1, 1, 10)
if(!do_after(user, calc_duration * toolspeed, M, target_zone = zone, max_distance = reach))
success = FALSE
to_chat(user, span_warning("You must remain close to and keep focused on your patient to conduct surgery."))
@@ -222,6 +220,8 @@
if(success)
selected_surgery.end_step(user, M, zone, src)
if(prob(100-cleanliness)) //Infection chance based on cleanliness.
affected.adjust_germ_level(rand(10,20))
else
selected_surgery.fail_step(user, M, zone, src)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) //Gets rid of instakill mechanics.
@@ -230,7 +230,7 @@
if (ishuman(M))
var/mob/living/carbon/human/H = M
H.update_surgery()
return 1 //don't want to do weapony things after surgery
return TRUE //don't want to do weapony things after surgery
/proc/sort_surgeries()
var/gap = GLOB.surgery_steps.len

View File

@@ -9,7 +9,7 @@ var/list/table_icon_cache = list()
anchored = TRUE
layer = TABLE_LAYER
throwpass = 1
surgery_odds = 50 //VOREStation Edit
surgery_cleanliness = 50
var/flipped = 0
var/maxhealth = 10
var/health = 10