Merge branch 'master' into ghetto-saw

This commit is contained in:
moo
2020-02-06 16:45:05 -05:00
committed by GitHub
1423 changed files with 37162 additions and 92572 deletions
@@ -23,12 +23,12 @@
"<span class='notice'>[user] starts reshaping [target]'s ligaments into a hook-like shape.</span>",
"<span class='notice'>[user] starts manipulating [target]'s ligaments.</span>")
/datum/surgery_step/reshape_ligaments/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
/datum/surgery_step/reshape_ligaments/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
display_results(user, target, "<span class='notice'>You reshape [target]'s ligaments into a connective hook!</span>",
"<span class='notice'>[user] reshapes [target]'s ligaments into a connective hook!</span>",
"<span class='notice'>[user] finishes manipulating [target]'s ligaments.</span>")
new /datum/bioware/hooked_ligaments(target)
return ..(default_display_results = FALSE)
return ..()
/datum/bioware/hooked_ligaments
name = "Hooked Ligaments"
@@ -23,12 +23,12 @@
"<span class='notice'>[user] starts reinforce [target]'s ligaments.</span>",
"<span class='notice'>[user] starts manipulating [target]'s ligaments.</span>")
/datum/surgery_step/reinforce_ligaments/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
/datum/surgery_step/reinforce_ligaments/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
display_results(user, target, "<span class='notice'>You reinforce [target]'s ligaments!</span>",
"<span class='notice'>[user] reinforces [target]'s ligaments!</span>",
"<span class='notice'>[user] finishes manipulating [target]'s ligaments.</span>")
new /datum/bioware/reinforced_ligaments(target)
return ..(default_display_results = FALSE)
return ..()
/datum/bioware/reinforced_ligaments
name = "Reinforced Ligaments"
@@ -22,12 +22,12 @@
"<span class='notice'>[user] starts wrapping muscles around [target]'s circulatory system.</span>",
"<span class='notice'>[user] starts manipulating [target]'s circulatory system.</span>")
/datum/surgery_step/muscled_veins/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
/datum/surgery_step/muscled_veins/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
display_results(user, target, "<span class='notice'>You reshape [target]'s circulatory system, adding a muscled membrane!</span>",
"<span class='notice'>[user] reshapes [target]'s circulatory system, adding a muscled membrane!</span>",
"<span class='notice'>[user] finishes manipulating [target]'s circulatory system.</span>")
new /datum/bioware/muscled_veins(target)
return ..(default_display_results = FALSE)
return ..()
/datum/bioware/muscled_veins
name = "Threaded Veins"
@@ -22,12 +22,12 @@
"<span class='notice'>[user] starts rerouting [target]'s nerves.</span>",
"<span class='notice'>[user] starts manipulating [target]'s nervous system.</span>")
/datum/surgery_step/ground_nerves/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
/datum/surgery_step/ground_nerves/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
display_results(user, target, "<span class='notice'>You successfully reroute [target]'s nervous system!</span>",
"<span class='notice'>[user] successfully reroutes [target]'s nervous system!</span>",
"<span class='notice'>[user] finishes manipulating [target]'s nervous system.</span>")
new /datum/bioware/grounded_nerves(target)
return ..(default_display_results = FALSE)
return ..()
/datum/bioware/grounded_nerves
name = "Grounded Nerves"
@@ -22,12 +22,12 @@
"<span class='notice'>[user] starts splicing together [target]'s nerves.</span>",
"<span class='notice'>[user] starts manipulating [target]'s nervous system.</span>")
/datum/surgery_step/splice_nerves/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
/datum/surgery_step/splice_nerves/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
display_results(user, target, "<span class='notice'>You successfully splice [target]'s nervous system!</span>",
"<span class='notice'>[user] successfully splices [target]'s nervous system!</span>",
"<span class='notice'>[user] finishes manipulating [target]'s nervous system.</span>")
new /datum/bioware/spliced_nerves(target)
return ..(default_display_results = FALSE)
return ..()
/datum/bioware/spliced_nerves
name = "Spliced Nerves"
@@ -22,12 +22,12 @@
"<span class='notice'>[user] starts weaving [target]'s circulatory system.</span>",
"<span class='notice'>[user] starts manipulating [target]'s circulatory system.</span>")
/datum/surgery_step/thread_veins/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
/datum/surgery_step/thread_veins/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
display_results(user, target, "<span class='notice'>You weave [target]'s circulatory system into a resistant mesh!</span>",
"<span class='notice'>[user] weaves [target]'s circulatory system into a resistant mesh!</span>",
"<span class='notice'>[user] finishes manipulating [target]'s circulatory system.</span>")
new /datum/bioware/threaded_veins(target)
return ..(default_display_results = FALSE)
return ..()
/datum/bioware/threaded_veins
name = "Threaded Veins"
+3 -3
View File
@@ -9,7 +9,7 @@
/datum/surgery_step/sever_limb
name = "sever limb"
implements = list(TOOL_SCALPEL = 100, TOOL_SAW = 100, /obj/item/melee/arm_blade = 80, /obj/item/twohanded/fireaxe = 50, /obj/item/hatchet = 40, /obj/item/kitchen/knife/butcher = 25)
implements = list(/obj/item/shears = 300, TOOL_SCALPEL = 100, TOOL_SAW = 100, /obj/item/melee/arm_blade = 80, /obj/item/twohanded/fireaxe = 50, /obj/item/hatchet = 40, /obj/item/kitchen/knife/butcher = 25)
time = 64
experience_given = 5
@@ -18,7 +18,7 @@
"<span class='notice'>[user] begins to sever [target]'s [parse_zone(target_zone)]!</span>",
"<span class='notice'>[user] begins to sever [target]'s [parse_zone(target_zone)]!</span>")
/datum/surgery_step/sever_limb/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
/datum/surgery_step/sever_limb/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
var/mob/living/carbon/human/L = target
display_results(user, target, "<span class='notice'>You sever [L]'s [parse_zone(target_zone)].</span>",
"<span class='notice'>[user] severs [L]'s [parse_zone(target_zone)]!</span>",
@@ -28,4 +28,4 @@
target_limb.drop_limb()
if(user.mind)
user.mind.adjust_experience(/datum/skill/medical, experience_given)
return ..(default_display_results = FALSE)
return ..()
+15 -11
View File
@@ -21,15 +21,18 @@
C.emote("scream")
SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "dismembered", /datum/mood_event/dismembered)
drop_limb()
C.update_equipment_speed_mods() // Update in case speed affecting item unequipped by dismemberment
if(dam_type == BURN)
burn()
return 1
add_mob_blood(C)
C.update_equipment_speed_mods() // Update in case speed affecting item unequipped by dismemberment
var/turf/location = C.loc
if(istype(location))
C.add_splatter_floor(location)
if(QDELETED(src)) //Could have dropped into lava/explosion/chasm/whatever
return TRUE
if(dam_type == BURN)
burn()
return TRUE
add_mob_blood(C)
var/direction = pick(GLOB.cardinals)
var/t_range = rand(2,max(throw_range/2, 2))
var/turf/target_turf = get_turf(src)
@@ -41,7 +44,7 @@
if(new_turf.density)
break
throw_at(target_turf, throw_range, throw_speed)
return 1
return TRUE
/obj/item/bodypart/chest/dismember()
@@ -152,7 +155,7 @@
LB.brainmob = brainmob
brainmob = null
LB.brainmob.forceMove(LB)
LB.brainmob.stat = DEAD
LB.brainmob.set_stat(DEAD)
/obj/item/organ/eyes/transfer_to_limb(obj/item/bodypart/head/LB, mob/living/carbon/human/C)
LB.eyes = src
@@ -351,12 +354,13 @@
//Regenerates all limbs. Returns amount of limbs regenerated
/mob/living/proc/regenerate_limbs(noheal, excluded_limbs)
return 0
/mob/living/proc/regenerate_limbs(noheal = FALSE, list/excluded_limbs = list())
SEND_SIGNAL(src, COMSIG_LIVING_REGENERATE_LIMBS, noheal, excluded_limbs)
/mob/living/carbon/regenerate_limbs(noheal, list/excluded_limbs)
/mob/living/carbon/regenerate_limbs(noheal = FALSE, list/excluded_limbs = list())
. = ..()
var/list/limb_list = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG)
if(excluded_limbs)
if(length(excluded_limbs))
limb_list -= excluded_limbs
for(var/Z in limb_list)
. += regenerate_limb(Z, noheal)
+10 -10
View File
@@ -67,27 +67,27 @@
if(!brain)
. += "<span class='info'>The brain has been removed from [src].</span>"
else if(brain.suicided || brainmob?.suiciding)
. += "<span class='info'>There's a pretty dumb expression on [real_name]'s face; they must have really hated life. There is no hope of recovery.</span>"
else if(brain.brain_death || brainmob?.health <= HEALTH_THRESHOLD_DEAD)
. += "<span class='info'>It seems to be leaking some kind of... clear fluid? The brain inside must be in pretty bad shape... There is no coming back from that.</span>"
. += "<span class='info'>There's a miserable expression on [real_name]'s face; they must have really hated life. There's no hope of recovery.</span>"
else if(brainmob?.health <= HEALTH_THRESHOLD_DEAD)
. += "<span class='info'>It's leaking some kind of... clear fluid? The brain inside must be in pretty bad shape.</span>"
else if(brainmob)
if(brainmob.get_ghost(FALSE, TRUE))
. += "<span class='info'>Its muscles are still twitching slightly... It still seems to have a bit of life left to it.</span>"
. += "<span class='info'>Its muscles are twitching slightly... It seems to have some life still in it.</span>"
else
. += "<span class='info'>It seems seems particularly lifeless. Perhaps there'll be a chance for them later.</span>"
. += "<span class='info'>It's completely lifeless. Perhaps there'll be a chance for them later.</span>"
else if(brain?.decoy_override)
. += "<span class='info'>It seems particularly lifeless. Perhaps there'll be a chance for them later.</span>"
. += "<span class='info'>It's completely lifeless. Perhaps there'll be a chance for them later.</span>"
else
. += "<span class='info'>It seems completely devoid of life.</span>"
. += "<span class='info'>It's completely lifeless.</span>"
if(!eyes)
. += "<span class='info'>[real_name]'s eyes appear to have been removed.</span>"
. += "<span class='info'>[real_name]'s eyes have been removed.</span>"
if(!ears)
. += "<span class='info'>[real_name]'s ears appear to have been removed.</span>"
. += "<span class='info'>[real_name]'s ears have been removed.</span>"
if(!tongue)
. += "<span class='info'>[real_name]'s tongue appears to have been removed.</span>"
. += "<span class='info'>[real_name]'s tongue has been removed.</span>"
/obj/item/bodypart/head/can_dismember(obj/item/I)
+3 -2
View File
@@ -146,16 +146,17 @@
for(var/obj/item/I in L.embedded_objects)
L.embedded_objects -= I
I.forceMove(T)
I.unembedded()
clear_alert("embeddedobject")
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "embedded")
/mob/living/carbon/proc/has_embedded_objects()
. = 0
. = FALSE
for(var/X in bodyparts)
var/obj/item/bodypart/L = X
for(var/obj/item/I in L.embedded_objects)
return 1
return TRUE
//Helper for quickly creating a new limb - used by augment code in species.dm spec_attacked_by
+8 -5
View File
@@ -15,7 +15,8 @@
/datum/surgery_step/fix_brain
name = "fix brain"
implements = list(TOOL_HEMOSTAT = 85, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15) //don't worry, pouring some alcohol on their open brain will get that chance to 100
time = 120 //long and complicated
repeatable = TRUE
time = 100 //long and complicated
experience_given = 0 // per_trauma
/datum/surgery/brain_surgery/can_start(mob/user, mob/living/carbon/target)
@@ -29,16 +30,18 @@
"<span class='notice'>[user] begins to fix [target]'s brain.</span>",
"<span class='notice'>[user] begins to perform surgery on [target]'s brain.</span>")
/datum/surgery_step/fix_brain/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
/datum/surgery_step/fix_brain/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
display_results(user, target, "<span class='notice'>You succeed in fixing [target]'s brain.</span>",
"<span class='notice'>[user] successfully fixes [target]'s brain!</span>",
"<span class='notice'>[user] completes the surgery on [target]'s brain.</span>")
if(target.mind && target.mind.has_antag_datum(/datum/antagonist/brainwashed))
if(target.mind?.has_antag_datum(/datum/antagonist/brainwashed))
target.mind.remove_antag_datum(/datum/antagonist/brainwashed)
target.setOrganLoss(ORGAN_SLOT_BRAIN, target.getOrganLoss(ORGAN_SLOT_BRAIN) - 60) //we set damage in this case in order to clear the "failing" flag
target.setOrganLoss(ORGAN_SLOT_BRAIN, target.getOrganLoss(ORGAN_SLOT_BRAIN) - 50) //we set damage in this case in order to clear the "failing" flag
var/cured_num = target.cure_all_traumas(TRAUMA_RESILIENCE_SURGERY)
experience_given = 2*cured_num
return ..(default_display_results = FALSE)
if(target.getOrganLoss(ORGAN_SLOT_BRAIN) > 0)
to_chat(user, "[target]'s brain looks like it could be fixed further.")
return ..()
/datum/surgery_step/fix_brain/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
if(target.getorganslot(ORGAN_SLOT_BRAIN))
+3 -3
View File
@@ -31,7 +31,7 @@
"<span class='notice'>[user] checks for items in [target]'s [target_zone].</span>",
"<span class='notice'>[user] looks for something in [target]'s [target_zone].</span>")
/datum/surgery_step/handle_cavity/success(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
/datum/surgery_step/handle_cavity/success(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery = FALSE)
var/obj/item/bodypart/chest/CH = target.get_bodypart(BODY_ZONE_CHEST)
if(tool)
if(IC || tool.w_class > WEIGHT_CLASS_NORMAL || HAS_TRAIT(tool, TRAIT_NODROP) || istype(tool, /obj/item/organ))
@@ -43,7 +43,7 @@
"<span class='notice'>[user] stuffs [tool.w_class > WEIGHT_CLASS_SMALL ? tool : "something"] into [target]'s [target_zone].</span>")
user.transferItemToLoc(tool, target, TRUE)
CH.cavity_item = tool
return ..(default_display_results = FALSE)
return ..()
else
if(IC)
display_results(user, target, "<span class='notice'>You pull [IC] out of [target]'s [target_zone].</span>",
@@ -51,7 +51,7 @@
"<span class='notice'>[user] pulls [IC.w_class > WEIGHT_CLASS_SMALL ? IC : "something"] out of [target]'s [target_zone].</span>")
user.put_in_hands(IC)
CH.cavity_item = null
return ..(default_display_results = FALSE)
return ..()
else
to_chat(user, "<span class='warning'>You don't find anything in [target]'s [target_zone].</span>")
return 0
+3 -3
View File
@@ -22,7 +22,7 @@
"<span class='notice'>[user] begins to extract a core from [target].</span>",
"<span class='notice'>[user] begins to extract a core from [target].</span>")
/datum/surgery_step/extract_core/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
/datum/surgery_step/extract_core/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
var/mob/living/simple_animal/slime/slime = target
if(slime.cores > 0)
slime.cores--
@@ -34,9 +34,9 @@
if(slime.cores <= 0)
slime.icon_state = "[slime.colour] baby slime dead-nocore"
return ..(default_display_results = FALSE)
return ..()
else
return 0
else
to_chat(user, "<span class='warning'>There aren't any cores left in [target]!</span>")
return ..(default_display_results = FALSE)
return ..()
+5 -4
View File
@@ -24,7 +24,7 @@
"<span class='notice'>[user] begins to make an incision in [target]'s heart.</span>",
"<span class='notice'>[user] begins to make an incision in [target]'s heart.</span>")
/datum/surgery_step/incise_heart/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
/datum/surgery_step/incise_heart/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
if(ishuman(target))
var/mob/living/carbon/human/H = target
if (!(NOBLOOD in H.dna.species.species_traits))
@@ -33,7 +33,7 @@
"")
H.bleed_rate += 10
H.adjustBruteLoss(10)
return ..(default_display_results = FALSE)
return ..()
/datum/surgery_step/incise_heart/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
if(ishuman(target))
@@ -50,13 +50,14 @@
name = "graft coronary bypass"
implements = list(TOOL_HEMOSTAT = 90, TOOL_WIRECUTTER = 35, /obj/item/stack/packageWrap = 15, /obj/item/stack/cable_coil = 5)
time = 90
experience_given = 20
/datum/surgery_step/coronary_bypass/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 graft a bypass onto [target]'s heart...</span>",
"<span class='notice'>[user] begins to graft something onto [target]'s heart!</span>",
"<span class='notice'>[user] begins to graft something onto [target]'s heart!</span>")
/datum/surgery_step/coronary_bypass/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
/datum/surgery_step/coronary_bypass/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
target.setOrganLoss(ORGAN_SLOT_HEART, 60)
var/obj/item/organ/heart/heart = target.getorganslot(ORGAN_SLOT_HEART)
if(heart) //slightly worrying if we lost our heart mid-operation, but that's life
@@ -64,7 +65,7 @@
display_results(user, target, "<span class='notice'>You successfully graft a bypass onto [target]'s heart.</span>",
"<span class='notice'>[user] finishes grafting something onto [target]'s heart.</span>",
"<span class='notice'>[user] finishes grafting something onto [target]'s heart.</span>")
return ..(default_display_results = FALSE)
return ..()
/datum/surgery_step/coronary_bypass/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
if(ishuman(target))
+2 -2
View File
@@ -13,7 +13,7 @@
"<span class='notice'>[user] begins to wedge \the [tool] in [target]'s [parse_zone(target_zone)].</span>",
"<span class='notice'>[user] begins to wedge something in [target]'s [parse_zone(target_zone)].</span>")
/datum/surgery_step/insert_pill/success(mob/user, mob/living/carbon/target, target_zone, obj/item/reagent_containers/pill/tool, datum/surgery/surgery)
/datum/surgery_step/insert_pill/success(mob/user, mob/living/carbon/target, target_zone, obj/item/reagent_containers/pill/tool, datum/surgery/surgery, default_display_results = FALSE)
if(!istype(tool))
return 0
@@ -27,7 +27,7 @@
display_results(user, target, "<span class='notice'>You wedge [tool] into [target]'s [parse_zone(target_zone)].</span>",
"<span class='notice'>[user] wedges \the [tool] into [target]'s [parse_zone(target_zone)]!</span>",
"<span class='notice'>[user] wedges something into [target]'s [parse_zone(target_zone)]!</span>")
return ..(default_display_results = FALSE)
return ..()
/datum/action/item_action/hands_free/activate_pill
name = "Activate Pill"
@@ -73,26 +73,32 @@
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, display_results = TRUE)
/datum/surgery_step/dissection/success(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
var/points_earned = check_value(target, surgery)
user.visible_message("<span class='notice'>[user] dissects [target], discovering [points_earned] point\s of data!</span>", "<span class='notice'>You dissect [target], finding [points_earned] point\s worth of discoveries, you also write a few notes.</span>")
SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = points_earned*PUBLIC_TECHWEB_GAIN))
new /obj/item/research_notes(user.loc, points_earned*PRIVATE_TECHWEB_GAIN, "biology")
var/obj/item/research_notes/the_dossier =new /obj/item/research_notes(user.loc, points_earned*PRIVATE_TECHWEB_GAIN, "biology")
if(!user.put_in_hands(the_dossier) && istype(user.get_inactive_held_item(), /obj/item/research_notes))
var/obj/item/research_notes/hand_dossier = user.get_inactive_held_item()
hand_dossier.merge(the_dossier)
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
experience_given = 1+(points_earned/BASE_HUMAN_REWARD)
return ..(default_display_results = FALSE)
experience_given = 1+(points_earned/(BASE_HUMAN_REWARD/10))//if BHR = 500, 10 XP on base surgery
return ..()
/datum/surgery_step/dissection/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/points_earned = round(check_value(target, surgery) * 0.01)
user.visible_message("<span class='notice'>[user] dissects [target]!</span>", EXPDIS_FAIL_MSG)
SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = points_earned*PUBLIC_TECHWEB_GAIN))
new /obj/item/research_notes(user.loc, points_earned*PRIVATE_TECHWEB_GAIN, "biology")
var/obj/item/research_notes/the_dossier =new /obj/item/research_notes(user.loc, points_earned*PRIVATE_TECHWEB_GAIN, "biology")
if(!user.put_in_hands(the_dossier) && istype(user.get_inactive_held_item(), /obj/item/research_notes))
var/obj/item/research_notes/hand_dossier = user.get_inactive_held_item()
hand_dossier.merge(the_dossier)
var/obj/item/bodypart/L = target.get_bodypart(BODY_ZONE_CHEST)
target.apply_damage(80, BRUTE, L)
+3 -2
View File
@@ -10,6 +10,7 @@
name = "fix eyes"
implements = list(TOOL_HEMOSTAT = 100, TOOL_SCREWDRIVER = 45, /obj/item/pen = 25)
time = 64
experience_given = 5
/datum/surgery/eye_surgery/can_start(mob/user, mob/living/carbon/target)
var/obj/item/organ/eyes/E = target.getorganslot(ORGAN_SLOT_EYES)
@@ -23,7 +24,7 @@
"<span class='notice'>[user] begins to fix [target]'s eyes.</span>",
"<span class='notice'>[user] begins to perform surgery on [target]'s eyes.</span>")
/datum/surgery_step/fix_eyes/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
/datum/surgery_step/fix_eyes/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
var/obj/item/organ/eyes/E = target.getorganslot(ORGAN_SLOT_EYES)
user.visible_message("<span class='notice'>[user] successfully fixes [target]'s eyes!</span>", "<span class='notice'>You succeed in fixing [target]'s eyes.</span>")
display_results(user, target, "<span class='notice'>You succeed in fixing [target]'s eyes.</span>",
@@ -34,7 +35,7 @@
target.cure_nearsighted(list(EYE_DAMAGE))
target.blur_eyes(35) //this will fix itself slowly.
E.setOrganDamage(0)
return ..(default_display_results = FALSE)
return ..()
/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))
+9 -3
View File
@@ -1,3 +1,5 @@
#define PER_ITERATION_XP_CAP 3 //TW XP gain scales with repeated iterations.
/datum/surgery/healing
steps = list(/datum/surgery_step/incise,
/datum/surgery_step/retract_skin,
@@ -26,7 +28,7 @@
implements = list(TOOL_HEMOSTAT = 100, TOOL_SCREWDRIVER = 65, /obj/item/pen = 55)
repeatable = TRUE
time = 25
experience_given = 2
experience_given = 1 //scales with repeated iterations
var/brutehealing = 0
var/burnhealing = 0
var/missinghpbonus = 0 //heals an extra point of damager per X missing damage of type (burn damage for burn healing, brute for brute). Smaller Number = More Healing!
@@ -48,11 +50,13 @@
/datum/surgery_step/heal/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
if(..())
experience_given = min(experience_given+0.25,PER_ITERATION_XP_CAP)
while((brutehealing && target.getBruteLoss()) || (burnhealing && target.getFireLoss()))
if(!..())
break
experience_given = min(experience_given+0.25,PER_ITERATION_XP_CAP)
/datum/surgery_step/heal/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
/datum/surgery_step/heal/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
var/umsg = "You succeed in fixing some of [target]'s wounds" //no period, add initial space to "addons"
var/tmsg = "[user] fixes some of [target]'s wounds" //see above
var/urhealedamt_brute = brutehealing
@@ -76,7 +80,7 @@
if(istype(surgery, /datum/surgery/healing))
var/datum/surgery/healing/the_surgery = surgery
the_surgery.antispam = TRUE
return ..(default_display_results = FALSE)
return ..()
/datum/surgery_step/heal/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "<span class='warning'>You screwed up!</span>",
@@ -214,3 +218,5 @@
"<span class='warning'>[user] screws up!</span>",
"<span class='notice'>[user] fixes some of [target]'s wounds.</span>", TRUE)
target.take_bodypart_damage(5,5)
#undef PER_ITERATION_XP_CAP
+3 -2
View File
@@ -24,19 +24,20 @@
implements = list(TOOL_SCALPEL = 95, /obj/item/melee/transforming/energy/sword = 65, /obj/item/kitchen/knife = 45,
/obj/item/shard = 35)
time = 52
experience_given = 10
/datum/surgery_step/hepatectomy/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 cut out a damaged peice of [target]'s liver...</span>",
"<span class='notice'>[user] begins to make an incision in [target].</span>",
"<span class='notice'>[user] begins to make an incision in [target].</span>")
/datum/surgery_step/hepatectomy/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
/datum/surgery_step/hepatectomy/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
var/mob/living/carbon/human/H = target
H.setOrganLoss(ORGAN_SLOT_LIVER, 10) //not bad, not great
display_results(user, target, "<span class='notice'>You successfully remove the damaged part of [target]'s liver.</span>",
"<span class='notice'>[user] successfully removes the damaged part of [target]'s liver.</span>",
"<span class='notice'>[user] successfully removes the damaged part of [target]'s liver.</span>")
return ..(default_display_results = FALSE)
return ..()
/datum/surgery_step/hepatectomy/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery)
var/mob/living/carbon/human/H = target
+2 -2
View File
@@ -25,7 +25,7 @@
"<span class='notice'>[user] looks for an implant in [target]'s [target_zone].</span>",
"<span class='notice'>[user] looks for something in [target]'s [target_zone].</span>")
/datum/surgery_step/extract_implant/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
/datum/surgery_step/extract_implant/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
if(I)
display_results(user, target, "<span class='notice'>You successfully remove [I] from [target]'s [target_zone].</span>",
"<span class='notice'>[user] successfully removes [I] from [target]'s [target_zone]!</span>",
@@ -50,7 +50,7 @@
else
to_chat(user, "<span class='warning'>You can't find anything in [target]'s [target_zone]!</span>")
return ..(default_display_results = FALSE)
return ..()
/datum/surgery/implant_removal/mechanic
name = "implant removal"
+3 -2
View File
@@ -8,6 +8,7 @@
name = "replace limb"
implements = list(/obj/item/bodypart = 100, /obj/item/organ_storage = 100)
time = 32
experience_given = 10
var/obj/item/bodypart/L = null // L because "limb"
@@ -41,7 +42,7 @@
//SURGERY STEP SUCCESSES
/datum/surgery_step/replace_limb/success(mob/user, mob/living/carbon/target, target_zone, obj/item/bodypart/tool, datum/surgery/surgery)
/datum/surgery_step/replace_limb/success(mob/user, mob/living/carbon/target, target_zone, obj/item/bodypart/tool, datum/surgery/surgery, default_display_results = FALSE)
if(L)
if(istype(tool, /obj/item/organ_storage))
tool.icon_state = initial(tool.icon_state)
@@ -56,4 +57,4 @@
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 ..(default_display_results = FALSE)
return ..()
+7 -4
View File
@@ -4,7 +4,7 @@
possible_locs = list(BODY_ZONE_CHEST)
/datum/surgery/lipoplasty/can_start(mob/user, mob/living/carbon/target)
if(HAS_TRAIT(target, TRAIT_FAT))
if(HAS_TRAIT(target, TRAIT_FAT) && target.nutrition >= NUTRITION_LEVEL_WELL_FED)
return 1
return 0
@@ -14,6 +14,7 @@
name = "cut excess fat"
implements = list(TOOL_SAW = 100, /obj/item/hatchet = 35, /obj/item/kitchen/knife/butcher = 25)
time = 64
experience_given = 2
/datum/surgery_step/cut_fat/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
user.visible_message("<span class='notice'>[user] begins to cut away [target]'s excess fat.</span>", "<span class='notice'>You begin to cut away [target]'s excess fat...</span>")
@@ -32,20 +33,22 @@
name = "remove loose fat"
implements = list(TOOL_RETRACTOR = 100, TOOL_SCREWDRIVER = 45, TOOL_WIRECUTTER = 35)
time = 32
experience_given = 0 //scales with fat removed
/datum/surgery_step/remove_fat/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 [target]'s loose fat...</span>",
"<span class='notice'>[user] begins to extract [target]'s loose fat!</span>",
"<span class='notice'>[user] begins to extract something from [target]'s [target_zone].</span>")
/datum/surgery_step/remove_fat/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
/datum/surgery_step/remove_fat/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
display_results(user, target, "<span class='notice'>You extract [target]'s fat.</span>",
"<span class='notice'>[user] extracts [target]'s fat!</span>",
"<span class='notice'>[user] extracts [target]'s fat!</span>")
target.overeatduration = 0 //patient is unfatted
var/removednutriment = target.nutrition
target.set_nutrition(NUTRITION_LEVEL_WELL_FED)
removednutriment -= 450 //whatever was removed goes into the meat
removednutriment -= NUTRITION_LEVEL_WELL_FED //whatever was removed goes into the meat
experience_given = (round(removednutriment/30))
var/mob/living/carbon/human/H = target
var/typeofmeat = /obj/item/reagent_containers/food/snacks/meat/slab/human
@@ -59,4 +62,4 @@
newmeat.subjectjob = H.job
newmeat.reagents.add_reagent (/datum/reagent/consumable/nutriment, (removednutriment / 15)) //To balance with nutriment_factor of nutriment
newmeat.forceMove(target.loc)
return ..(default_display_results = FALSE)
return ..()
+3 -2
View File
@@ -18,13 +18,14 @@
implements = list(TOOL_SCALPEL = 95, /obj/item/melee/transforming/energy/sword = 65, /obj/item/kitchen/knife = 45,
/obj/item/shard = 35)
time = 42
experience_given = 10
/datum/surgery_step/lobectomy/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 make an incision in [target]'s lungs...</span>",
"<span class='notice'>[user] begins to make an incision in [target].</span>",
"<span class='notice'>[user] begins to make an incision in [target].</span>")
/datum/surgery_step/lobectomy/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
/datum/surgery_step/lobectomy/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
if(ishuman(target))
var/mob/living/carbon/human/H = target
var/obj/item/organ/lungs/L = H.getorganslot(ORGAN_SLOT_LUNGS)
@@ -33,7 +34,7 @@
display_results(user, target, "<span class='notice'>You successfully excise [H]'s most damaged lobe.</span>",
"<span class='notice'>Successfully removes a piece of [H]'s lungs.</span>",
"")
return ..(default_display_results = FALSE)
return ..()
/datum/surgery_step/lobectomy/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
if(ishuman(target))
+5 -6
View File
@@ -68,7 +68,7 @@
time = 64
name = "manipulate organs"
repeatable = 1
implements = list(/obj/item/organ = 100, /obj/item/reagent_containers/food/snacks/organ = 0, /obj/item/organ_storage = 100)
implements = list(/obj/item/organ = 100, /obj/item/organ_storage = 100)
var/implements_extract = list(TOOL_HEMOSTAT = 100, TOOL_CROWBAR = 55)
var/current_type
var/obj/item/organ/I = null
@@ -94,7 +94,10 @@
if(target_zone != I.zone || target.getorganslot(I.slot))
to_chat(user, "<span class='warning'>There is no room for [I] in [target]'s [parse_zone(target_zone)]!</span>")
return -1
var/obj/item/organ/meatslab = tool
if(!meatslab.useable)
to_chat(user, "<span class='warning'>[I] seems to have been chewed on, you can't use this!</span>")
return -1
display_results(user, target, "<span class='notice'>You begin to insert [tool] into [target]'s [parse_zone(target_zone)]...</span>",
"<span class='notice'>[user] begins to insert [tool] into [target]'s [parse_zone(target_zone)].</span>",
"<span class='notice'>[user] begins to insert something into [target]'s [parse_zone(target_zone)].</span>")
@@ -122,10 +125,6 @@
else
return -1
else if(istype(tool, /obj/item/reagent_containers/food/snacks/organ))
to_chat(user, "<span class='warning'>[tool] was bitten by someone! It's too damaged to use!</span>")
return -1
/datum/surgery_step/manipulate_organs/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
if(current_type == "insert")
if(istype(tool, /obj/item/organ_storage))
+6 -6
View File
@@ -17,7 +17,7 @@
return TRUE
/datum/surgery_step/incise/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
/datum/surgery_step/incise/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
if ishuman(target)
var/mob/living/carbon/human/H = target
if (!(NOBLOOD in H.dna.species.species_traits))
@@ -25,9 +25,10 @@
"<span class='notice'>Blood pools around the incision in [H]'s [parse_zone(target_zone)].</span>",
"")
H.bleed_rate += 3
return ..(default_display_results = FALSE)
return ..()
/datum/surgery_step/incise/nobleed //silly friendly!
experience_given = 1 //safer so not as much XP
/datum/surgery_step/incise/nobleed/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 <i>carefully</i> make an incision in [target]'s [parse_zone(target_zone)]...</span>",
@@ -113,7 +114,6 @@
/datum/surgery_step/saw/tool_check(mob/user, obj/item/tool)
if(implement_type == /obj/item && !(tool.get_sharpness() && (tool.force >= 10)))
return FALSE
return TRUE
/datum/surgery_step/saw/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
@@ -121,7 +121,7 @@
display_results(user, target, "<span class='notice'>You saw [target]'s [parse_zone(target_zone)] open.</span>",
"<span class='notice'>[user] saws [target]'s [parse_zone(target_zone)] open!</span>",
"<span class='notice'>[user] saws [target]'s [parse_zone(target_zone)] open!</span>")
return ..(default_display_results = FALSE)
return ..()
//drill bone
/datum/surgery_step/drill
@@ -134,8 +134,8 @@
"<span class='notice'>[user] begins to drill into the bone in [target]'s [parse_zone(target_zone)].</span>",
"<span class='notice'>[user] begins to drill into the bone in [target]'s [parse_zone(target_zone)].</span>")
/datum/surgery_step/drill/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
/datum/surgery_step/drill/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
display_results(user, target, "<span class='notice'>You drill into [target]'s [parse_zone(target_zone)].</span>",
"<span class='notice'>[user] drills into [target]'s [parse_zone(target_zone)]!</span>",
"<span class='notice'>[user] drills into [target]'s [parse_zone(target_zone)]!</span>")
return ..(default_display_results = FALSE)
return ..()
-6
View File
@@ -39,9 +39,3 @@
..()
if(inflamed)
M.ForceContractDisease(new /datum/disease/appendicitis(), FALSE, TRUE)
/obj/item/organ/appendix/prepare_eat()
var/obj/S = ..()
if(inflamed)
S.reagents.add_reagent(/datum/reagent/toxin/bad_food, 5)
return S
@@ -152,7 +152,7 @@
if(allow_thrust(0.01))
ion_trail.start()
RegisterSignal(owner, COMSIG_MOVABLE_MOVED, .proc/move_react)
owner.add_movespeed_modifier(MOVESPEED_ID_CYBER_THRUSTER, priority=100, multiplicative_slowdown=-2, movetypes=FLOATING, conflict=MOVE_CONFLICT_JETPACK)
owner.add_movespeed_modifier(MOVESPEED_ID_CYBER_THRUSTER, priority=100, multiplicative_slowdown=-0.5, movetypes=FLOATING, conflict=MOVE_CONFLICT_JETPACK)
if(!silent)
to_chat(owner, "<span class='notice'>You turn your thrusters set on.</span>")
else
@@ -164,14 +164,11 @@
on = FALSE
update_icon()
/obj/item/organ/cyberimp/chest/thrusters/update_icon()
/obj/item/organ/cyberimp/chest/thrusters/update_icon_state()
if(on)
icon_state = "imp_jetpack-on"
else
icon_state = "imp_jetpack"
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
/obj/item/organ/cyberimp/chest/thrusters/proc/move_react()
allow_thrust(0.01)
+3 -4
View File
@@ -39,7 +39,7 @@
deaf = max(deaf, 1)
else if(!(organ_flags & ORGAN_FAILING)) // if this organ is failing, do not clear deaf stacks.
deaf = max(deaf - 1, 0)
if(prob(damage / 20) && (damage > low_threshold))
if(prob(damage / 30) && (damage > low_threshold))
adjustEarDamage(0, 4)
SEND_SOUND(C, sound('sound/weapons/flash_ring.ogg'))
to_chat(C, "<span class='warning'>The ringing in your ears grows louder, blocking out any external noises for a moment.</span>")
@@ -114,19 +114,18 @@
/obj/item/organ/ears/penguin
name = "penguin ears"
desc = "The source of a penguin's happy feet."
var/datum/component/waddle
/obj/item/organ/ears/penguin/Insert(mob/living/carbon/human/H, special = 0, drop_if_replaced = TRUE)
. = ..()
if(istype(H))
to_chat(H, "<span class='notice'>You suddenly feel like you've lost your balance.</span>")
waddle = H.AddComponent(/datum/component/waddling)
H.AddElement(/datum/element/waddling)
/obj/item/organ/ears/penguin/Remove(mob/living/carbon/human/H, special = 0)
. = ..()
if(istype(H))
to_chat(H, "<span class='notice'>Your sense of balance comes back to you.</span>")
QDEL_NULL(waddle)
H.RemoveElement(/datum/element/waddling)
/obj/item/organ/ears/bronze
name = "tin ears"
+1 -1
View File
@@ -197,7 +197,7 @@
/obj/item/organ/eyes/robotic/shield/emp_act(severity)
return
#define RGB2EYECOLORSTRING(definitionvar) ("[copytext(definitionvar,2,3)][copytext(definitionvar,4,5)][copytext(definitionvar,6,7)]")
#define RGB2EYECOLORSTRING(definitionvar) ("[copytext_char(definitionvar, 2, 3)][copytext_char(definitionvar, 4, 5)][copytext_char(definitionvar, 6, 7)]")
/obj/item/organ/eyes/robotic/glow
name = "High Luminosity Eyes"
+39 -21
View File
@@ -6,7 +6,7 @@
slot = ORGAN_SLOT_HEART
healing_factor = STANDARD_ORGAN_HEALING
decay_factor = 5 * STANDARD_ORGAN_DECAY //designed to fail about 5 minutes after death
decay_factor = 3.5 * STANDARD_ORGAN_DECAY //designed to fail a little under 4 minutes after death
low_threshold_passed = "<span class='info'>Prickles of pain appear then die out from within your chest...</span>"
high_threshold_passed = "<span class='warning'>Something inside your chest hurts, and the pain isn't subsiding. You notice yourself breathing far faster than before.</span>"
@@ -21,7 +21,7 @@
var/failed = FALSE //to prevent constantly running failing code
var/operated = FALSE //whether the heart's been operated on to fix some of its damages
/obj/item/organ/heart/update_icon()
/obj/item/organ/heart/update_icon_state()
if(beating)
icon_state = "[icon_base]-on"
else
@@ -54,10 +54,10 @@
update_icon()
return 1
/obj/item/organ/heart/prepare_eat()
var/obj/S = ..()
S.icon_state = "heart-off"
return S
/obj/item/organ/heart/OnEatFrom(eater, feeder)
. = ..()
beating = FALSE
update_icon()
/obj/item/organ/heart/on_life()
..()
@@ -172,40 +172,58 @@
colour = "red"
/obj/item/organ/heart/cybernetic
name = "cybernetic heart"
desc = "An electronic device designed to mimic the functions of an organic human heart. Also holds an emergency dose of epinephrine, used automatically after facing severe trauma."
name = "basic cybernetic heart"
desc = "A basic electronic device designed to mimic the functions of an organic human heart."
icon_state = "heart-c"
organ_flags = ORGAN_SYNTHETIC
maxHealth = 1.1 * STANDARD_ORGAN_THRESHOLD
maxHealth = STANDARD_ORGAN_THRESHOLD*0.75 //This also hits defib timer, so a bit higher than its less important counterparts
var/dose_available = TRUE
var/dose_available = FALSE
var/rid = /datum/reagent/medicine/epinephrine
var/ramount = 10
var/emp_vulnerability = 80 //Chance of permanent effects if emp-ed.
/obj/item/organ/heart/cybernetic/tier2
name = "cybernetic heart"
desc = "An electronic device designed to mimic the functions of an organic human heart. Also holds an emergency dose of epinephrine, used automatically after facing severe trauma."
icon_state = "heart-c-u"
maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD
dose_available = TRUE
emp_vulnerability = 40
/obj/item/organ/heart/cybernetic/tier3
name = "upgraded cybernetic heart"
desc = "An electronic device designed to mimic the functions of an organic human heart. Also holds an emergency dose of epinephrine, used automatically after facing severe trauma. This upgraded model can regenerate its dose after use."
icon_state = "heart-c-u2"
maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
dose_available = TRUE
emp_vulnerability = 20
/obj/item/organ/heart/cybernetic/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
Stop()
addtimer(CALLBACK(src, .proc/Restart), 20/severity SECONDS)
damage += 100/severity
if(world.time > severe_cooldown) //So we cant just spam emp to kill people.
owner.Dizzy(10)
owner.losebreath += 10
severe_cooldown = world.time + 20 SECONDS
if(prob(emp_vulnerability/severity)) //Chance of permanent effects
organ_flags = ORGAN_SYNTHETIC_EMP //Starts organ faliure - gonna need replacing soon.
Stop()
owner.visible_message("<span class='danger'>[owner] clutches at [owner.p_their()] chest as if [owner.p_their()] heart is stopping!</span>", \
"<span class='userdanger'>You feel a terrible pain in your chest, as if your heart has stopped!</span>")
addtimer(CALLBACK(src, .proc/Restart), 10 SECONDS)
/obj/item/organ/heart/cybernetic/on_life()
. = ..()
if(dose_available && owner.health <= owner.crit_threshold && !owner.reagents.has_reagent(rid))
owner.reagents.add_reagent(rid, ramount)
used_dose()
/obj/item/organ/heart/cybernetic/proc/used_dose()
owner.reagents.add_reagent(rid, ramount)
dose_available = FALSE
/obj/item/organ/heart/cybernetic/upgraded
name = "upgraded cybernetic heart"
desc = "An electronic device designed to mimic the functions of an organic human heart. Also holds an emergency dose of epinephrine, used automatically after facing severe trauma. This upgraded model can regenerate its dose after use."
icon_state = "heart-c-u"
maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
/obj/item/organ/heart/cybernetic/upgraded/used_dose()
/obj/item/organ/heart/cybernetic/tier3/used_dose()
. = ..()
addtimer(VARSET_CALLBACK(src, dose_available, TRUE), 5 MINUTES)
+117 -104
View File
@@ -1,104 +1,117 @@
#define LIVER_DEFAULT_TOX_TOLERANCE 3 //amount of toxins the liver can filter out
#define LIVER_DEFAULT_TOX_LETHALITY 0.01 //lower values lower how harmful toxins are to the liver
/obj/item/organ/liver
name = "liver"
icon_state = "liver"
w_class = WEIGHT_CLASS_SMALL
zone = BODY_ZONE_CHEST
slot = ORGAN_SLOT_LIVER
desc = "Pairing suggestion: chianti and fava beans."
maxHealth = STANDARD_ORGAN_THRESHOLD
healing_factor = STANDARD_ORGAN_HEALING
decay_factor = STANDARD_ORGAN_DECAY
var/alcohol_tolerance = ALCOHOL_RATE//affects how much damage the liver takes from alcohol
var/toxTolerance = LIVER_DEFAULT_TOX_TOLERANCE//maximum amount of toxins the liver can just shrug off
var/toxLethality = LIVER_DEFAULT_TOX_LETHALITY//affects how much damage toxins do to the liver
var/filterToxins = TRUE //whether to filter toxins
#define HAS_SILENT_TOXIN 0 //don't provide a feedback message if this is the only toxin present
#define HAS_NO_TOXIN 1
#define HAS_PAINFUL_TOXIN 2
/obj/item/organ/liver/on_life()
var/mob/living/carbon/C = owner
..() //perform general on_life()
if(istype(C))
if(!(organ_flags & ORGAN_FAILING) && !HAS_TRAIT(C, TRAIT_NOMETABOLISM))//can't process reagents with a failing liver
var/provide_pain_message = HAS_NO_TOXIN
if(filterToxins && !HAS_TRAIT(owner, TRAIT_TOXINLOVER))
//handle liver toxin filtration
for(var/datum/reagent/toxin/T in C.reagents.reagent_list)
var/thisamount = C.reagents.get_reagent_amount(T.type)
if (thisamount && thisamount <= toxTolerance)
C.reagents.remove_reagent(T.type, 1)
else
damage += (thisamount*toxLethality)
if(provide_pain_message != HAS_PAINFUL_TOXIN)
provide_pain_message = T.silent_toxin ? HAS_SILENT_TOXIN : HAS_PAINFUL_TOXIN
//metabolize reagents
C.reagents.metabolize(C, can_overdose=TRUE)
if(provide_pain_message && damage > 10 && prob(damage/3))//the higher the damage the higher the probability
to_chat(C, "<span class='warning'>You feel a dull pain in your abdomen.</span>")
else //for when our liver's failing
C.liver_failure()
if(damage > maxHealth)//cap liver damage
damage = maxHealth
#undef HAS_SILENT_TOXIN
#undef HAS_NO_TOXIN
#undef HAS_PAINFUL_TOXIN
/obj/item/organ/liver/prepare_eat()
var/obj/S = ..()
S.reagents.add_reagent(/datum/reagent/iron, 5)
return S
/obj/item/organ/liver/fly
name = "insectoid liver"
icon_state = "liver-x" //xenomorph liver? It's just a black liver so it fits.
desc = "A mutant liver designed to handle the unique diet of a flyperson."
alcohol_tolerance = 0.007 //flies eat vomit, so a lower alcohol tolerance is perfect!
/obj/item/organ/liver/plasmaman
name = "reagent processing crystal"
icon_state = "liver-p"
desc = "A large crystal that is somehow capable of metabolizing chemicals, these are found in plasmamen."
/obj/item/organ/liver/alien
name = "alien liver" // doesnt matter for actual aliens because they dont take toxin damage
icon_state = "liver-x" // Same sprite as fly-person liver.
desc = "A liver that used to belong to a killer alien, who knows what it used to eat."
toxLethality = LIVER_DEFAULT_TOX_LETHALITY * 2.5 // rejects its owner early after too much punishment
toxTolerance = 15 // complete toxin immunity like xenos have would be too powerful
/obj/item/organ/liver/cybernetic
name = "cybernetic liver"
icon_state = "liver-c"
desc = "An electronic device designed to mimic the functions of a human liver. Handles toxins slightly better than an organic liver."
organ_flags = ORGAN_SYNTHETIC
maxHealth = 1.1 * STANDARD_ORGAN_THRESHOLD
toxTolerance = 3.3
toxLethality = 0.009
/obj/item/organ/liver/cybernetic/upgraded
name = "upgraded cybernetic liver"
icon_state = "liver-c-u"
desc = "An upgraded version of the cybernetic liver, designed to improve further upon organic livers. It is resistant to alcohol poisoning and is very robust at filtering toxins."
alcohol_tolerance = 0.001
maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
toxTolerance = 15 //can shrug off up to 15u of toxins
toxLethality = 0.008 //20% less damage than a normal liver
/obj/item/organ/liver/cybernetic/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
damage += 100/severity
#define LIVER_DEFAULT_TOX_TOLERANCE 3 //amount of toxins the liver can filter out
#define LIVER_DEFAULT_TOX_LETHALITY 0.01 //lower values lower how harmful toxins are to the liver
/obj/item/organ/liver
name = "liver"
icon_state = "liver"
w_class = WEIGHT_CLASS_SMALL
zone = BODY_ZONE_CHEST
slot = ORGAN_SLOT_LIVER
desc = "Pairing suggestion: chianti and fava beans."
maxHealth = STANDARD_ORGAN_THRESHOLD
healing_factor = STANDARD_ORGAN_HEALING
decay_factor = STANDARD_ORGAN_DECAY
food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/iron = 5)
var/alcohol_tolerance = ALCOHOL_RATE//affects how much damage the liver takes from alcohol
var/toxTolerance = LIVER_DEFAULT_TOX_TOLERANCE//maximum amount of toxins the liver can just shrug off
var/toxLethality = LIVER_DEFAULT_TOX_LETHALITY//affects how much damage toxins do to the liver
var/filterToxins = TRUE //whether to filter toxins
#define HAS_SILENT_TOXIN 0 //don't provide a feedback message if this is the only toxin present
#define HAS_NO_TOXIN 1
#define HAS_PAINFUL_TOXIN 2
/obj/item/organ/liver/on_life()
var/mob/living/carbon/C = owner
..() //perform general on_life()
if(istype(C))
if(!(organ_flags & ORGAN_FAILING) && !HAS_TRAIT(C, TRAIT_NOMETABOLISM))//can't process reagents with a failing liver
var/provide_pain_message = HAS_NO_TOXIN
if(filterToxins && !HAS_TRAIT(owner, TRAIT_TOXINLOVER))
//handle liver toxin filtration
for(var/datum/reagent/toxin/T in C.reagents.reagent_list)
var/thisamount = C.reagents.get_reagent_amount(T.type)
if (thisamount && thisamount <= toxTolerance)
C.reagents.remove_reagent(T.type, 1)
else
damage += (thisamount*toxLethality)
if(provide_pain_message != HAS_PAINFUL_TOXIN)
provide_pain_message = T.silent_toxin ? HAS_SILENT_TOXIN : HAS_PAINFUL_TOXIN
//metabolize reagents
C.reagents.metabolize(C, can_overdose=TRUE)
if(provide_pain_message && damage > 10 && prob(damage/3))//the higher the damage the higher the probability
to_chat(C, "<span class='warning'>You feel a dull pain in your abdomen.</span>")
else //for when our liver's failing
C.liver_failure()
if(damage > maxHealth)//cap liver damage
damage = maxHealth
#undef HAS_SILENT_TOXIN
#undef HAS_NO_TOXIN
#undef HAS_PAINFUL_TOXIN
/obj/item/organ/liver/fly
name = "insectoid liver"
icon_state = "liver-x" //xenomorph liver? It's just a black liver so it fits.
desc = "A mutant liver designed to handle the unique diet of a flyperson."
alcohol_tolerance = 0.007 //flies eat vomit, so a lower alcohol tolerance is perfect!
/obj/item/organ/liver/plasmaman
name = "reagent processing crystal"
icon_state = "liver-p"
desc = "A large crystal that is somehow capable of metabolizing chemicals, these are found in plasmamen."
/obj/item/organ/liver/alien
name = "alien liver" // doesnt matter for actual aliens because they dont take toxin damage
icon_state = "liver-x" // Same sprite as fly-person liver.
desc = "A liver that used to belong to a killer alien, who knows what it used to eat."
toxLethality = LIVER_DEFAULT_TOX_LETHALITY * 2.5 // rejects its owner early after too much punishment
toxTolerance = 15 // complete toxin immunity like xenos have would be too powerful
/obj/item/organ/liver/cybernetic
name = "basic cybernetic liver"
icon_state = "liver-c"
desc = "A very basic device designed to mimic the functions of a human liver. Handles toxins slightly worse than an organic liver."
organ_flags = ORGAN_SYNTHETIC
toxTolerance = 2
toxLethality = 0.011
maxHealth = STANDARD_ORGAN_THRESHOLD*0.5
var/emp_vulnerability = 80 //Chance of permanent effects if emp-ed.
/obj/item/organ/liver/cybernetic/tier2
name = "cybernetic liver"
icon_state = "liver-c-u"
desc = "An electronic device designed to mimic the functions of a human liver. Handles toxins slightly better than an organic liver."
maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD
toxTolerance = 5 //can shrug off up to 5u of toxins
toxLethality = 0.008 //20% less damage than a normal liver
emp_vulnerability = 40
/obj/item/organ/liver/cybernetic/tier3
name = "upgraded cybernetic liver"
icon_state = "liver-c-u2"
desc = "An upgraded version of the cybernetic liver, designed to improve further upon organic livers. It is resistant to alcohol poisoning and is very robust at filtering toxins."
alcohol_tolerance = 0.001
maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
toxTolerance = 10 //can shrug off up to 10u of toxins
toxLethality = 0.008 //20% less damage than a normal liver
emp_vulnerability = 20
/obj/item/organ/liver/cybernetic/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
if(world.time > severe_cooldown) //So we cant just spam emp to kill people.
owner.adjustToxLoss(10)
severe_cooldown = world.time + 10 SECONDS
if(prob(emp_vulnerability/severity)) //Chance of permanent effects
organ_flags = ORGAN_SYNTHETIC_EMP //Starts organ faliure - gonna need replacing soon.
+42 -24
View File
@@ -11,10 +11,15 @@
healing_factor = STANDARD_ORGAN_HEALING
decay_factor = STANDARD_ORGAN_DECAY
low_threshold_passed = "<span class='warning'>You feel short of breath.</span>"
high_threshold_passed = "<span class='warning'>You feel some sort of constriction around your chest as your breathing becomes shallow and rapid.</span>"
now_fixed = "<span class='warning'>Your lungs seem to once again be able to hold air.</span>"
low_threshold_cleared = "<span class='info'>You can breathe normally again.</span>"
high_threshold_cleared = "<span class='info'>The constriction around your chest loosens as your breathing calms down.</span>"
food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/medicine/salbutamol = 5)
//Breath damage
var/safe_oxygen_min = 16 // Minimum safe partial pressure of O2, in kPa
@@ -392,20 +397,18 @@
breath.temperature = H.bodytemperature
/obj/item/organ/lungs/on_life()
..()
if((!failed) && ((organ_flags & ORGAN_FAILING)))
if(owner.stat == CONSCIOUS)
owner.visible_message("<span class='danger'>[owner] grabs [owner.p_their()] throat, struggling for breath!</span>", \
"<span class='userdanger'>You suddenly feel like you can't breathe!</span>")
failed = TRUE
else if(!(organ_flags & ORGAN_FAILING))
. = ..()
if(failed && !(organ_flags & ORGAN_FAILING))
failed = FALSE
return
return
if(damage >= low_threshold)
var/do_i_cough = damage < high_threshold ? prob(5) : prob(10) // between : past high
if(do_i_cough)
owner.emote("cough")
if(organ_flags & ORGAN_FAILING && owner.stat == CONSCIOUS)
owner.visible_message("<span class='danger'>[owner] grabs [owner.p_their()] throat, struggling for breath!</span>", "<span class='userdanger'>You suddenly feel like you can't breathe!</span>")
failed = TRUE
/obj/item/organ/lungs/prepare_eat()
var/obj/S = ..()
S.reagents.add_reagent(/datum/reagent/medicine/salbutamol, 5)
return S
/obj/item/organ/lungs/plasmaman
name = "plasma filter"
@@ -429,28 +432,43 @@
owner.blood_volume += (0.2 * plasma_pp) // 10/s when breathing literally nothing but plasma, which will suffocate you.
/obj/item/organ/lungs/cybernetic
name = "cybernetic lungs"
desc = "A cybernetic version of the lungs found in traditional humanoid entities. Allows for greater intakes of oxygen than organic lungs, requiring slightly less pressure."
name = "basic cybernetic lungs"
desc = "A basic cybernetic version of the lungs found in traditional humanoid entities."
icon_state = "lungs-c"
organ_flags = ORGAN_SYNTHETIC
maxHealth = 1.1 * STANDARD_ORGAN_THRESHOLD
safe_oxygen_min = 16
maxHealth = STANDARD_ORGAN_THRESHOLD*0.5
var/emp_vulnerability = 80 //Chance of permanent effects if emp-ed.
/obj/item/organ/lungs/cybernetic/tier2
name = "cybernetic lungs"
desc = "A cybernetic version of the lungs found in traditional humanoid entities. Allows for greater intakes of oxygen than organic lungs, requiring slightly less pressure."
icon_state = "lungs-c-u"
organ_flags = ORGAN_SYNTHETIC
maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD
safe_oxygen_min = 13
emp_vulnerability = 40
/obj/item/organ/lungs/cybernetic/emp_act()
. = ..()
if(. & EMP_PROTECT_SELF)
return
owner.losebreath = 20
/obj/item/organ/lungs/cybernetic/upgraded
/obj/item/organ/lungs/cybernetic/tier3
name = "upgraded cybernetic lungs"
desc = "A more advanced version of the stock cybernetic lungs. Features the ability to filter out lower levels of toxins and carbon dioxide."
icon_state = "lungs-c-u"
icon_state = "lungs-c-u2"
safe_toxins_max = 20
safe_co2_max = 20
maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
emp_vulnerability = 20
cold_level_1_threshold = 200
cold_level_2_threshold = 140
cold_level_3_threshold = 100
/obj/item/organ/lungs/cybernetic/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
if(world.time > severe_cooldown) //So we cant just spam emp to kill people.
owner.losebreath += 20
severe_cooldown = world.time + 30 SECONDS
if(prob(emp_vulnerability/severity)) //Chance of permanent effects
organ_flags = ORGAN_SYNTHETIC_EMP //Starts organ faliure - gonna need replacing soon.
+18 -33
View File
@@ -8,7 +8,7 @@
var/zone = BODY_ZONE_CHEST
var/slot
// DO NOT add slots with matching names to different zones - it will break internal_organs_slot list!
var/organ_flags = 0
var/organ_flags = ORGAN_EDIBLE
var/maxHealth = STANDARD_ORGAN_THRESHOLD
var/damage = 0 //total damage this organ has sustained
///Healing factor and decay factor function on % of maxhealth, and do not work by applying a static number per tick
@@ -16,7 +16,7 @@
var/decay_factor = 0 //same as above but when without a living owner, set to 0 for generic organs
var/high_threshold = STANDARD_ORGAN_THRESHOLD * 0.45 //when severe organ damage occurs
var/low_threshold = STANDARD_ORGAN_THRESHOLD * 0.1 //when minor organ damage occurs
var/severe_cooldown //cooldown for severe effects, used for synthetic organ emp effects.
///Organ variables for determining what we alert the owner with when they pass/clear the damage thresholds
var/prev_damage = 0
var/low_threshold_passed
@@ -26,6 +26,15 @@
var/high_threshold_cleared
var/low_threshold_cleared
///When you take a bite you cant jam it in for surgery anymore.
var/useable = TRUE
var/list/food_reagents = list(/datum/reagent/consumable/nutriment = 5)
/obj/item/organ/Initialize()
. = ..()
if(organ_flags & ORGAN_EDIBLE)
AddComponent(/datum/component/edible, food_reagents, null, RAW | MEAT | GROSS, null, 10, null, null, null, CALLBACK(src, .proc/OnEatFrom))
/obj/item/organ/proc/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
if(!iscarbon(M) || owner == M)
return
@@ -81,6 +90,9 @@
/obj/item/organ/proc/on_life() //repair organ damage if the organ is not failing
if(organ_flags & ORGAN_FAILING)
return
if(organ_flags & ORGAN_SYNTHETIC_EMP) //Synthetic organ has been emped, is now failing.
applyOrganDamage(maxHealth * decay_factor)
return
///Damage decrements by a percent of its maxhealth
var/healing_amount = -(maxHealth * healing_factor)
///Damage decrements again by a percent of its maxhealth, up to a total of 4 extra times depending on the owner's health
@@ -91,31 +103,13 @@
. = ..()
if(organ_flags & ORGAN_FAILING)
if(status == ORGAN_ROBOTIC)
. += "<span class='warning'>[src] seems to be broken!</span>"
. += "<span class='warning'>[src] seems to be broken.</span>"
return
. += "<span class='warning'>[src] has decayed for too long, and has turned a sickly color! It doesn't look like it will work anymore!</span>"
. += "<span class='warning'>[src] has decayed for too long, and has turned a sickly color. It probably won't work without repairs.</span>"
return
if(damage > high_threshold)
. += "<span class='warning'>[src] is starting to look discolored.</span>"
/obj/item/organ/proc/prepare_eat()
var/obj/item/reagent_containers/food/snacks/organ/S = new
S.name = name
S.desc = desc
S.icon = icon
S.icon_state = icon_state
S.w_class = w_class
return S
/obj/item/reagent_containers/food/snacks/organ
name = "appendix"
icon_state = "appendix"
icon = 'icons/obj/surgery.dmi'
list_reagents = list(/datum/reagent/consumable/nutriment = 5)
foodtype = RAW | MEAT | GROSS
/obj/item/organ/Initialize()
. = ..()
START_PROCESSING(SSobj, src)
@@ -129,17 +123,8 @@
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/organ/attack(mob/living/carbon/M, mob/user)
if(M == user && ishuman(user))
var/mob/living/carbon/human/H = user
if(status == ORGAN_ORGANIC)
var/obj/item/reagent_containers/food/snacks/S = prepare_eat(H)
if(S)
qdel(src)
if(H.put_in_active_hand(S))
S.attack(H, H)
else
..()
/obj/item/organ/proc/OnEatFrom(eater, feeder)
useable = FALSE //You can't use it anymore after eating it you spaztic
/obj/item/organ/item_action_slot_check(slot,mob/user)
return //so we don't grant the organ's action to mobs who pick up the organ.
+1 -1
View File
@@ -124,4 +124,4 @@
to_chat(owner, "<span class='notice'>You absorb some of the shock into your body!</span>")
/obj/item/organ/stomach/ethereal/proc/adjust_charge(amount)
crystal_charge = CLAMP(crystal_charge + amount, ETHEREAL_CHARGE_NONE, ETHEREAL_CHARGE_FULL)
crystal_charge = CLAMP(crystal_charge + amount, ETHEREAL_CHARGE_NONE, ETHEREAL_CHARGE_DANGEROUS)
+4
View File
@@ -41,6 +41,10 @@
tail_type = "Smooth"
var/spines = "None"
/obj/item/organ/tail/lizard/Initialize()
..()
color = "#"+ random_color()
/obj/item/organ/tail/lizard/Insert(mob/living/carbon/human/H, special = 0, drop_if_replaced = TRUE)
..()
if(istype(H))
+2 -1
View File
@@ -169,7 +169,7 @@
var/insertpos = rand(1, message_list.len - 1)
var/inserttext = message_list[insertpos]
if(!(copytext(inserttext, length(inserttext) - 2) == "..."))
if(!(copytext(inserttext, -3) == "..."))//3 == length("...")
message_list[insertpos] = inserttext + "..."
if(prob(20) && message_list.len > 3)
@@ -248,6 +248,7 @@
name = "robotic voicebox"
desc = "A voice synthesizer that can interface with organic lifeforms."
status = ORGAN_ROBOTIC
organ_flags = NONE
icon_state = "tonguerobot"
say_mod = "states"
attack_verb = list("beeped", "booped")
+10 -8
View File
@@ -78,8 +78,10 @@
return FALSE
if(!owner)
return FALSE
if(!owner.can_speak())
return FALSE
if(isliving(owner))
var/mob/living/L = owner
if(!L.can_speak_vocal())
return FALSE
if(check_flags & AB_CHECK_CONSCIOUS)
if(owner.stat)
return FALSE
@@ -104,7 +106,7 @@
return FALSE
if(!owner)
return FALSE
if(!owner.can_speak())
if(!owner.can_speak_vocal())
to_chat(owner, "<span class='warning'>You are unable to speak!</span>")
return FALSE
return TRUE
@@ -184,19 +186,19 @@
listeners = list(L) //Devil names are unique.
power_multiplier *= 5 //if you're a devil and god himself addressed you, you fucked up
//Cut out the name so it doesn't trigger commands
message = copytext(message, 0, start)+copytext(message, start + length(devilinfo.truename), length(message) + 1)
message = copytext(message, 1, start) + copytext(message, start + length(devilinfo.truename))
break
else if(dd_hasprefix(message, L.real_name))
else if(findtext(message, L.real_name, 1, length(L.real_name) + 1))
specific_listeners += L //focus on those with the specified name
//Cut out the name so it doesn't trigger commands
found_string = L.real_name
else if(dd_hasprefix(message, L.first_name()))
else if(findtext(message, L.first_name(), 1, length(L.first_name()) + 1))
specific_listeners += L //focus on those with the specified name
//Cut out the name so it doesn't trigger commands
found_string = L.first_name()
else if(L.mind && L.mind.assigned_role && dd_hasprefix(message, L.mind.assigned_role))
else if(L.mind && L.mind.assigned_role && findtext(message, L.mind.assigned_role, 1, length(L.mind.assigned_role) + 1))
specific_listeners += L //focus on those with the specified job
//Cut out the job so it doesn't trigger commands
found_string = L.mind.assigned_role
@@ -204,7 +206,7 @@
if(specific_listeners.len)
listeners = specific_listeners
power_multiplier *= (1 + (1/specific_listeners.len)) //2x on a single guy, 1.5x on two and so on
message = copytext(message, 0, 1)+copytext(message, 1 + length(found_string), length(message) + 1)
message = copytext(message, length(found_string) + 1)
var/static/regex/stun_words = regex("stop|wait|stand still|hold on|halt")
var/static/regex/knockdown_words = regex("drop|fall|trip|knockdown")
+3 -2
View File
@@ -8,6 +8,7 @@
name = "reshape face"
implements = list(TOOL_SCALPEL = 100, /obj/item/kitchen/knife = 50, TOOL_WIRECUTTER = 35)
time = 64
experience_given = 5
/datum/surgery_step/reshape_face/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
user.visible_message("<span class='notice'>[user] begins to alter [target]'s appearance.</span>", "<span class='notice'>You begin to alter [target]'s appearance...</span>")
@@ -15,7 +16,7 @@
"<span class='notice'>[user] begins to alter [target]'s appearance.</span>",
"<span class='notice'>[user] begins to make an incision in [target]'s face.</span>")
/datum/surgery_step/reshape_face/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
/datum/surgery_step/reshape_face/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
if(HAS_TRAIT_FROM(target, TRAIT_DISFIGURED, TRAIT_GENERIC))
REMOVE_TRAIT(target, TRAIT_DISFIGURED, TRAIT_GENERIC)
display_results(user, target, "<span class='notice'>You successfully restore [target]'s appearance.</span>",
@@ -42,7 +43,7 @@
if(ishuman(target))
var/mob/living/carbon/human/H = target
H.sec_hud_set_ID()
return ..(default_display_results = FALSE)
return ..()
/datum/surgery_step/reshape_face/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, leaving [target]'s appearance disfigured!</span>",
@@ -19,6 +19,7 @@
name = "add prosthetic"
implements = list(/obj/item/bodypart = 100, /obj/item/organ_storage = 100, /obj/item/twohanded/required/chainsaw = 100, /obj/item/melee/synthetic_arm_blade = 100)
time = 32
experience_given = 5 //won't get full XP if rejected
var/organ_rejection_dam = 0
/datum/surgery_step/add_prosthetic/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -62,8 +63,8 @@
to_chat(user, "<span class='warning'>[tool] must be installed onto an arm.</span>")
return -1
/datum/surgery_step/add_prosthetic/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
. = ..(default_display_results = FALSE)
/datum/surgery_step/add_prosthetic/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
. = ..()
if(istype(tool, /obj/item/organ_storage))
tool.icon_state = initial(tool.icon_state)
tool.desc = initial(tool.desc)
@@ -74,6 +75,7 @@
L.attach_limb(target)
if(organ_rejection_dam)
target.adjustToxLoss(organ_rejection_dam)
experience_given -= (round(organ_rejection_dam/10))
display_results(user, target, "<span class='notice'>You succeed in replacing [target]'s [parse_zone(target_zone)].</span>",
"<span class='notice'>[user] successfully replaces [target]'s [parse_zone(target_zone)] with [tool]!</span>",
"<span class='notice'>[user] successfully replaces [target]'s [parse_zone(target_zone)]!</span>")
@@ -8,6 +8,7 @@
name = "remove embedded objects"
time = 32
accept_hand = 1
experience_given = 5
var/obj/item/bodypart/L = null
@@ -22,7 +23,7 @@
user.visible_message("<span class='notice'>[user] looks for [target]'s [parse_zone(user.zone_selected)].</span>", "<span class='notice'>You look for [target]'s [parse_zone(user.zone_selected)]...</span>")
/datum/surgery_step/remove_object/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
/datum/surgery_step/remove_object/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
if(L)
if(ishuman(target))
var/mob/living/carbon/human/H = target
@@ -45,4 +46,4 @@
else
to_chat(user, "<span class='warning'>You can't find [target]'s [parse_zone(user.zone_selected)], let alone any objects embedded in it!</span>")
return ..(default_display_results = FALSE)
return ..()
+53
View File
@@ -0,0 +1,53 @@
/datum/surgery/stomach_pump
name = "Stomach Pump"
steps = list(/datum/surgery_step/incise,
/datum/surgery_step/retract_skin,
/datum/surgery_step/incise,
/datum/surgery_step/clamp_bleeders,
/datum/surgery_step/stomach_pump,
/datum/surgery_step/close)
target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
possible_locs = list(BODY_ZONE_CHEST)
requires_bodypart_type = TRUE
ignore_clothes = FALSE
/datum/surgery/stomach_pump/can_start(mob/user, mob/living/carbon/target)
var/obj/item/organ/stomach/S = target.getorganslot(ORGAN_SLOT_STOMACH)
if(target.stat != DEAD) //shamelessly lifted off the revival surgery but we're looking for the same critera here, a dead, non-husked, revivable patient.
return FALSE
if(HAS_TRAIT(target, TRAIT_HUSK))
return FALSE
if(!S)
return FALSE
return ..()
//Working the stomach by hand in such a way that you induce vomiting.
/datum/surgery_step/stomach_pump
name = "Pump Stomach"
accept_hand = TRUE
repeatable = TRUE
time = 20
/datum/surgery_step/stomach_pump/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "<span class='notice'>You begin pumping [target]'s stomach...</span>",
"<span class='notice'>[user] begins to pump [target]'s stomach.</span>",
"<span class='notice'>[user] begins to press on [target]'s chest.</span>")
/datum/surgery_step/stomach_pump/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
if(ishuman(target))
var/mob/living/carbon/human/H = target
display_results(user, target, "<span class='notice'>[user] forces [H] to vomit, cleansing their stomach of some chemicals!</span>",
"<span class='notice'>[user] forces [H] to vomit, cleansing their stomach of some chemicals!</span>",
"[user] forces [H] to vomit!")
H.vomit(20, FALSE, TRUE, 1, TRUE, FALSE, purge = TRUE) //called with purge as true to lose more reagents
return ..()
/datum/surgery_step/stomach_pump/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
if(ishuman(target))
var/mob/living/carbon/human/H = target
display_results(user, target, "<span class='warning'>You screw up, brusing [H]'s chest!</span>",
"<span class='warning'>[user] screws up, brusing [H]'s chest!</span>",
"<span class='warning'>[user] screws up!</span>")
H.adjustOrganLoss(ORGAN_SLOT_STOMACH, 5)
H.adjustBruteLoss(5)
+1 -1
View File
@@ -79,7 +79,7 @@
if(!opcomputer)
return
if(opcomputer.stat & (NOPOWER|BROKEN))
if(opcomputer.machine_stat & (NOPOWER|BROKEN))
return .
if(replaced_by in opcomputer.advanced_surgeries)
return FALSE
+22 -10
View File
@@ -83,27 +83,39 @@
/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("<span class='notice'>[user] removes [I] from [M]'s [parse_zone(selected_zone)].</span>", \
"<span class='notice'>You remove [I] from [M]'s [parse_zone(selected_zone)].</span>")
qdel(S)
else if(S.can_cancel)
return
if(S.can_cancel)
var/required_tool_type = TOOL_CAUTERY
var/obj/item/close_tool = user.get_inactive_held_item()
var/is_robotic = S.requires_bodypart_type == BODYPART_ROBOTIC
if(is_robotic)
required_tool_type = TOOL_SCREWDRIVER
if(close_tool && close_tool.tool_behaviour == required_tool_type || iscyborg(user))
if (ishuman(M))
var/mob/living/carbon/human/H = M
H.bleed_rate = max( (H.bleed_rate - 3), 0)
M.surgeries -= S
user.visible_message("<span class='notice'>[user] closes [M]'s [parse_zone(selected_zone)] with [close_tool] and removes [I].</span>", \
"<span class='notice'>You close [M]'s [parse_zone(selected_zone)] with [close_tool] and remove [I].</span>")
qdel(S)
else
if(iscyborg(user))
close_tool = locate(/obj/item/cautery) in user.held_items
if(!close_tool)
to_chat(user, "<span class='warning'>You need to equip a cautery in an inactive slot to stop [M]'s surgery!</span>")
return
else if(!close_tool || close_tool.tool_behaviour != required_tool_type)
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>")
return
if(ishuman(M))
var/mob/living/carbon/human/H = M
H.bleed_rate = max( (H.bleed_rate - 3), 0)
M.surgeries -= S
user.visible_message("<span class='notice'>[user] closes [M]'s [parse_zone(selected_zone)] with [close_tool] and removes [I].</span>", \
"<span class='notice'>You close [M]'s [parse_zone(selected_zone)] with [close_tool] and remove [I].</span>")
qdel(S)
/proc/get_location_modifier(mob/M)
var/turf/T = get_turf(M)
+4 -4
View File
@@ -9,6 +9,7 @@
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
/// The amount of a experience given for successfully completing the step.
var/experience_given = 1
/datum/surgery_step/proc/try_op(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
@@ -77,7 +78,7 @@
implement_speed_mod = implements[implement_type] / 100.0
speed_mod /= (get_location_modifier(target) * (1 + surgery.speed_modifier) * implement_speed_mod)
var/modded_time = time * speed_mod * user.mind.get_skill_speed_modifier(/datum/skill/medical)
var/modded_time = time * speed_mod * user.mind.get_skill_modifier(/datum/skill/medical, SKILL_SPEED_MODIFIER)
fail_prob = min(max(0, modded_time - (time * SURGERY_SLOWDOWN_CAP_MULTIPLIER)),99)//if modded_time > time * modifier, then fail_prob = modded_time - time*modifier. starts at 0, caps at 99
@@ -99,8 +100,7 @@
if(failure(user, target, target_zone, tool, surgery, fail_prob))
advance = TRUE
if(chem_check_result)
if(.(user, target, target_zone, tool, surgery, try_to_fail)) //automatically re-attempt if failed for reason other than lack of required chemical
advance = TRUE
return .(user, target, target_zone, tool, surgery, try_to_fail) //automatically re-attempt if failed for reason other than lack of required chemical
if(advance && !repeatable)
surgery.status++
if(surgery.status > surgery.steps.len)
@@ -122,7 +122,7 @@
display_results(user, target, "<span class='notice'>You succeed.</span>",
"<span class='notice'>[user] succeeds!</span>",
"<span class='notice'>[user] finishes.</span>")
user?.mind.adjust_experience(/datum/skill/medical, experience_given)
user?.mind.adjust_experience(/datum/skill/medical, round(experience_given))
return TRUE
/datum/surgery_step/proc/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, var/fail_prob = 0)
+70
View File
@@ -330,3 +330,73 @@
/obj/item/surgicaldrill/advanced/examine()
. = ..()
. += " It's set to [tool_behaviour == TOOL_DRILL ? "drilling" : "mending"] mode."
/obj/item/shears
name = "amputation shears"
desc = "A type of heavy duty surgical shears used for achieving a clean separation between limb and patient. Keeping the patient still is imperative to be able to secure and align the shears."
icon = 'icons/obj/surgery.dmi'
icon_state = "shears"
flags_1 = CONDUCT_1
item_flags = SURGICAL_TOOL
toolspeed = 1
force = 12
w_class = WEIGHT_CLASS_NORMAL
throwforce = 6
throw_speed = 2
throw_range = 5
custom_materials = list(/datum/material/iron=8000, /datum/material/titanium=6000)
attack_verb = list("sheared", "snipped")
sharpness = IS_SHARP
custom_premium_price = 1800
/obj/item/shears/attack(mob/living/M, mob/user)
if(!iscarbon(M) || user.a_intent != INTENT_HELP)
return ..()
if(user.zone_selected == BODY_ZONE_CHEST)
return ..()
var/mob/living/carbon/patient = M
if(HAS_TRAIT(patient, TRAIT_NODISMEMBER))
to_chat(user, "<span class='warning'>The patient's limbs look too sturdy to amputate.</span>")
return
var/candidate_name
var/obj/item/organ/tail_snip_candidate
var/obj/item/bodypart/limb_snip_candidate
if(user.zone_selected == BODY_ZONE_PRECISE_GROIN)
tail_snip_candidate = patient.getorganslot(ORGAN_SLOT_TAIL)
if(!tail_snip_candidate)
to_chat(user, "<span class='warning'>[patient] does not have a tail.</span>")
return
candidate_name = tail_snip_candidate.name
else
limb_snip_candidate = patient.get_bodypart(check_zone(user.zone_selected))
if(!limb_snip_candidate)
to_chat(user, "<span class='warning'>[patient] is already missing that limb, what more do you want?</span>")
return
candidate_name = limb_snip_candidate.name
var/amputation_speed_mod
patient.visible_message("<span class='danger'>[user] begins to secure [src] around [patient]'s [candidate_name].</span>", "<span class='userdanger'>[user] begins to secure [src] around your [candidate_name]!</span>")
playsound(get_turf(patient), 'sound/items/ratchet.ogg', 20, TRUE)
if(patient.stat == DEAD || patient.stat == UNCONSCIOUS || patient.IsStun()) //Stun is used by paralytics like curare it should not be confused with the more common paralyze.
amputation_speed_mod = 0.5
else if(patient.jitteriness >= 1)
amputation_speed_mod = 1.5
else
amputation_speed_mod = 1
if(do_after(user, toolspeed * 150 * amputation_speed_mod, target = patient))
playsound(get_turf(patient), 'sound/weapons/bladeslice.ogg', 250, TRUE)
if(user.zone_selected == BODY_ZONE_PRECISE_GROIN) //OwO
tail_snip_candidate.Remove(patient)
tail_snip_candidate.forceMove(get_turf(patient))
else
limb_snip_candidate.dismember()
user.visible_message("<span class='danger'>[src] violently slams shut, amputating [patient]'s [candidate_name].</span>", "<span class='notice'>You amputate [patient]'s [candidate_name] with [src].</span>")