mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-21 20:20:33 +01:00
<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may not be viewable. --> <!-- You can view Contributing.MD for a detailed description of the pull request process. --> ## About The Pull Request ### Cybernetic variant surgeries Many of the surgeries able to be performed on organic limbs now have a version for robotic limbs. This includes; ### NONE OF THESE ARE SELF SURGERY OPTIONS - Organ repair surgeries - Stomach Pumps - Blood filtering - Autopsies - Lobotomies - Pacification - Lipoplasty - Amputation - Brainwashing (including the Sleeper Agent protocol) - Nerve Splicing and Nerve Grounding - Vein Threading and Vein Muscle Membrane - Ligament Hook and Ligament Reinforcement - Cortex Folding and Cortex Imprint These utilize mechanical steps and unique versions of their special step that uses mechanical tools. But many of these are able to be performed using standard surgery tools. In fact, I've improved the chances for doing surgery using standard tools for mechanical steps, recognizing that medical is often going to end up with synths in medbay whether we like it or not. ### NONE OF THESE ARE SELF SURGERY OPTIONS ### Organ Repair Surgeries correct EMP Failure Cascades When you repair a synthetic organ using the organ repair surgery, it reverses the effects of organ failure from an EMP. That is, the permanent failure of an organ. This allows for an alternative method to replacing that organ wholesale, which makes treating synths a lot easier for medical and EMPs less of a RNG death knell for people with cybernetic organs. However, it still needs the surgery to correct the error, so this isn't removing the danger of being EMP'd. ### Health Scanners report EMP Failure Cascades Scanning someone with a cybernetic organ now actually tells you that the organ is failing. Wow, why wasn't this already the case? ## Why It's Good For The Game #### Surgeries With the new techweb changes, augmented crew are becoming a lot, lot more common place, as are the implantation of cybernetics. These are required for research to be able to progress both medical and robotics technology. Therefore, those using these items are becoming a lot more common place. However, our medical system is quite blind to these people as of the moment. A lot of surgeries that are critical to recovering the injured/dead do not work on them outright, and medical can't resolve the problems that come with cybernetic organs entirely. This change hopefully modernizes our surgeries to account for these synthetic/cybernetically-altered crew members that neither forces people to choose between taking them to medical or robotics (they're often going to end up in medical regardless), and letting either department to function as a place for these crew to obtain medical services. Also gives them some cooler flavour to their surgeries, which I think is the most important part of this change. It actually feels like you're more than human without getting too much in the way of gameplay loops and over complicating things. Edit: To provide a bit of extra clarity on 'Why allow the advanced surgeries?' You can actually have the benefits of the advanced surgeries as an augmented humanoid. The problem is that it has to take place before you are augmented. They're not mutually exclusive, just slow to apply. There isn't much reason for there not to be a method to apply them to robotic people, particularly since augmentations are expected earlier in the round than advanced surgeries. #### EMP Failure and Detection This mechanic is probably what people hate the most about cybernetics. It is largely invisible, and forces you to have to go through a tedious process of organ replacement on what could be any one of your organs, since it wasn't being broadcast to the user which one is failing until you are possibly already doubling over. Now, it is easier for medical staff to identify if they have a cybernetically enhanced patient in the midst of a failure cascade, and have the means to resolve the problem. Robotics and cyborgs can too, since sometimes they'll have the means usually to do the same operations and detection. ## Changelog <!-- If your PR modifies aspects of the game that can be concretely observed by players or admins you should add a changelog. If your change does NOT meet this description, remove this section. Be sure to properly mark your PRs to prevent unnecessary GBP loss. You can read up on GBP and it's effects on PRs in the tgstation guides for contributors. Please note that maintainers freely reserve the right to remove and add tags should they deem it appropriate. You can attempt to finagle the system all you want, but it's best to shoot for clear communication right off the bat. --> 🆑 add: Robotic variants of many of the standard and advanced humanoid surgeries. You cannot perform self surgery with these surgeries. balance: It is easier to do robotic surgeries with normal surgery tools. qol: It is now possible to detect EMP organ failure cascades via health scanners. qol: EMP organ failure cascades can be reversed by doing organ repair surgeries targeting the failing organ. /🆑 <!-- Both 🆑's are required for the changelog to work! You can put your name to the right of the first 🆑 if you want to overwrite your GitHub username as author ingame. --> <!-- You can use multiple of the same prefix (they're only used for the icon ingame) and delete the unneeded ones. Despite some of the tags, changelogs should generally represent how a player might be affected by the changes rather than a summary of the PR's contents. --> --------- Co-authored-by: Jacquerel <hnevard@gmail.com>
317 lines
12 KiB
Plaintext
317 lines
12 KiB
Plaintext
/datum/surgery/organ_manipulation
|
|
name = "Organ manipulation"
|
|
surgery_flags = SURGERY_REQUIRE_RESTING | SURGERY_REQUIRE_LIMB | SURGERY_REQUIRES_REAL_LIMB | SURGERY_MORBID_CURIOSITY
|
|
possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD)
|
|
steps = list(
|
|
/datum/surgery_step/incise,
|
|
/datum/surgery_step/retract_skin,
|
|
/datum/surgery_step/saw,
|
|
/datum/surgery_step/clamp_bleeders,
|
|
/datum/surgery_step/incise,
|
|
/datum/surgery_step/manipulate_organs/internal,
|
|
/datum/surgery_step/close,
|
|
)
|
|
|
|
/datum/surgery/organ_manipulation/soft
|
|
possible_locs = list(BODY_ZONE_PRECISE_GROIN, BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)
|
|
steps = list(
|
|
/datum/surgery_step/incise,
|
|
/datum/surgery_step/retract_skin,
|
|
/datum/surgery_step/clamp_bleeders,
|
|
/datum/surgery_step/incise,
|
|
/datum/surgery_step/manipulate_organs/internal,
|
|
/datum/surgery_step/close,
|
|
)
|
|
|
|
/datum/surgery/organ_manipulation/external
|
|
name = "Feature manipulation"
|
|
possible_locs = list(
|
|
BODY_ZONE_CHEST,
|
|
BODY_ZONE_HEAD,
|
|
BODY_ZONE_PRECISE_GROIN,
|
|
BODY_ZONE_L_ARM,
|
|
BODY_ZONE_R_ARM,
|
|
BODY_ZONE_L_LEG,
|
|
BODY_ZONE_R_LEG,
|
|
)
|
|
steps = list(
|
|
/datum/surgery_step/incise,
|
|
/datum/surgery_step/retract_skin,
|
|
/datum/surgery_step/manipulate_organs/external,
|
|
/datum/surgery_step/close,
|
|
)
|
|
|
|
/datum/surgery/organ_manipulation/alien
|
|
name = "Alien organ manipulation"
|
|
possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD, BODY_ZONE_PRECISE_GROIN, BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)
|
|
target_mobtypes = list(/mob/living/carbon/alien/adult)
|
|
steps = list(
|
|
/datum/surgery_step/saw,
|
|
/datum/surgery_step/incise,
|
|
/datum/surgery_step/retract_skin,
|
|
/datum/surgery_step/saw,
|
|
/datum/surgery_step/manipulate_organs/internal,
|
|
/datum/surgery_step/close,
|
|
)
|
|
|
|
/datum/surgery/organ_manipulation/mechanic
|
|
name = "Hardware Manipulation"
|
|
requires_bodypart_type = BODYTYPE_ROBOTIC
|
|
surgery_flags = SURGERY_SELF_OPERABLE | SURGERY_REQUIRE_LIMB
|
|
possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD)
|
|
steps = list(
|
|
/datum/surgery_step/mechanic_open,
|
|
/datum/surgery_step/open_hatch,
|
|
/datum/surgery_step/mechanic_unwrench,
|
|
/datum/surgery_step/prepare_electronics,
|
|
/datum/surgery_step/manipulate_organs/internal/mechanic,
|
|
/datum/surgery_step/mechanic_wrench,
|
|
/datum/surgery_step/mechanic_close,
|
|
)
|
|
|
|
/datum/surgery/organ_manipulation/mechanic/next_step(mob/living/user, modifiers)
|
|
if(location != user.zone_selected)
|
|
return FALSE
|
|
if(user.combat_mode)
|
|
return FALSE
|
|
if(step_in_progress)
|
|
return TRUE
|
|
|
|
var/try_to_fail = FALSE
|
|
if(LAZYACCESS(modifiers, RIGHT_CLICK))
|
|
try_to_fail = TRUE
|
|
|
|
var/datum/surgery_step/step = get_surgery_step()
|
|
if(isnull(step))
|
|
return FALSE
|
|
var/obj/item/tool = user.get_active_held_item()
|
|
if(step.try_op(user, target, user.zone_selected, tool, src, try_to_fail))
|
|
return TRUE
|
|
if(tool && tool.tool_behaviour) //Mechanic organ manipulation isn't done with just surgery tools
|
|
to_chat(user, span_warning("This step requires a different tool!"))
|
|
return TRUE
|
|
|
|
return FALSE
|
|
|
|
/datum/surgery/organ_manipulation/mechanic/soft
|
|
possible_locs = list(
|
|
BODY_ZONE_PRECISE_GROIN,
|
|
BODY_ZONE_PRECISE_EYES,
|
|
BODY_ZONE_PRECISE_MOUTH,
|
|
BODY_ZONE_L_ARM,
|
|
BODY_ZONE_R_ARM,
|
|
)
|
|
steps = list(
|
|
/datum/surgery_step/mechanic_open,
|
|
/datum/surgery_step/open_hatch,
|
|
/datum/surgery_step/prepare_electronics,
|
|
/datum/surgery_step/manipulate_organs/internal/mechanic,
|
|
/datum/surgery_step/mechanic_close,
|
|
)
|
|
|
|
/datum/surgery/organ_manipulation/mechanic/external
|
|
name = "Chassis Manipulation"
|
|
possible_locs = list(
|
|
BODY_ZONE_CHEST,
|
|
BODY_ZONE_HEAD,
|
|
BODY_ZONE_PRECISE_GROIN,
|
|
BODY_ZONE_L_ARM,
|
|
BODY_ZONE_R_ARM,
|
|
BODY_ZONE_L_LEG,
|
|
BODY_ZONE_R_LEG,
|
|
)
|
|
steps = list( //not shorter than soft prosthetic manip because I dunno what steps could be cut here
|
|
/datum/surgery_step/mechanic_open,
|
|
/datum/surgery_step/open_hatch,
|
|
/datum/surgery_step/prepare_electronics,
|
|
/datum/surgery_step/manipulate_organs/external/mechanic,
|
|
/datum/surgery_step/mechanic_close,
|
|
)
|
|
|
|
///Organ manipulation base class. Do not use, it wont work. Use its subtypes
|
|
/datum/surgery_step/manipulate_organs
|
|
name = "manipulate organs"
|
|
repeatable = TRUE
|
|
implements = list(
|
|
/obj/item/organ = 100,
|
|
/obj/item/borg/apparatus/organ_storage = 100)
|
|
preop_sound = 'sound/surgery/organ2.ogg'
|
|
success_sound = 'sound/surgery/organ1.ogg'
|
|
|
|
var/implements_extract = list(TOOL_HEMOSTAT = 100, TOOL_CROWBAR = 55, /obj/item/kitchen/fork = 35)
|
|
var/current_type
|
|
var/obj/item/organ/target_organ
|
|
|
|
/datum/surgery_step/manipulate_organs/New()
|
|
..()
|
|
implements = implements + implements_extract
|
|
|
|
/datum/surgery_step/manipulate_organs/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
|
target_organ = null
|
|
if(istype(tool, /obj/item/borg/apparatus/organ_storage))
|
|
preop_sound = initial(preop_sound)
|
|
success_sound = initial(success_sound)
|
|
if(!length(tool.contents))
|
|
to_chat(user, span_warning("There is nothing inside [tool]!"))
|
|
return SURGERY_STEP_FAIL
|
|
target_organ = tool.contents[1]
|
|
if(!isorgan(target_organ))
|
|
if (target_zone == BODY_ZONE_PRECISE_EYES)
|
|
target_zone = check_zone(target_zone)
|
|
to_chat(user, span_warning("You cannot put [target_organ] into [target]'s [target.parse_zone_with_bodypart(target_zone)]!"))
|
|
return SURGERY_STEP_FAIL
|
|
tool = target_organ
|
|
if(isorgan(tool))
|
|
current_type = "insert"
|
|
preop_sound = 'sound/surgery/hemostat1.ogg'
|
|
success_sound = 'sound/surgery/organ2.ogg'
|
|
target_organ = tool
|
|
if(target_zone != target_organ.zone || target.get_organ_slot(target_organ.slot))
|
|
to_chat(user, span_warning("There is no room for [target_organ] in [target]'s [target.parse_zone_with_bodypart(target_zone)]!"))
|
|
return SURGERY_STEP_FAIL
|
|
var/obj/item/organ/meatslab = tool
|
|
if(!meatslab.useable)
|
|
to_chat(user, span_warning("[target_organ] seems to have been chewed on, you can't use this!"))
|
|
return SURGERY_STEP_FAIL
|
|
|
|
if(!can_use_organ(user, meatslab))
|
|
return SURGERY_STEP_FAIL
|
|
|
|
if (target_zone == BODY_ZONE_PRECISE_EYES)
|
|
target_zone = check_zone(target_zone)
|
|
display_results(
|
|
user,
|
|
target,
|
|
span_notice("You begin to insert [tool] into [target]'s [target.parse_zone_with_bodypart(target_zone)]..."),
|
|
span_notice("[user] begins to insert [tool] into [target]'s [target.parse_zone_with_bodypart(target_zone)]."),
|
|
span_notice("[user] begins to insert something into [target]'s [target.parse_zone_with_bodypart(target_zone)]."),
|
|
)
|
|
display_pain(target, "You can feel something being placed in your [target.parse_zone_with_bodypart(target_zone)]!")
|
|
|
|
|
|
else if(implement_type in implements_extract)
|
|
current_type = "extract"
|
|
var/list/unfiltered_organs = target.get_organs_for_zone(target_zone)
|
|
var/list/organs = list()
|
|
for(var/organ in unfiltered_organs)
|
|
if(can_use_organ(user, organ))
|
|
organs.Add(organ)
|
|
if (target_zone == BODY_ZONE_PRECISE_EYES)
|
|
target_zone = check_zone(target_zone)
|
|
if(!length(organs))
|
|
to_chat(user, span_warning("There are no removable organs in [target]'s [target.parse_zone_with_bodypart(target_zone)]!"))
|
|
return SURGERY_STEP_FAIL
|
|
else
|
|
for(var/obj/item/organ/organ in organs)
|
|
organ.on_find(user)
|
|
organs -= organ
|
|
organs[organ.name] = organ
|
|
|
|
var/chosen_organ = tgui_input_list(user, "Remove which organ?", "Surgery", sort_list(organs))
|
|
if(isnull(chosen_organ))
|
|
return SURGERY_STEP_FAIL
|
|
target_organ = chosen_organ
|
|
if(user && target && user.Adjacent(target) && user.get_active_held_item() == tool)
|
|
target_organ = organs[target_organ]
|
|
if(!target_organ)
|
|
return SURGERY_STEP_FAIL
|
|
if(target_organ.organ_flags & ORGAN_UNREMOVABLE)
|
|
to_chat(user, span_warning("[target_organ] is too well connected to take out!"))
|
|
return SURGERY_STEP_FAIL
|
|
display_results(
|
|
user,
|
|
target,
|
|
span_notice("You begin to extract [target_organ] from [target]'s [target.parse_zone_with_bodypart(target_zone)]..."),
|
|
span_notice("[user] begins to extract [target_organ] from [target]'s [target.parse_zone_with_bodypart(target_zone)]."),
|
|
span_notice("[user] begins to extract something from [target]'s [target.parse_zone_with_bodypart(target_zone)]."),
|
|
)
|
|
display_pain(target, "You can feel your [target_organ.name] being removed from your [target.parse_zone_with_bodypart(target_zone)]!")
|
|
else
|
|
return SURGERY_STEP_FAIL
|
|
|
|
/datum/surgery_step/manipulate_organs/success(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
|
|
if (target_zone == BODY_ZONE_PRECISE_EYES)
|
|
target_zone = check_zone(target_zone)
|
|
if(current_type == "insert")
|
|
var/obj/item/apparatus
|
|
if(istype(tool, /obj/item/borg/apparatus/organ_storage))
|
|
apparatus = tool
|
|
tool = tool.contents[1]
|
|
target_organ = tool
|
|
user.temporarilyRemoveItemFromInventory(target_organ, TRUE)
|
|
if(target_organ.Insert(target))
|
|
if(apparatus)
|
|
apparatus.icon_state = initial(apparatus.icon_state)
|
|
apparatus.desc = initial(apparatus.desc)
|
|
apparatus.cut_overlays()
|
|
display_results(
|
|
user,
|
|
target,
|
|
span_notice("You insert [tool] into [target]'s [target.parse_zone_with_bodypart(target_zone)]."),
|
|
span_notice("[user] inserts [tool] into [target]'s [target.parse_zone_with_bodypart(target_zone)]!"),
|
|
span_notice("[user] inserts something into [target]'s [target.parse_zone_with_bodypart(target_zone)]!"),
|
|
)
|
|
display_pain(target, "Your [target.parse_zone_with_bodypart(target_zone)] throbs with pain as your new [tool.name] comes to life!")
|
|
target_organ.on_surgical_insertion(user, target, target_zone, tool)
|
|
else
|
|
target_organ.forceMove(target.loc)
|
|
|
|
else if(current_type == "extract")
|
|
if(target_organ && target_organ.owner == target)
|
|
display_results(
|
|
user,
|
|
target,
|
|
span_notice("You successfully extract [target_organ] from [target]'s [target.parse_zone_with_bodypart(target_zone)]."),
|
|
span_notice("[user] successfully extracts [target_organ] from [target]'s [target.parse_zone_with_bodypart(target_zone)]!"),
|
|
span_notice("[user] successfully extracts something from [target]'s [target.parse_zone_with_bodypart(target_zone)]!"),
|
|
)
|
|
display_pain(target, "Your [target.parse_zone_with_bodypart(target_zone)] throbs with pain, you can't feel your [target_organ.name] anymore!")
|
|
log_combat(user, target, "surgically removed [target_organ.name] from", addition="COMBAT MODE: [uppertext(user.combat_mode)]")
|
|
target_organ.Remove(target)
|
|
target_organ.forceMove(get_turf(target))
|
|
target_organ.on_surgical_removal(user, target, target_zone, tool)
|
|
else
|
|
display_results(
|
|
user,
|
|
target,
|
|
span_warning("You can't extract anything from [target]'s [target.parse_zone_with_bodypart(target_zone)]!"),
|
|
span_notice("[user] can't seem to extract anything from [target]'s [target.parse_zone_with_bodypart(target_zone)]!"),
|
|
span_notice("[user] can't seem to extract anything from [target]'s [target.parse_zone_with_bodypart(target_zone)]!"),
|
|
)
|
|
if(HAS_MIND_TRAIT(user, TRAIT_MORBID) && ishuman(user))
|
|
var/mob/living/carbon/human/morbid_weirdo = user
|
|
morbid_weirdo.add_mood_event("morbid_abominable_surgery_success", /datum/mood_event/morbid_abominable_surgery_success)
|
|
return ..()
|
|
|
|
///You can never use this MUHAHAHAHAHAHAH (because its the byond version of abstract)
|
|
/datum/surgery_step/manipulate_organs/proc/can_use_organ(mob/user, obj/item/organ/organ)
|
|
return FALSE
|
|
|
|
///Surgery step for internal organs, like hearts and brains
|
|
/datum/surgery_step/manipulate_organs/internal
|
|
time = 6.4 SECONDS
|
|
name = "manipulate organs (hemostat/organ)"
|
|
|
|
///only operate on internal organs
|
|
/datum/surgery_step/manipulate_organs/internal/can_use_organ(mob/user, obj/item/organ/organ)
|
|
return isinternalorgan(organ)
|
|
|
|
///prosthetic surgery gives full effectiveness to crowbars (and hemostats)
|
|
/datum/surgery_step/manipulate_organs/internal/mechanic
|
|
implements_extract = list(TOOL_HEMOSTAT = 100, TOOL_CROWBAR = 100, /obj/item/kitchen/fork = 35)
|
|
name = "manipulate prosthetic organs (hemostat or crowbar/organ)"
|
|
|
|
///Surgery step for external organs/features, like tails, frills, wings etc
|
|
/datum/surgery_step/manipulate_organs/external
|
|
time = 3.2 SECONDS
|
|
name = "manipulate features (hemostat/feature)"
|
|
|
|
///Only operate on external organs
|
|
/datum/surgery_step/manipulate_organs/external/can_use_organ(mob/user, obj/item/organ/organ)
|
|
return isexternalorgan(organ)
|
|
|
|
///prosthetic surgery gives full effectiveness to crowbars (and hemostats)
|
|
/datum/surgery_step/manipulate_organs/external/mechanic
|
|
implements_extract = list(TOOL_HEMOSTAT = 100, TOOL_CROWBAR = 100, /obj/item/kitchen/fork = 35)
|
|
name = "manipulate prosthetic features (hemostat or crowbar/feature)"
|