From ac041b1d9381dc8678af04a07c60db2aea08d37b Mon Sep 17 00:00:00 2001 From: nmajask Date: Tue, 21 Jun 2022 20:59:49 -0400 Subject: [PATCH 1/3] a --- code/_onclick/hud/radial.dm | 47 +++++++++++++++--- code/game/objects/effects/info.dm | 26 ++++++++++ code/modules/surgery/amputation.dm | 2 + code/modules/surgery/brain_surgery.dm | 2 + code/modules/surgery/cavity_implant.dm | 3 ++ code/modules/surgery/coronary_bypass.dm | 2 + code/modules/surgery/dental_implant.dm | 2 + .../surgery/experimental_dissection.dm | 2 + code/modules/surgery/eye_surgery.dm | 2 + code/modules/surgery/healing.dm | 4 ++ code/modules/surgery/helpers.dm | 10 +++- code/modules/surgery/implant_removal.dm | 2 + code/modules/surgery/limb_augmentation.dm | 2 + code/modules/surgery/lipoplasty.dm | 2 + code/modules/surgery/lobectomy.dm | 2 + code/modules/surgery/organ_manipulation.dm | 2 + .../modules/surgery/prosthetic_replacement.dm | 2 + .../modules/surgery/remove_embedded_object.dm | 1 + code/modules/surgery/repair_puncture.dm | 2 + code/modules/surgery/stomachpump.dm | 2 + code/modules/surgery/surgery.dm | 5 ++ code/modules/surgery/surgery_step.dm | 6 +-- code/modules/surgery/tools.dm | 24 +++++++++ icons/effects/effects.dmi | Bin 901209 -> 901514 bytes icons/misc/surgery_icons.dmi | Bin 0 -> 3359 bytes yogstation.dme | 1 + .../modules/surgery/gender_reassignment.dm | 3 +- 27 files changed, 146 insertions(+), 12 deletions(-) create mode 100644 code/game/objects/effects/info.dm create mode 100644 icons/misc/surgery_icons.dmi diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm index c38ca3ae2165..4772d0bca9bf 100644 --- a/code/_onclick/hud/radial.dm +++ b/code/_onclick/hud/radial.dm @@ -51,10 +51,16 @@ GLOBAL_LIST_EMPTY(radial_menus) parent.finished = TRUE /datum/radial_menu - var/list/choices = list() //List of choice id's - var/list/choices_icons = list() //choice_id -> icon - var/list/choices_values = list() //choice_id -> choice - var/list/page_data = list() //list of choices per page + /// List of choice IDs + var/list/choices = list() + /// choice_id -> icon + var/list/choices_icons = list() + /// choice_id -> choice + var/list/choices_values = list() + /// choice_id -> /datum/radial_menu_choice + var/list/choice_datums = list() + ///list of choices per page + var/list/page_data = list() var/selected_choice @@ -188,6 +194,7 @@ GLOBAL_LIST_EMPTY(radial_menus) E.alpha = 255 E.mouse_opacity = MOUSE_OPACITY_ICON E.cut_overlays() + E.vis_contents.Cut() if(choice_id == NEXT_PAGE_ID) E.name = "Next Page" E.next_page = TRUE @@ -195,6 +202,9 @@ GLOBAL_LIST_EMPTY(radial_menus) else if(istext(choices_values[choice_id])) E.name = choices_values[choice_id] + else if(ispath(choices_values[choice_id],/atom)) + var/atom/A = choices_values[choice_id] + E.name = initial(A.name) else var/atom/movable/AM = choices_values[choice_id] //Movables only E.name = AM.name @@ -203,6 +213,12 @@ GLOBAL_LIST_EMPTY(radial_menus) E.next_page = FALSE if(choices_icons[choice_id]) E.add_overlay(choices_icons[choice_id]) + if (choice_datums[choice_id]) + var/datum/radial_menu_choice/choice_datum = choice_datums[choice_id] + if (choice_datum.info) + var/obj/effect/abstract/info/info_button = new(E, choice_datum.info) + info_button.layer = ABOVE_HUD_LAYER + 0.1 + E.vis_contents += info_button /datum/radial_menu/New() close_button = new @@ -231,11 +247,18 @@ GLOBAL_LIST_EMPTY(radial_menus) var/I = extract_image(new_choices[E]) if(I) choices_icons[id] = I + + if (istype(new_choices[E], /datum/radial_menu_choice)) + choice_datums[id] = new_choices[E] setup_menu(use_tooltips) -/datum/radial_menu/proc/extract_image(E) - var/mutable_appearance/MA = new /mutable_appearance(E) +/datum/radial_menu/proc/extract_image(to_extract_from) + if (istype(to_extract_from, /datum/radial_menu_choice)) + var/datum/radial_menu_choice/choice = to_extract_from + to_extract_from = choice.image + + var/mutable_appearance/MA = new /mutable_appearance(to_extract_from) if(MA) MA.layer = ABOVE_HUD_LAYER MA.appearance_flags |= RESET_TRANSFORM @@ -315,3 +338,15 @@ GLOBAL_LIST_EMPTY(radial_menus) if(!menu.custom_check_callback.Invoke()) return return answer + +/// Can be provided to choices in radial menus if you want to provide more information +/datum/radial_menu_choice + /// Required -- what to display for this button + var/image + + /// If provided, will display an info button that will put this text in your chat + var/info + +/datum/radial_menu_choice/Destroy(force, ...) + . = ..() + QDEL_NULL(image) diff --git a/code/game/objects/effects/info.dm b/code/game/objects/effects/info.dm new file mode 100644 index 000000000000..23f341c8a3c7 --- /dev/null +++ b/code/game/objects/effects/info.dm @@ -0,0 +1,26 @@ +/// An info button that, when clicked, puts some text in the user's chat +/obj/effect/abstract/info + name = "info" + icon = 'icons/effects/effects.dmi' + icon_state = "info" + + /// What should the info button display when clicked? + var/info_text + +/obj/effect/abstract/info/Initialize(mapload, info_text) + . = ..() + + if (!isnull(info_text)) + src.info_text = info_text + +/obj/effect/abstract/info/Click() + . = ..() + to_chat(usr, info_text) + +/obj/effect/abstract/info/MouseEntered() + . = ..() + icon_state = "info_hovered" + +/obj/effect/abstract/info/MouseExited() + . = ..() + icon_state = initial(icon_state) diff --git a/code/modules/surgery/amputation.dm b/code/modules/surgery/amputation.dm index 5ad199d41ff6..6a357e482b95 100644 --- a/code/modules/surgery/amputation.dm +++ b/code/modules/surgery/amputation.dm @@ -1,6 +1,8 @@ /datum/surgery/amputation name = "Amputation" + icon_state = "amputation" + desc = "Sever a limb from the torso." steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/sever_limb) target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG, BODY_ZONE_HEAD) diff --git a/code/modules/surgery/brain_surgery.dm b/code/modules/surgery/brain_surgery.dm index 953862939643..d94fa661c36b 100644 --- a/code/modules/surgery/brain_surgery.dm +++ b/code/modules/surgery/brain_surgery.dm @@ -1,5 +1,7 @@ /datum/surgery/brain_surgery name = "Brain surgery" + icon = 'icons/obj/surgery.dmi' + icon_state = "brain" steps = list( /datum/surgery_step/incise, /datum/surgery_step/retract_skin, diff --git a/code/modules/surgery/cavity_implant.dm b/code/modules/surgery/cavity_implant.dm index c85e68b73b66..d231d9769bfd 100644 --- a/code/modules/surgery/cavity_implant.dm +++ b/code/modules/surgery/cavity_implant.dm @@ -1,5 +1,8 @@ /datum/surgery/cavity_implant name = "Cavity implant" + desc = "Replace a severed limb with either a normal or a robotic limb." + icon = 'icons/obj/lighting.dmi' + icon_state = "flashlight" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/incise, /datum/surgery_step/handle_cavity, /datum/surgery_step/close) target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_CHEST) diff --git a/code/modules/surgery/coronary_bypass.dm b/code/modules/surgery/coronary_bypass.dm index 2af4c91b3f88..37c9bb1eb0ce 100644 --- a/code/modules/surgery/coronary_bypass.dm +++ b/code/modules/surgery/coronary_bypass.dm @@ -1,5 +1,7 @@ /datum/surgery/coronary_bypass name = "Coronary Bypass" + icon = 'icons/obj/surgery.dmi' + icon_state = "heart-off" steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/incise_heart, /datum/surgery_step/coronary_bypass, /datum/surgery_step/close) possible_locs = list(BODY_ZONE_CHEST) diff --git a/code/modules/surgery/dental_implant.dm b/code/modules/surgery/dental_implant.dm index f0457cdc6b39..13c6da9f001d 100644 --- a/code/modules/surgery/dental_implant.dm +++ b/code/modules/surgery/dental_implant.dm @@ -1,5 +1,7 @@ /datum/surgery/dental_implant name = "Dental implant" + icon = 'icons/obj/implants.dmi' + icon_state = "reagents" steps = list(/datum/surgery_step/drill, /datum/surgery_step/insert_pill) possible_locs = list(BODY_ZONE_PRECISE_MOUTH) diff --git a/code/modules/surgery/experimental_dissection.dm b/code/modules/surgery/experimental_dissection.dm index cfa5b4f8ae80..02e4fc648c6a 100644 --- a/code/modules/surgery/experimental_dissection.dm +++ b/code/modules/surgery/experimental_dissection.dm @@ -1,5 +1,7 @@ /datum/surgery/experimental_dissection name = "Experimental Dissection" + icon = 'icons/obj/surgery.dmi' + icon_state = "scalpel" desc = "A surgical procedure which deeply analyzes the biology of a corpse, and automatically adds new findings to the research database." steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, diff --git a/code/modules/surgery/eye_surgery.dm b/code/modules/surgery/eye_surgery.dm index 6c5661c86503..4ac7f203952c 100644 --- a/code/modules/surgery/eye_surgery.dm +++ b/code/modules/surgery/eye_surgery.dm @@ -1,5 +1,7 @@ /datum/surgery/eye_surgery name = "Eye surgery" + icon = 'icons/obj/surgery.dmi' + icon_state = "eyeballs" steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/fix_eyes, /datum/surgery_step/close) target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_PRECISE_EYES) diff --git a/code/modules/surgery/healing.dm b/code/modules/surgery/healing.dm index 3735e1185038..421c1eb3f19c 100644 --- a/code/modules/surgery/healing.dm +++ b/code/modules/surgery/healing.dm @@ -1,4 +1,5 @@ /datum/surgery/healing + icon = 'icons/obj/chemical.dmi' steps = list(/datum/surgery_step/incise, /datum/surgery_step/heal, /datum/surgery_step/close) @@ -105,6 +106,7 @@ /***************************BRUTE***************************/ /datum/surgery/healing/brute name = "Tend Wounds (Bruises)" + icon_state = "bandaid_brute" /datum/surgery/healing/brute/basic name = "Tend Wounds (Bruises, Basic)" @@ -170,6 +172,7 @@ /***************************BURN***************************/ /datum/surgery/healing/burn name = "Tend Wounds (Burn)" + icon_state = "bandaid_burn" /datum/surgery/healing/burn/basic name = "Tend Wounds (Burn, Basic)" @@ -236,6 +239,7 @@ /datum/surgery/healing/combo name = "Tend Wounds (Mixture, Basic)" + icon_state = "bandaid_both" replaced_by = /datum/surgery/healing/combo/upgraded requires_tech = TRUE healing_step_type = /datum/surgery_step/heal/combo diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm index 9304f1be5528..b0796951924b 100644 --- a/code/modules/surgery/helpers.dm +++ b/code/modules/surgery/helpers.dm @@ -19,6 +19,7 @@ if(!current_surgery) var/list/all_surgeries = GLOB.surgeries_list.Copy() var/list/available_surgeries = list() + var/list/radial_list = list() for(var/datum/surgery/S in all_surgeries) if(!S.possible_locs.Find(selected_zone)) @@ -39,12 +40,17 @@ for(var/path in S.target_mobtypes) if(istype(M, path)) available_surgeries[S.name] = S + var/datum/radial_menu_choice/choice = new + choice.image = S.get_icon() + choice.info = S.desc + radial_list[S.name] = choice break if(!available_surgeries.len) + to_chat(user, span_warning("You can't preform any surgeries on [M]'s [parse_zone(selected_zone)]!")) return - - var/P = input("Begin which procedure?", "Surgery", null, null) as null|anything in available_surgeries + + var/P = show_radial_menu(user, M, radial_list, require_near = TRUE, tooltips = TRUE) if(P && user && user.Adjacent(M) && (I in user)) var/datum/surgery/S = available_surgeries[P] diff --git a/code/modules/surgery/implant_removal.dm b/code/modules/surgery/implant_removal.dm index 24e40312d8b2..da1138153ca7 100644 --- a/code/modules/surgery/implant_removal.dm +++ b/code/modules/surgery/implant_removal.dm @@ -1,5 +1,7 @@ /datum/surgery/implant_removal name = "implant removal" + icon = 'icons/obj/implants.dmi' + icon_state = "implantcase-b" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/extract_implant, /datum/surgery_step/close) target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_CHEST) diff --git a/code/modules/surgery/limb_augmentation.dm b/code/modules/surgery/limb_augmentation.dm index 25c0deb4f370..56405fb1a813 100644 --- a/code/modules/surgery/limb_augmentation.dm +++ b/code/modules/surgery/limb_augmentation.dm @@ -45,6 +45,8 @@ /datum/surgery/augmentation name = "Augmentation" + desc = "Replace a limb with a robot part." + icon_state = "augmentation" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/replace, /datum/surgery_step/saw, /datum/surgery_step/replace_limb) target_mobtypes = list(/mob/living/carbon/human) possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD) diff --git a/code/modules/surgery/lipoplasty.dm b/code/modules/surgery/lipoplasty.dm index 80d399676eb5..74d23bcaf92a 100644 --- a/code/modules/surgery/lipoplasty.dm +++ b/code/modules/surgery/lipoplasty.dm @@ -1,5 +1,7 @@ /datum/surgery/lipoplasty name = "Lipoplasty" + icon = 'icons/obj/food/food.dmi' + icon_state = "meat" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/cut_fat, /datum/surgery_step/remove_fat, /datum/surgery_step/close) possible_locs = list(BODY_ZONE_CHEST) diff --git a/code/modules/surgery/lobectomy.dm b/code/modules/surgery/lobectomy.dm index fa9dabfb0c0c..d9580ae31468 100644 --- a/code/modules/surgery/lobectomy.dm +++ b/code/modules/surgery/lobectomy.dm @@ -1,5 +1,7 @@ /datum/surgery/lobectomy name = "Lobectomy" //not to be confused with lobotomy + icon = 'icons/obj/surgery.dmi' + icon_state = "lungs" steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/lobectomy, /datum/surgery_step/close) possible_locs = list(BODY_ZONE_CHEST) diff --git a/code/modules/surgery/organ_manipulation.dm b/code/modules/surgery/organ_manipulation.dm index da0a825d689b..a27f68fdb38b 100644 --- a/code/modules/surgery/organ_manipulation.dm +++ b/code/modules/surgery/organ_manipulation.dm @@ -1,5 +1,7 @@ /datum/surgery/organ_manipulation name = "Organ manipulation" + icon_state = "organ_manipulation" + desc = "This surgery covers operations to remove/insert internal organs, tails, and cyber implants." target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD) requires_real_bodypart = 1 diff --git a/code/modules/surgery/prosthetic_replacement.dm b/code/modules/surgery/prosthetic_replacement.dm index e158067b4ba6..e7adaf10ca54 100644 --- a/code/modules/surgery/prosthetic_replacement.dm +++ b/code/modules/surgery/prosthetic_replacement.dm @@ -1,5 +1,7 @@ /datum/surgery/prosthetic_replacement name = "Prosthetic replacement" + desc = "Replace a severed limb with either a normal or a robotic limb." + icon_state = "prosthetic_replacement" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/add_prosthetic) target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) possible_locs = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG, BODY_ZONE_HEAD) diff --git a/code/modules/surgery/remove_embedded_object.dm b/code/modules/surgery/remove_embedded_object.dm index 3b4f542f5d3a..ab51e55d0e01 100644 --- a/code/modules/surgery/remove_embedded_object.dm +++ b/code/modules/surgery/remove_embedded_object.dm @@ -1,5 +1,6 @@ /datum/surgery/embedded_removal name = "Removal of embedded objects" + icon_state = "embedded_removal" steps = list(/datum/surgery_step/incise, /datum/surgery_step/remove_object, /datum/surgery_step/close) possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD) diff --git a/code/modules/surgery/repair_puncture.dm b/code/modules/surgery/repair_puncture.dm index 7a13400394f1..59936f641564 100644 --- a/code/modules/surgery/repair_puncture.dm +++ b/code/modules/surgery/repair_puncture.dm @@ -8,6 +8,8 @@ ///// Repair puncture wounds /datum/surgery/repair_puncture name = "Repair puncture" + icon = 'icons/obj/stack_medical.dmi' + icon_state = "suture_3" steps = list(/datum/surgery_step/incise, /datum/surgery_step/repair_innards, /datum/surgery_step/seal_veins, /datum/surgery_step/close) // repeat between steps 2 and 3 until healed target_mobtypes = list(/mob/living/carbon) possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD) diff --git a/code/modules/surgery/stomachpump.dm b/code/modules/surgery/stomachpump.dm index 45b57042b1ed..dfe41cc6608c 100644 --- a/code/modules/surgery/stomachpump.dm +++ b/code/modules/surgery/stomachpump.dm @@ -1,5 +1,7 @@ /datum/surgery/stomach_pump name = "Stomach Pump" + icon = 'icons/obj/surgery.dmi' + icon_state = "stomach" steps = list( /datum/surgery_step/incise, /datum/surgery_step/retract_skin, diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index 6e8e6506fa7d..fb9f77750be4 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -1,6 +1,8 @@ /datum/surgery var/name = "surgery" var/desc = "surgery description" + var/icon = 'icons/misc/surgery_icons.dmi' + var/icon_state var/status = 1 var/list/steps = list() //Steps in a surgery var/step_in_progress = 0 //Actively performing a Surgery @@ -147,6 +149,9 @@ return probability + success_multiplier +/datum/surgery/proc/get_icon() + return icon(icon, icon_state) + /datum/surgery/advanced name = "advanced surgery" requires_tech = TRUE diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm index 92714731a597..49bee8cb9ccb 100644 --- a/code/modules/surgery/surgery_step.dm +++ b/code/modules/surgery/surgery_step.dm @@ -154,7 +154,7 @@ break else sound_file_use = preop_sound - playsound(get_turf(target), sound_file_use, 75, TRUE, falloff = 1) + playsound(get_turf(target), sound_file_use, 30, TRUE, falloff = 2) /datum/surgery_step/proc/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, span_notice("You succeed."), @@ -173,7 +173,7 @@ break else sound_file_use = success_sound - playsound(get_turf(target), sound_file_use, 75, TRUE, falloff = 1) + playsound(get_turf(target), sound_file_use, 30, TRUE, falloff = 2) /datum/surgery_step/proc/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results(user, target, span_warning("You screw up!"), @@ -192,7 +192,7 @@ break else sound_file_use = failure_sound - playsound(get_turf(target), sound_file_use, 75, TRUE, falloff = 1) + playsound(get_turf(target), sound_file_use, 30, TRUE, falloff = 2) /datum/surgery_step/proc/tool_check(mob/user, obj/item/tool) return TRUE diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 5576ac42ed1b..2ccf6019a1a4 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -12,6 +12,9 @@ tool_behaviour = TOOL_RETRACTOR w_class = WEIGHT_CLASS_TINY +/obj/item/retractor/attack(mob/living/M, mob/user) + if(!attempt_initiate_surgery(src, M, user)) + ..() /obj/item/retractor/augment name = "retractor" @@ -45,6 +48,9 @@ w_class = WEIGHT_CLASS_TINY attack_verb = list("attacked", "pinched") +/obj/item/hemostat/attack(mob/living/M, mob/user) + if(!attempt_initiate_surgery(src, M, user)) + ..() /obj/item/hemostat/augment name = "hemostat" @@ -79,6 +85,9 @@ w_class = WEIGHT_CLASS_TINY attack_verb = list("burnt") +/obj/item/cautery/attack(mob/living/M, mob/user) + if(!attempt_initiate_surgery(src, M, user)) + ..() /obj/item/cautery/augment name = "cautery" @@ -125,6 +134,9 @@ SSachievements.unlock_achievement(/datum/achievement/likearecord, user.client) return (MANUAL_SUICIDE) +/obj/item/surgicaldrill/attack(mob/living/M, mob/user) + if(!attempt_initiate_surgery(src, M, user)) + ..() /obj/item/surgicaldrill/augment name = "surgical drill" @@ -167,6 +179,10 @@ . = ..() AddComponent(/datum/component/butchering, 80 * toolspeed, 100, 0) +/obj/item/scalpel/attack(mob/living/M, mob/user) + if(!attempt_initiate_surgery(src, M, user)) + ..() + /obj/item/scalpel/augment name = "scalpel" desc = "Ultra-sharp blade attached directly to your bone for extra-accuracy." @@ -222,6 +238,10 @@ . = ..() AddComponent(/datum/component/butchering, 40 * toolspeed, 100, 5, 'sound/weapons/circsawhit.ogg') //saws are very accurate and fast at butchering +/obj/item/circular_saw/attack(mob/living/M, mob/user) + if(!attempt_initiate_surgery(src, M, user)) + ..() + /obj/item/circular_saw/augment name = "circular saw" desc = "A small but very fast spinning saw. Edges dulled to prevent accidental cutting inside of the surgeon." @@ -258,6 +278,10 @@ w_class = WEIGHT_CLASS_SMALL attack_verb = list("corrected", "properly set") +/obj/item/bonesetter/attack(mob/living/M, mob/user) + if(!attempt_initiate_surgery(src, M, user)) + ..() + /obj/item/bonesetter/bone name = "bone bonesetter" desc = "A bonesetter made of bones... for setting bones with... bones?" diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index aa03f6b641a9513aa29ef7db8f959c27ec364b24..dcd970251cf5fa924d1f9cb951028b6d1a4485aa 100644 GIT binary patch delta 14553 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 delta 14246 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 Date: Sat, 25 Jun 2022 01:41:56 -0400 Subject: [PATCH 2/3] final touches --- code/_onclick/hud/radial.dm | 20 +++--- code/game/objects/effects/info.dm | 26 ------- code/modules/mob/living/carbon/examine.dm | 9 +++ .../mob/living/carbon/human/examine.dm | 10 ++- code/modules/surgery/advanced/lobotomy.dm | 1 + code/modules/surgery/advanced/revival.dm | 1 + code/modules/surgery/autopsy.dm | 3 + code/modules/surgery/brain_surgery.dm | 1 + code/modules/surgery/cavity_implant.dm | 2 +- code/modules/surgery/core_removal.dm | 3 + code/modules/surgery/coronary_bypass.dm | 1 + code/modules/surgery/dental_implant.dm | 1 + .../surgery/experimental_dissection.dm | 4 +- code/modules/surgery/eye_surgery.dm | 1 + code/modules/surgery/helpers.dm | 35 +++++---- code/modules/surgery/implant_removal.dm | 1 + code/modules/surgery/lipoplasty.dm | 1 + code/modules/surgery/lobectomy.dm | 1 + code/modules/surgery/plastic_surgery.dm | 2 + .../modules/surgery/remove_embedded_object.dm | 8 ++- code/modules/surgery/surgery.dm | 68 ++++++++++++------ code/modules/surgery/surgery_step.dm | 9 +++ code/modules/surgery/tools.dm | 16 ++--- icons/misc/surgery_icons.dmi | Bin 3359 -> 4400 bytes yogstation.dme | 1 - .../modules/surgery/gender_reassignment.dm | 3 +- .../code/modules/surgery/healing_surgeries.dm | 6 ++ 27 files changed, 147 insertions(+), 87 deletions(-) delete mode 100644 code/game/objects/effects/info.dm diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm index 4772d0bca9bf..f9fa07185689 100644 --- a/code/_onclick/hud/radial.dm +++ b/code/_onclick/hud/radial.dm @@ -19,7 +19,7 @@ GLOBAL_LIST_EMPTY(radial_menus) . = ..() icon_state = "radial_slice_focus" if(tooltips) - openToolTip(usr, src, params, title = name) + openToolTip(usr, src, params, title = name, content = desc) /obj/screen/radial/slice/MouseExited(location, control, params) . = ..() @@ -170,6 +170,7 @@ GLOBAL_LIST_EMPTY(radial_menus) E.cut_overlays() E.alpha = 0 E.name = "None" + E.desc = null E.maptext = null E.mouse_opacity = MOUSE_OPACITY_TRANSPARENT E.choice = null @@ -197,6 +198,7 @@ GLOBAL_LIST_EMPTY(radial_menus) E.vis_contents.Cut() if(choice_id == NEXT_PAGE_ID) E.name = "Next Page" + E.desc = null E.next_page = TRUE E.add_overlay("radial_next") else @@ -208,17 +210,17 @@ GLOBAL_LIST_EMPTY(radial_menus) else var/atom/movable/AM = choices_values[choice_id] //Movables only E.name = AM.name + + if(choices_icons[choice_id]) + E.add_overlay(choices_icons[choice_id]) + + var/datum/radial_menu_choice/choice_datum = choice_datums[choice_id] + if(istext(choice_datum.info)) + E.desc = choice_datum.info + E.choice = choice_id E.maptext = null E.next_page = FALSE - if(choices_icons[choice_id]) - E.add_overlay(choices_icons[choice_id]) - if (choice_datums[choice_id]) - var/datum/radial_menu_choice/choice_datum = choice_datums[choice_id] - if (choice_datum.info) - var/obj/effect/abstract/info/info_button = new(E, choice_datum.info) - info_button.layer = ABOVE_HUD_LAYER + 0.1 - E.vis_contents += info_button /datum/radial_menu/New() close_button = new diff --git a/code/game/objects/effects/info.dm b/code/game/objects/effects/info.dm deleted file mode 100644 index 23f341c8a3c7..000000000000 --- a/code/game/objects/effects/info.dm +++ /dev/null @@ -1,26 +0,0 @@ -/// An info button that, when clicked, puts some text in the user's chat -/obj/effect/abstract/info - name = "info" - icon = 'icons/effects/effects.dmi' - icon_state = "info" - - /// What should the info button display when clicked? - var/info_text - -/obj/effect/abstract/info/Initialize(mapload, info_text) - . = ..() - - if (!isnull(info_text)) - src.info_text = info_text - -/obj/effect/abstract/info/Click() - . = ..() - to_chat(usr, info_text) - -/obj/effect/abstract/info/MouseEntered() - . = ..() - icon_state = "info_hovered" - -/obj/effect/abstract/info/MouseExited() - . = ..() - icon_state = initial(icon_state) diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index 75a3cb178ae5..f80c6c2b1939 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -78,6 +78,15 @@ msg += "[t_He] [t_is] moderately deformed!\n" else msg += "[t_He] [t_is] severely deformed!\n" + + if(surgeries.len) + var/surgery_text + for(var/datum/surgery/S in surgeries) + if(!surgery_text) + surgery_text = "[t_He] [t_is] being operated on in \the [S.operated_bodypart]" + else + surgery_text += ", [S.operated_bodypart]" + msg += "[surgery_text].\n" if(HAS_TRAIT(src, TRAIT_DUMB)) msg += "[t_He] seem[p_s()] to be clumsy and unable to think.\n" diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 324beccad878..60a34b30803d 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -206,7 +206,15 @@ msg += "[t_He] [t_has] moderate cellular damage!\n" else msg += "[t_He] [t_has] severe cellular damage!\n" - + + if(surgeries.len) + var/surgery_text + for(var/datum/surgery/S in surgeries) + if(!surgery_text) + surgery_text = "[t_He] [t_is] being operated on in \the [S.operated_bodypart]" + else + surgery_text += ", [S.operated_bodypart]" + msg += "[surgery_text].\n" if(fire_stacks > 0) msg += "[t_He] [t_is] covered in something flammable.\n" diff --git a/code/modules/surgery/advanced/lobotomy.dm b/code/modules/surgery/advanced/lobotomy.dm index 0bec7ca1f1f5..c90b40a15eba 100644 --- a/code/modules/surgery/advanced/lobotomy.dm +++ b/code/modules/surgery/advanced/lobotomy.dm @@ -1,6 +1,7 @@ /datum/surgery/advanced/lobotomy name = "Lobotomy" desc = "An invasive surgical procedure which guarantees removal of almost all brain traumas, but might cause another permanent trauma in return." + icon_state = "lobotomy" steps = list( /datum/surgery_step/incise, /datum/surgery_step/retract_skin, diff --git a/code/modules/surgery/advanced/revival.dm b/code/modules/surgery/advanced/revival.dm index 2981a884f526..164d1fedb60d 100644 --- a/code/modules/surgery/advanced/revival.dm +++ b/code/modules/surgery/advanced/revival.dm @@ -1,6 +1,7 @@ /datum/surgery/advanced/revival name = "Revival" desc = "An experimental surgical procedure which involves reconstruction and reactivation of the patient's brain even long after death. The body must still be able to sustain life." + icon_state = "revival" steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, diff --git a/code/modules/surgery/autopsy.dm b/code/modules/surgery/autopsy.dm index 331a4fb9b4e3..995ca5ec1c94 100644 --- a/code/modules/surgery/autopsy.dm +++ b/code/modules/surgery/autopsy.dm @@ -1,6 +1,9 @@ /datum/surgery/autopsy name = "Autopsy" + desc = "Tells you what last damaged the patient." + icon = 'icons/obj/surgery.dmi' + icon_state = "scalpel" steps = list(/datum/surgery_step/incise, /datum/surgery_step/autopsy) target_mobtypes = list(/mob/living) diff --git a/code/modules/surgery/brain_surgery.dm b/code/modules/surgery/brain_surgery.dm index d94fa661c36b..1d764536b704 100644 --- a/code/modules/surgery/brain_surgery.dm +++ b/code/modules/surgery/brain_surgery.dm @@ -1,5 +1,6 @@ /datum/surgery/brain_surgery name = "Brain surgery" + desc = "This procedure cures all severe and basic traumas and reduces brain damage by a large amount. Failing to fix the brain causes hefty brain damage." icon = 'icons/obj/surgery.dmi' icon_state = "brain" steps = list( diff --git a/code/modules/surgery/cavity_implant.dm b/code/modules/surgery/cavity_implant.dm index d231d9769bfd..fc8faf3b667e 100644 --- a/code/modules/surgery/cavity_implant.dm +++ b/code/modules/surgery/cavity_implant.dm @@ -1,6 +1,6 @@ /datum/surgery/cavity_implant name = "Cavity implant" - desc = "Replace a severed limb with either a normal or a robotic limb." + desc = "Implants or removes an object in the chest. Items up to normal size can be implanted, but tiny and small items won't show what they are in the implanting messages." icon = 'icons/obj/lighting.dmi' icon_state = "flashlight" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/incise, /datum/surgery_step/handle_cavity, /datum/surgery_step/close) diff --git a/code/modules/surgery/core_removal.dm b/code/modules/surgery/core_removal.dm index 9155cf201235..32be2db283f0 100644 --- a/code/modules/surgery/core_removal.dm +++ b/code/modules/surgery/core_removal.dm @@ -1,5 +1,8 @@ /datum/surgery/core_removal name = "Core removal" + desc = "Remove core from slime. Extract core must be repeated for every core if slime has several." + icon = 'icons/mob/slimes.dmi' + icon_state = "grey slime extract" steps = list(/datum/surgery_step/incise, /datum/surgery_step/extract_core) target_mobtypes = list(/mob/living/simple_animal/slime) possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD) diff --git a/code/modules/surgery/coronary_bypass.dm b/code/modules/surgery/coronary_bypass.dm index 37c9bb1eb0ce..86c32a148482 100644 --- a/code/modules/surgery/coronary_bypass.dm +++ b/code/modules/surgery/coronary_bypass.dm @@ -1,5 +1,6 @@ /datum/surgery/coronary_bypass name = "Coronary Bypass" + desc = "Restores the heart to a functional state if it is in a non-functional state, making it able to be defibrillated and sustain life. Can only be performed once on an individual heart." icon = 'icons/obj/surgery.dmi' icon_state = "heart-off" steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/clamp_bleeders, diff --git a/code/modules/surgery/dental_implant.dm b/code/modules/surgery/dental_implant.dm index 13c6da9f001d..965d6cd03f59 100644 --- a/code/modules/surgery/dental_implant.dm +++ b/code/modules/surgery/dental_implant.dm @@ -1,5 +1,6 @@ /datum/surgery/dental_implant name = "Dental implant" + desc = "This allows you to insert pills/patches into a tooth cavity, allowing you to pop it any time to ingest it. This works for both stimulants and suicide pills." icon = 'icons/obj/implants.dmi' icon_state = "reagents" steps = list(/datum/surgery_step/drill, /datum/surgery_step/insert_pill) diff --git a/code/modules/surgery/experimental_dissection.dm b/code/modules/surgery/experimental_dissection.dm index 02e4fc648c6a..09bd2b66f8fc 100644 --- a/code/modules/surgery/experimental_dissection.dm +++ b/code/modules/surgery/experimental_dissection.dm @@ -1,8 +1,8 @@ /datum/surgery/experimental_dissection name = "Experimental Dissection" - icon = 'icons/obj/surgery.dmi' - icon_state = "scalpel" desc = "A surgical procedure which deeply analyzes the biology of a corpse, and automatically adds new findings to the research database." + icon = 'icons/obj/implants.dmi' + icon_state = "scan_mode" steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/clamp_bleeders, diff --git a/code/modules/surgery/eye_surgery.dm b/code/modules/surgery/eye_surgery.dm index 4ac7f203952c..4f41fb3a1308 100644 --- a/code/modules/surgery/eye_surgery.dm +++ b/code/modules/surgery/eye_surgery.dm @@ -1,5 +1,6 @@ /datum/surgery/eye_surgery name = "Eye surgery" + desc = "Fixes all damage done to eyes, though doesnt fix genetic blindness. Failing to fix the eyes will cause brain damage to the patient." icon = 'icons/obj/surgery.dmi' icon_state = "eyeballs" steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/fix_eyes, /datum/surgery_step/close) diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm index b0796951924b..507b7bef2244 100644 --- a/code/modules/surgery/helpers.dm +++ b/code/modules/surgery/helpers.dm @@ -50,7 +50,7 @@ to_chat(user, span_warning("You can't preform any surgeries on [M]'s [parse_zone(selected_zone)]!")) return - var/P = show_radial_menu(user, M, radial_list, require_near = TRUE, tooltips = TRUE) + var/P = show_radial_menu(user, M, radial_list, radius = 40, require_near = TRUE, tooltips = TRUE) if(P && user && user.Adjacent(M) && (I in user)) var/datum/surgery/S = available_surgeries[P] @@ -75,11 +75,17 @@ if(S.ignore_clothes || get_location_accessible(M, selected_zone)) var/datum/surgery/procedure = new S.type(M, selected_zone, affecting) - user.visible_message("[user] drapes [I] over [M]'s [parse_zone(selected_zone)] to prepare for surgery.", \ - span_notice("You drape [I] over [M]'s [parse_zone(selected_zone)] to prepare for \an [procedure.name].")) + var/datum/surgery_step/step = procedure.get_surgery_step() + user.visible_message("[user] prepares to operate on [M]'s [parse_zone(selected_zone)].", \ + span_notice("You prepare to operate on [M]'s [parse_zone(selected_zone)].")) playsound(get_turf(M), 'sound/items/handling/cloth_drop.ogg', 30, TRUE, falloff = 1) - log_combat(user, M, "operated on", null, "(OPERATION TYPE: [procedure.name]) (TARGET AREA: [selected_zone])") + if(procedure.step_in_progress) + return + var/try_to_fail = FALSE + if(user.a_intent == INTENT_DISARM) + try_to_fail = TRUE + step.try_op(user, M, user.zone_selected, I, procedure, try_to_fail) else to_chat(user, span_warning("You need to expose [M]'s [parse_zone(selected_zone)] first!")) @@ -90,26 +96,25 @@ /proc/attempt_cancel_surgery(datum/surgery/S, obj/item/I, mob/living/M, mob/user) var/selected_zone = user.zone_selected + to_chat(user, span_notice("You begin to cancel \the [S].")) + if(!do_mob(user, M, 3 SECONDS)) + return if(S.status == 1) M.surgeries -= S - user.visible_message("[user] removes [I] from [M]'s [parse_zone(selected_zone)].", \ - span_notice("You remove [I] from [M]'s [parse_zone(selected_zone)].")) + user.visible_message("[user] stops the surgery on [M]'s [parse_zone(selected_zone)].", \ + span_notice("You stop the surgery on [M]'s [parse_zone(selected_zone)].")) qdel(S) else if(S.can_cancel) - var/close_tool_type = /obj/item/cautery - var/obj/item/close_tool = user.get_inactive_held_item() - var/is_robotic = S.requires_bodypart_type == BODYPART_ROBOTIC - if(is_robotic) - close_tool_type = /obj/item/screwdriver - if(istype(close_tool, close_tool_type) || iscyborg(user)) + var/obj/item/close_tool = user.get_active_held_item() + if(close_tool.tool_behaviour == (S.requires_bodypart_type == BODYPART_ROBOTIC ? TOOL_SCREWDRIVER : TOOL_CAUTERY) || iscyborg(user)) if(S.operated_bodypart) S.operated_bodypart.generic_bleedstacks -= 10 M.surgeries -= S - user.visible_message("[user] closes [M]'s [parse_zone(selected_zone)] with [close_tool] and removes [I].", \ - span_notice("You close [M]'s [parse_zone(selected_zone)] with [close_tool] and remove [I].")) + user.visible_message("[user] closes [M]'s [parse_zone(selected_zone)] with [close_tool].", \ + span_notice("You close [M]'s [parse_zone(selected_zone)] with [close_tool].")) qdel(S) else - to_chat(user, span_warning("You need to hold a [is_robotic ? "screwdriver" : "cautery"] in your inactive hand to stop [M]'s surgery!")) + to_chat(user, span_warning("You need to hold a [S.requires_bodypart_type == BODYPART_ROBOTIC ? "screwdriver" : "cautery"] in your active hand to stop [M]'s surgery!")) /proc/get_location_modifier(mob/M) var/turf/T = get_turf(M) diff --git a/code/modules/surgery/implant_removal.dm b/code/modules/surgery/implant_removal.dm index da1138153ca7..5ead081c0fc8 100644 --- a/code/modules/surgery/implant_removal.dm +++ b/code/modules/surgery/implant_removal.dm @@ -1,5 +1,6 @@ /datum/surgery/implant_removal name = "implant removal" + desc = "Extracts implants from the patient. If you don't have an empty implant case in your other hand, the implant will be ruined on extraction." icon = 'icons/obj/implants.dmi' icon_state = "implantcase-b" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/extract_implant, /datum/surgery_step/close) diff --git a/code/modules/surgery/lipoplasty.dm b/code/modules/surgery/lipoplasty.dm index 74d23bcaf92a..59e0a9b60b30 100644 --- a/code/modules/surgery/lipoplasty.dm +++ b/code/modules/surgery/lipoplasty.dm @@ -1,5 +1,6 @@ /datum/surgery/lipoplasty name = "Lipoplasty" + desc = "Removes excess fat from the patient." icon = 'icons/obj/food/food.dmi' icon_state = "meat" steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/cut_fat, /datum/surgery_step/remove_fat, /datum/surgery_step/close) diff --git a/code/modules/surgery/lobectomy.dm b/code/modules/surgery/lobectomy.dm index d9580ae31468..c73fc138b767 100644 --- a/code/modules/surgery/lobectomy.dm +++ b/code/modules/surgery/lobectomy.dm @@ -1,5 +1,6 @@ /datum/surgery/lobectomy name = "Lobectomy" //not to be confused with lobotomy + desc = "Restores the lungs to a functional state if it is in a non-functional state, making it able to sustain life. Can only be performed once on an individual set of lungs." icon = 'icons/obj/surgery.dmi' icon_state = "lungs" steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/clamp_bleeders, diff --git a/code/modules/surgery/plastic_surgery.dm b/code/modules/surgery/plastic_surgery.dm index f5dcbdcd139b..374aef33655b 100644 --- a/code/modules/surgery/plastic_surgery.dm +++ b/code/modules/surgery/plastic_surgery.dm @@ -1,5 +1,7 @@ /datum/surgery/plastic_surgery name = "Plastic surgery" + desc = "If the patient's face is damaged and unrecognizable it restores it, otherwise it change the face and identity of the patient." + icon_state = "plastic_surgery" steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/reshape_face, /datum/surgery_step/close) possible_locs = list(BODY_ZONE_HEAD) diff --git a/code/modules/surgery/remove_embedded_object.dm b/code/modules/surgery/remove_embedded_object.dm index ab51e55d0e01..1ef83e512b6c 100644 --- a/code/modules/surgery/remove_embedded_object.dm +++ b/code/modules/surgery/remove_embedded_object.dm @@ -1,9 +1,16 @@ /datum/surgery/embedded_removal name = "Removal of embedded objects" + desc = "Extracts objects stuck in the body such as throwing stars or spears." icon_state = "embedded_removal" steps = list(/datum/surgery_step/incise, /datum/surgery_step/remove_object, /datum/surgery_step/close) possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD) +/datum/surgery/repair_bone_hairline/can_start(mob/living/user, mob/living/carbon/target) + if(!istype(target)) + return FALSE + if(..()) + var/obj/item/bodypart/targeted_bodypart = target.get_bodypart(user.zone_selected) + return(targeted_bodypart.embedded_objects) /datum/surgery_step/remove_object name = "remove embedded objects" @@ -14,7 +21,6 @@ var/obj/item/target_item = null var/obj/item/bodypart/L = null - /datum/surgery_step/remove_object/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) L = surgery.operated_bodypart if(L) diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index fb9f77750be4..eae199ee97b5 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -4,25 +4,44 @@ var/icon = 'icons/misc/surgery_icons.dmi' var/icon_state var/status = 1 - var/list/steps = list() //Steps in a surgery - var/step_in_progress = 0 //Actively performing a Surgery - var/can_cancel = 1 //Can cancel this surgery after step 1 with cautery - var/list/target_mobtypes = list(/mob/living/carbon/human) //Acceptable Species - var/location = BODY_ZONE_CHEST //Surgery location - var/requires_bodypart_type = BODYPART_ORGANIC //Prevents you from performing an operation on incorrect limbs. 0 for any limb type - var/list/possible_locs = list() //Multiple locations - var/ignore_clothes = 0 //This surgery ignores clothes - var/mob/living/carbon/target //Operation target mob - var/obj/item/bodypart/operated_bodypart //Operable body part - var/datum/wound/operated_wound //The actual wound datum instance we're targeting - var/datum/wound/targetable_wound //The wound type this surgery targets - var/requires_bodypart = TRUE //Surgery available only when a bodypart is present, or only when it is missing. - var/success_multiplier = 0 //Step success propability multiplier - var/requires_real_bodypart = 0 //Some surgeries don't work on limbs that don't really exist - var/lying_required = TRUE //Does the vicitm needs to be lying down. - var/self_operable = FALSE //Can the surgery be performed on yourself. - var/requires_tech = FALSE //handles techweb-oriented surgeries, previously restricted to the /advanced subtype (You still need to add designs) - var/replaced_by //type; doesn't show up if this type exists. Set to /datum/surgery if you want to hide a "base" surgery (useful for typing parents IE healing.dm just make sure to null it out again) + /// Steps in a surgery + var/list/steps = list() + /// Actively performing a Surgery + var/step_in_progress = 0 + /// Can cancel this surgery after step 1 with cautery + var/can_cancel = 1 + /// Acceptable Species + var/list/target_mobtypes = list(/mob/living/carbon/human) + /// Surgery location + var/location = BODY_ZONE_CHEST + /// Prevents you from performing an operation on incorrect limbs. FALSE for any limb type + var/requires_bodypart_type = BODYPART_ORGANIC + /// Multiple locations + var/list/possible_locs = list() + /// If this surgery ignores clothes + var/ignore_clothes = 0 + /// Operation target mob + var/mob/living/carbon/target + /// Operable body part + var/obj/item/bodypart/operated_bodypart + /// The actual wound datum instance we're targeting + var/datum/wound/operated_wound + /// The wound type this surgery targets + var/datum/wound/targetable_wound + /// Surgery available only when a bodypart is present, or only when it is missing. + var/requires_bodypart = TRUE + /// Step success propability multiplier + var/success_multiplier = 0 + /// Some surgeries don't work on limbs that don't really exist + var/requires_real_bodypart = 0 + /// Does the vicitm needs to be lying down. + var/lying_required = TRUE + /// Can the surgery be performed on yourself. + var/self_operable = FALSE + /// Handles techweb-oriented surgeries, previously restricted to the /advanced subtype (You still need to add designs) + var/requires_tech = FALSE + /// Type; doesn't show up if this type exists. Set to /datum/surgery if you want to hide a "base" surgery (useful for typing parents IE healing.dm just make sure to null it out again) + var/replaced_by /datum/surgery/New(surgery_target, surgery_location, surgery_bodypart) ..() @@ -116,9 +135,14 @@ var/obj/item/tool = user.get_active_held_item() if(S.try_op(user, target, user.zone_selected, tool, src, try_to_fail)) return TRUE - if(tool.item_flags & SURGICAL_TOOL) //Just because you used the wrong tool it doesn't mean you meant to whack the patient with it - to_chat(user, span_warning("This step requires a different tool!")) - return TRUE + if(tool) + if(tool.tool_behaviour == TOOL_CAUTERY || (requires_bodypart_type == BODYPART_ROBOTIC && tool.tool_behaviour == TOOL_SCREWDRIVER)) + // Cancel the surgery if a cautery/screwdriver is used AND it's not the tool used in the next step. + attempt_cancel_surgery(src, tool, target, user) + return TRUE + if(tool.item_flags & SURGICAL_TOOL) //Just because you used the wrong tool it doesn't mean you meant to whack the patient with it + to_chat(user, span_warning("This step requires a different tool!")) + return TRUE return FALSE /datum/surgery/proc/get_surgery_step() diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm index 49bee8cb9ccb..2dc56a6b5f3d 100644 --- a/code/modules/surgery/surgery_step.dm +++ b/code/modules/surgery/surgery_step.dm @@ -113,6 +113,14 @@ prob_chance = implements[implement_type] prob_chance *= surgery.get_probability_multiplier() + // Blood splatters on tools and user + if(tool && prob(20)) + tool.add_mob_blood(target) + to_chat(user, span_warning("Your [tool] gets covered [target]'s blood ")) + if(prob(10)) + user.add_mob_blood(target) + to_chat(user, span_warning("You get covered [target]'s blood ")) + if((prob(prob_chance) || iscyborg(user)) && chem_check(target, user, tool) && !try_to_fail) if(success(user, target, target_zone, tool, surgery)) @@ -121,6 +129,7 @@ else if(failure(user, target, target_zone, tool, surgery)) play_failure_sound(user, target, target_zone, tool, surgery) + advance = TRUE if(!HAS_TRAIT(target, TRAIT_SURGERY_PREPARED) && target.stat != DEAD && !IS_IN_STASIS(target) && fuckup_damage) //not under the effects of anaesthetics or a strong painkiller, harsh penalty to success chance if(!issilicon(user) && !HAS_TRAIT(user, TRAIT_SURGEON)) //borgs and abductors are immune to this diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 2ccf6019a1a4..577773fe4322 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -13,7 +13,7 @@ w_class = WEIGHT_CLASS_TINY /obj/item/retractor/attack(mob/living/M, mob/user) - if(!attempt_initiate_surgery(src, M, user)) + if(user.a_intent == INTENT_HARM || !attempt_initiate_surgery(src, M, user)) ..() /obj/item/retractor/augment @@ -49,7 +49,7 @@ attack_verb = list("attacked", "pinched") /obj/item/hemostat/attack(mob/living/M, mob/user) - if(!attempt_initiate_surgery(src, M, user)) + if(user.a_intent == INTENT_HARM || !attempt_initiate_surgery(src, M, user)) ..() /obj/item/hemostat/augment @@ -86,7 +86,7 @@ attack_verb = list("burnt") /obj/item/cautery/attack(mob/living/M, mob/user) - if(!attempt_initiate_surgery(src, M, user)) + if(user.a_intent == INTENT_HARM || !attempt_initiate_surgery(src, M, user)) ..() /obj/item/cautery/augment @@ -135,7 +135,7 @@ return (MANUAL_SUICIDE) /obj/item/surgicaldrill/attack(mob/living/M, mob/user) - if(!attempt_initiate_surgery(src, M, user)) + if(user.a_intent == INTENT_HARM || !attempt_initiate_surgery(src, M, user)) ..() /obj/item/surgicaldrill/augment @@ -180,7 +180,7 @@ AddComponent(/datum/component/butchering, 80 * toolspeed, 100, 0) /obj/item/scalpel/attack(mob/living/M, mob/user) - if(!attempt_initiate_surgery(src, M, user)) + if(user.a_intent == INTENT_HARM || !attempt_initiate_surgery(src, M, user)) ..() /obj/item/scalpel/augment @@ -239,7 +239,7 @@ AddComponent(/datum/component/butchering, 40 * toolspeed, 100, 5, 'sound/weapons/circsawhit.ogg') //saws are very accurate and fast at butchering /obj/item/circular_saw/attack(mob/living/M, mob/user) - if(!attempt_initiate_surgery(src, M, user)) + if(user.a_intent == INTENT_HARM || !attempt_initiate_surgery(src, M, user)) ..() /obj/item/circular_saw/augment @@ -279,7 +279,7 @@ attack_verb = list("corrected", "properly set") /obj/item/bonesetter/attack(mob/living/M, mob/user) - if(!attempt_initiate_surgery(src, M, user)) + if(user.a_intent == INTENT_HARM || !attempt_initiate_surgery(src, M, user)) ..() /obj/item/bonesetter/bone @@ -300,7 +300,7 @@ attack_verb = list("slapped") /obj/item/surgical_drapes/attack(mob/living/M, mob/user) - if(!attempt_initiate_surgery(src, M, user)) + if(user.a_intent == INTENT_HARM || !attempt_initiate_surgery(src, M, user)) ..() /obj/item/surgical_drapes/goliath diff --git a/icons/misc/surgery_icons.dmi b/icons/misc/surgery_icons.dmi index 45d5b89dfb55c62e15165cd51648ee229447fa3f..9d2abbf3b18060ed531de39af6aa3fcae0b6ce27 100644 GIT binary patch literal 4400 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 literal 3359 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 Date: Sat, 25 Jun 2022 17:43:52 -0400 Subject: [PATCH 3/3] makeshift tool surgery --- code/_onclick/hud/radial.dm | 2 +- code/game/objects/items/kitchen.dm | 4 +++- code/game/objects/items/tools/crowbar.dm | 4 ++++ code/game/objects/items/tools/screwdriver.dm | 2 ++ code/game/objects/items/tools/weldingtool.dm | 4 ++++ code/game/objects/items/tools/wirecutters.dm | 2 ++ code/game/objects/items/tools/wrench.dm | 4 ++++ code/modules/surgery/organs/augments_arms.dm | 3 +-- 8 files changed, 21 insertions(+), 4 deletions(-) diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm index f9fa07185689..85e3914b8513 100644 --- a/code/_onclick/hud/radial.dm +++ b/code/_onclick/hud/radial.dm @@ -215,7 +215,7 @@ GLOBAL_LIST_EMPTY(radial_menus) E.add_overlay(choices_icons[choice_id]) var/datum/radial_menu_choice/choice_datum = choice_datums[choice_id] - if(istext(choice_datum.info)) + if(choice_datum && istext(choice_datum.info)) E.desc = choice_datum.info E.choice = choice_id diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm index f9dbc90fef4f..dd54d5b450d1 100644 --- a/code/game/objects/items/kitchen.dm +++ b/code/game/objects/items/kitchen.dm @@ -106,7 +106,9 @@ AddComponent(/datum/component/butchering, 80 - force, 100, force - 10) //bonus chance increases depending on force /obj/item/kitchen/knife/attack(mob/living/carbon/M, mob/living/carbon/user) - if(user.zone_selected == BODY_ZONE_PRECISE_EYES) + if(!user.a_intent == INTENT_HARM && attempt_initiate_surgery(src, M, user)) + return + else if(user.zone_selected == BODY_ZONE_PRECISE_EYES) if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) M = user return eyestab(M,user) diff --git a/code/game/objects/items/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm index c4e0c4483489..bbb6ccbf7112 100644 --- a/code/game/objects/items/tools/crowbar.dm +++ b/code/game/objects/items/tools/crowbar.dm @@ -20,6 +20,10 @@ toolspeed = 1 armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) +/obj/item/crowbar/attack(mob/living/M, mob/user) + if(user.a_intent == INTENT_HARM || !attempt_initiate_surgery(src, M, user)) + ..() + /obj/item/crowbar/suicide_act(mob/user) user.visible_message(span_suicide("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) diff --git a/code/game/objects/items/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm index 52e90d6bece8..f3fecffcfc4a 100644 --- a/code/game/objects/items/tools/screwdriver.dm +++ b/code/game/objects/items/tools/screwdriver.dm @@ -74,6 +74,8 @@ return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', icon_state) /obj/item/screwdriver/attack(mob/living/carbon/M, mob/living/carbon/user) + if(!user.a_intent == INTENT_HARM && attempt_initiate_surgery(src, M, user)) + return if(!istype(M)) return ..() if(user.zone_selected != BODY_ZONE_PRECISE_EYES && user.zone_selected != BODY_ZONE_HEAD) diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index 3bd3fa8f26fe..c1102c83554c 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -95,6 +95,10 @@ dyn_explosion(T, plasmaAmount/5)//20 plasma in a standard welder has a 4 power explosion. no breaches, but enough to kill/dismember holder qdel(src) +/obj/item/weldingtool/attack(mob/living/M, mob/user) + if(!isOn() || user.a_intent == INTENT_HARM || !attempt_initiate_surgery(src, M, user)) + ..() + /obj/item/weldingtool/afterattack(atom/O, mob/user, proximity) . = ..() if(!proximity) diff --git a/code/game/objects/items/tools/wirecutters.dm b/code/game/objects/items/tools/wirecutters.dm index 52e9fd2f2a3c..3dc2a749b2da 100644 --- a/code/game/objects/items/tools/wirecutters.dm +++ b/code/game/objects/items/tools/wirecutters.dm @@ -60,6 +60,8 @@ if(do_after(user, 1.5 SECONDS, C)) to_chat(C, span_notice("You succesfuly remove the durathread strand.")) C.remove_status_effect(STATUS_EFFECT_CHOKINGSTRAND) + else if(!user.a_intent == INTENT_HARM && attempt_initiate_surgery(src, C, user)) + return else ..() diff --git a/code/game/objects/items/tools/wrench.dm b/code/game/objects/items/tools/wrench.dm index 08585cf4ef53..77d1584505ba 100644 --- a/code/game/objects/items/tools/wrench.dm +++ b/code/game/objects/items/tools/wrench.dm @@ -20,6 +20,10 @@ toolspeed = 1 armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) +/obj/item/wrench/attack(mob/living/M, mob/user) + if(user.a_intent == INTENT_HARM || !attempt_initiate_surgery(src, M, user)) + ..() + /obj/item/wrench/suicide_act(mob/user) user.visible_message(span_suicide("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm index 10833bf57762..a1140682a993 100644 --- a/code/modules/surgery/organs/augments_arms.dm +++ b/code/modules/surgery/organs/augments_arms.dm @@ -325,8 +325,7 @@ /obj/item/toolset_handler/attack(mob/living/M, mob/user) if(active_tool) - if(istype(active_tool, /obj/item/surgical_drapes)) //of all the things to not have a tool behavior its drapes - attempt_initiate_surgery(src, M, user) + if(!(user.a_intent == INTENT_HARM) && attempt_initiate_surgery(active_tool, M, user)) return ..()