[MIRROR] Amputation Repair, Surgery adjustments, and amputation vision. (#12475)

Co-authored-by: Cameron Lennox <killer65311@gmail.com>
This commit is contained in:
CHOMPStation2StaffMirrorBot
2026-02-28 04:50:24 -05:00
committed by GitHub
co-authored by Cameron Lennox
parent de8b0c830b
commit 0b9b1617ad
31 changed files with 807 additions and 539 deletions
+1 -1
View File
@@ -30,7 +30,7 @@
var/aug_cooldown = 1 SECONDS //CHOMPedit, no reason for it to be 30 seconds, the powerful implants already have their own values
var/cooldown = null
description_fluff = "If attempting to implant a compatible augment into a synthetic limb, the limb must be screwdrivered open and then modified with a multitool before insertion can begin."
description_fluff = "If attempting to implant a compatible augment into a synthetic limb, the limb must be screwdrivered open and then the augment port opened with a crowbar before insertion can begin."
/obj/item/organ/internal/augment/Initialize(mapload)
. = ..()
+64 -9
View File
@@ -185,9 +185,7 @@ var/list/organ_cache = list()
if(CONFIG_GET(flag/organs_decay) && decays) damage += rand(1,3)
if(damage >= max_damage)
damage = max_damage
adjust_germ_level(rand(2,6))
if(germ_level >= INFECTION_LEVEL_TWO)
adjust_germ_level(rand(2,6))
adjust_germ_level(1) //If something knocked a limb off, usually it'll have 100ish germs. This means you have ~30 minutes to get it back on before it becomes necrotic.
if(germ_level >= INFECTION_LEVEL_THREE)
die()
@@ -199,8 +197,43 @@ var/list/organ_cache = list()
/obj/item/organ/examine(mob/user)
. = ..()
//Descriptors for 'status of the limb'
if(status & ORGAN_DEAD) //Can happen for other reasons than infection.
. += span_bolddanger("The [name] is dead.")
if(status & ORGAN_MUTATED)
. += span_danger("The [name] is mutated and deformed.")
if(status & ORGAN_BROKEN)
. += span_danger("The [name] is broken.")
//Descriptors for 'how infected is this organ'
if(germ_level < INFECTION_LEVEL_ONE)
return
switch(germ_level)
if(INFECTION_LEVEL_ONE to INFECTION_LEVEL_TWO - 1)
. += span_warning("Signs of a minor infection are apparent.")
if(INFECTION_LEVEL_TWO to INFECTION_LEVEL_THREE - 1)
. += span_boldwarning("Signs of a moderate infection are apparent.")
if(INFECTION_LEVEL_THREE to INFINITY)
. += span_bolddanger("Necrosis has set in.")
/obj/item/organ/get_description_info(list/additional_information)
if(!additional_information)
additional_information = list()
if(butcherable && meat_type)
additional_information += "Can be butchered with use of any sharp and edged object."
if(germ_level)
additional_information += "Can be washed in a sink, shower, or sprayed with space cleaner to clean infection. This will not bring it back from death, however."
if(status & ORGAN_DEAD)
. += span_notice("Decay appears to have set in.")
additional_information += "Can have five units of peridaxon applied to bring the organ back from death. This will not cure any infection, however."
. = ..(additional_information)
return .
/obj/item/organ/get_description_antag()
. = ..()
if(butcherable && meat_type)
. += "Can be butchered with use of any sharp and edged object, allowing for quick disposal of evidence."
return .
//A little wonky: internal organs stop calling this (they return early in process) when dead, but external ones cause further damage when dead
/obj/item/organ/proc/handle_germ_effects()
@@ -498,11 +531,20 @@ var/list/organ_cache = list()
bitten(user)
return
/obj/item/organ/attackby(obj/item/W as obj, mob/user as mob)
/obj/item/organ/attackby(obj/item/W, mob/user)
if(can_butcher(W, user))
butcher(W, user)
return
var/obj/item/reagent_containers/container = W
if(istype(container))
if(container.reagents.has_reagent(REAGENT_ID_PERIDAXON, 5))
status &= ~ORGAN_DEAD
damage-- //Fix JUST enough damage so it doesn't immediately die again. For full repair, use denec removal surgery.
START_PROCESSING(SSobj, src) //When an organ dies, it stops processing. This restarts it.
container.reagents.remove_reagent(REAGENT_ID_PERIDAXON, 5)
to_chat(user, "You use the [container] to revive \the [src]")
return
return ..()
/obj/item/organ/proc/can_butcher(var/obj/item/O, var/mob/living/user)
@@ -522,11 +564,20 @@ var/list/organ_cache = list()
return FALSE
/obj/item/organ/proc/butcher(var/obj/item/O, var/mob/living/user, var/atom/newtarget)
if(robotic >= ORGAN_ROBOT)
user?.visible_message(span_notice("[user] disassembles \the [src]."))
else
user?.visible_message(span_notice("[user] butchers \the [src]."))
if(user)
to_chat(user, span_danger("You are preparing to butcher \the [src]!"))
user.visible_message(span_danger("[user] prepares to butcher \the [src]!"))
if(!do_after(user, 10 SECONDS * O.toolspeed, target = src)) //They can queue this up on multiple organs.
to_chat(user, span_notice("You reconsider butchering \the [src]..."))
user.visible_message(span_notice("[user] reconsiders butchering \the [src]!"))
return FALSE
if(robotic >= ORGAN_ROBOT)
user?.visible_message(span_warning("[user] disassembles \the [src]."))
else
user?.visible_message(span_warning("[user] butchers \the [src]."))
if(!newtarget)
newtarget = get_turf(src)
@@ -536,6 +587,10 @@ var/list/organ_cache = list()
if(istype(newmeat, /obj/item/reagent_containers/food/snacks/meat))
newmeat.name = "[src.name] [newmeat.name]" // "liver meat" "heart meat", etc.
if(LAZYLEN(contents)) //You can't shove the nuke disk into a leg and then butcher the leg to delete the nuke disk.
for(var/obj/contained_object in contents)
contained_object.forceMove(newtarget)
qdel(src)
/obj/item/organ/proc/organ_can_feel_pain()
+86 -5
View File
@@ -173,15 +173,67 @@
return //no eating the limb until everything's been removed
return ..(user, TRUE)
/obj/item/organ/external/get_description_info(list/additional_information)
if(!additional_information)
additional_information = list()
switch(stage)
if(0)
additional_information += "Can be cut open via a scalpel to perform procedures on it."
if(1)
additional_information += "The [name] is cut open and can be opened further with a retractor or closed with a cautery."
if(2)
additional_information += "The [name] is fully open, allowing for removal of anything within or attached via a hemostat. It can also be partially closed with fix-o-vein."
if(status & ORGAN_DEAD)
additional_information += "Can have necrosis partially removed by use of a scalpel."
if(3) //Status only happens if we used a scalpel on stage 2.
additional_information += "The [name] is fully open with some necrotic tissue removed. The use of a bioregenerator can fully remove infection and necrosis from the limb."
if(status & ORGAN_DEAD)
additional_information += "Can have necrosis and infection surgically removed."
. = ..(additional_information)
return .
/obj/item/organ/external/examine(mob/user)
. = ..()
if(in_range(user, src) || isobserver(user))
for(var/obj/item/I in contents)
if(istype(I, /obj/item/organ))
//Handling attached limbs, like the foot on a leg.
if(istype(I, /obj/item/organ/external))
var/obj/item/organ/external/child_organ = I
. += span_notice("There is [child_organ.name] attached to it.")
//Handling status on attached limbs.
if(child_organ.status & ORGAN_DEAD) //Can happen for other reasons than infection.
. += span_bolddanger("The attached [child_organ.name] is dead.")
if(child_organ.status & ORGAN_MUTATED)
. += span_danger("The attached [child_organ.name] is mutated and deformed.")
if(child_organ.status & ORGAN_BROKEN)
. += span_danger("The attached [child_organ.name] is broken.")
//Handling infections on attached limbs.
if(child_organ.germ_level < INFECTION_LEVEL_ONE)
continue
switch(child_organ.germ_level)
if(INFECTION_LEVEL_ONE to INFECTION_LEVEL_TWO - 1)
. += span_warning("The attached [child_organ.name] has signs of a minor infection.")
if(INFECTION_LEVEL_TWO to INFECTION_LEVEL_THREE - 1)
. += span_boldwarning("The attached [child_organ.name] has signs of a moderate infection.")
if(INFECTION_LEVEL_THREE to INFINITY)
. += span_bolddanger("The attached [child_organ.name] is necrotic.")
continue
if(istype(I, /obj/item/organ)) //We can't see inside the organ if it has an organ in it.
continue
. += span_danger("There is \a [I] sticking out of it.")
if(stage)
switch(stage)
if(1)
. += span_danger("The [name] is surgically cut open.")
if(2)
. += span_danger("The [name] is cut open and the skin retracted.")
/obj/item/organ/external/attackby(obj/item/W as obj, mob/living/user as mob)
/obj/item/organ/external/attackby(obj/item/W, mob/living/user)
switch(stage)
if(0)
if(istype(W,/obj/item/surgical/scalpel))
@@ -193,16 +245,44 @@
user.visible_message(span_danger(span_bold("[user]") + " cracks [src] open like an egg with [W]!"))
stage++
return
if(istype(W,/obj/item/surgical/cautery))
user.visible_message(span_danger(span_bold("[user]") + " closes [src] with [W]!"))
stage--
return
if(2)
if(istype(W,/obj/item/surgical/hemostat))
if(contents.len)
var/obj/item/removing = pick(contents)
if(LAZYLEN(contents))
var/obj/item/removing = tgui_input_list(user, "What would you like to remove?", "Extraction", contents, timeout = 20 SECONDS)
if(!removing || removing.loc != src || !Adjacent(user)) //Didn't select anything or selected something that was already removed OR we walked away.
user.visible_message(span_danger(span_bold("[user]") + " decides against removing anything from [src]"))
return
removing.loc = get_turf(user.loc)
user.put_in_hands(removing)
user.visible_message(span_danger(span_bold("[user]") + " extracts [removing] from [src] with [W]!"))
else
user.visible_message(span_danger(span_bold("[user]") + " fishes around fruitlessly in [src] with [W]."))
return
if(istype(W,/obj/item/surgical/FixOVein))
user.visible_message(span_danger(span_bold("[user]") + " partially closes [src] with [W]!"))
stage--
return
//Begin necrosis surgery
if(istype(W,/obj/item/surgical/scalpel))
if(!(status & ORGAN_DEAD))
to_chat(user, span_notice("The limb isn't necrotic, there's no need to fix it!"))
return
user.visible_message(span_danger(span_bold("[user]") + " cuts necrotic tissue off [src] with [W]!"))
stage++
return
if(3)
if(istype(W,/obj/item/surgical/bioregen))
user.visible_message(span_danger(span_bold("[user]") + " rejuvinates formerly necrotic tissue on [src] with [W]!"))
germ_level = 0
status &= ~ORGAN_DEAD
damage = 0 //Fix the damage on it as well.
START_PROCESSING(SSobj, src) //Dead limbs stop processing, so we restart the process.
stage-- //Go back to stage 2
return
..()
/obj/item/organ/external/proc/is_dislocated()
@@ -243,7 +323,8 @@
dislocated = 0
if(istype(owner))
owner.shock_stage += 20
if(!organ_can_feel_pain())
owner.shock_stage += 20
//check to see if we still need the verb
for(var/obj/item/organ/external/limb in owner.organs)
+1 -1
View File
@@ -375,7 +375,7 @@
/datum/wound/lost_limb/New(var/obj/item/organ/external/lost_limb, var/losstype, var/clean)
var/damage_amt = lost_limb.max_damage
if(clean) damage_amt /= 2
if(clean) damage_amt *= 0.25
switch(losstype)
if(DROPLIMB_EDGE, DROPLIMB_BLUNT)