Files
Aeri 9036e5bd26 Protean surgery and also spellcheck I guess (#5683)
# About The Pull Request
Restores Protean self-surgery, which was broken by the TG surgery system
rework. The rework introduced required_bodytype gating on all mechanical
surgery operations and an OPERATION_SELF_OPERABLE flag requirement for
self-targeting. Protean limbs use BODYTYPE_NANO, which was never added
to any of these checks, leaving Proteans unable to access the synth
flavored surgery operations they're intended to have and locked out of
self-surgery entirely.

The fix adds BODYTYPE_NANO to the required_bodytype of all six
preparatory mechanical operations in operation_generic_mechanic.dm
(unscrew shell, open hatch, screw shell, prepare electronics,
unwrench/wrench endoskeleton) and to the two prosthetic organ/feature
manipulation operations in operation_organ_manip.dm.

Synths were already handled by a prior Nova edit that added
BODYTYPE_SYNTHETIC; this PR extends the same treatment to Proteans and
logs it with a Bubber Edit comment.

As a drive-by shooting fix, I also changed a persistent "Orginal" [sic]
typo in BUBBER/NOVA EDIT comments across six surgery operation files.
These were copied verbatim from the original Nova edit and propagated
into every subsequent edit comment in the directory.

# Why It's Good For The Game
Proteans are a Bubberstation-original species with self-surgery as
intended functionality. The TG surgery rework silently broke this
without any corresponding fix being applied downstream. A surgeon could
still operate on a Protean using organic surgical tools but this is
sub-optimal and annoying.

# Proof Of Testing
Spawned as Protean, laid down on a table, applied surgical drapes,
worked through the full mechanical surgery chain on myself. Do you
really need a screenshot of me laying on a table?


🆑
fix: Protean self-surgery now works correctly after the TG surgery
rework broke it
fix: Surgeons can now use mechanical tools on Proteans as intended,
consistent with Synth behaviour
spellcheck: Fixed "Orginal" typo in NOVA/BUBBER EDIT comments across six
surgery operation files
/🆑
2026-05-26 21:08:50 -04:00

110 lines
4.1 KiB
Plaintext

/datum/surgery_operation/limb/lipoplasty
name = "excise excess fat"
rnd_name = "Lipoplasty (Excise Fat)"
desc = "Remove excess fat from a patient's body."
operation_flags = OPERATION_NOTABLE | OPERATION_AFFECTS_MOOD
implements = list(
TOOL_SAW = 1,
TOOL_SCALPEL = 1.25,
/obj/item/shovel/serrated = 1.33,
/obj/item/melee/energy/sword = 1.33,
/obj/item/hatchet = 3.33,
/obj/item/knife = 3.33,
/obj/item = 5,
)
time = 6.4 SECONDS
required_bodytype = (~BODYTYPE_ROBOTIC & ~BODYTYPE_SYNTHETIC) // NOVA EDIT CHANGE - SYNTH FLAGS -Original: required_bodytype = ~BODYTYPE_ROBOTIC
preop_sound = list(
/obj/item/circular_saw = 'sound/items/handling/surgery/saw.ogg',
/obj/item = 'sound/items/handling/surgery/scalpel1.ogg',
)
success_sound = 'sound/items/handling/surgery/organ2.ogg'
all_surgery_states_required = SURGERY_SKIN_OPEN
any_surgery_states_blocked = SURGERY_VESSELS_UNCLAMPED
/datum/surgery_operation/limb/lipoplasty/get_any_tool()
return "Any sharp edged item"
/datum/surgery_operation/limb/lipoplasty/get_default_radial_image()
return image(/obj/item/food/meat/slab/human)
/datum/surgery_operation/limb/lipoplasty/all_required_strings()
. = list()
. += "operate on chest (target chest)"
. += ..()
. += "the patient must have excess fat to remove"
/datum/surgery_operation/limb/lipoplasty/tool_check(obj/item/tool)
// Require edged sharpness OR a tool behavior match
return ((tool.get_sharpness() & SHARP_EDGED) || implements[tool.tool_behaviour])
/datum/surgery_operation/limb/lipoplasty/state_check(obj/item/bodypart/limb)
if(limb.body_zone != BODY_ZONE_CHEST)
return FALSE
if(HAS_TRAIT(limb.owner, TRAIT_NOHUNGER))
return FALSE
if(!HAS_TRAIT_FROM(limb.owner, TRAIT_FAT, OBESITY) || limb.owner.nutrition < NUTRITION_LEVEL_WELL_FED)
return FALSE
return TRUE
/datum/surgery_operation/limb/lipoplasty/on_preop(obj/item/bodypart/limb, mob/living/surgeon, obj/item/tool, list/operation_args)
display_results(
surgeon,
limb.owner,
span_notice("You begin to cut away [limb.owner]'s excess fat..."),
span_notice("[surgeon] begins to cut away [limb.owner]'s excess fat."),
span_notice("[surgeon] begins to cut [limb.owner]'s [limb.plaintext_zone] with [tool]."),
)
display_pain(limb.owner, "You feel a stabbing in your [limb.plaintext_zone]!")
/datum/surgery_operation/limb/lipoplasty/on_success(obj/item/bodypart/limb, mob/living/surgeon, obj/item/tool, list/operation_args)
display_results(
surgeon,
limb.owner,
span_notice("You successfully remove excess fat from [limb.owner]'s body!"),
span_notice("[surgeon] successfully removes excess fat from [limb.owner]'s body!"),
span_notice("[surgeon] finishes cutting away excess fat from [limb.owner]'s [limb.plaintext_zone]."),
)
var/removednutriment = limb.owner.nutrition
limb.owner.overeatduration = 0 //patient is unfatted
limb.owner.set_nutrition(NUTRITION_LEVEL_WELL_FED)
removednutriment -= NUTRITION_LEVEL_WELL_FED //whatever was removed goes into the meat
if(limb.owner.flags_1 & HOLOGRAM_1)
return
var/typeofmeat = null
for(var/meat_path in limb.butcher_drops)
if(ispath(meat_path, /obj/item/food/meat))
typeofmeat = meat_path
break
if(!typeofmeat)
return
var/obj/item/food/meat/slab/newmeat = new typeofmeat(limb.owner.drop_location())
newmeat.name = "fatty meat"
newmeat.desc = "Extremely fatty tissue taken from a patient."
newmeat.subjectname = limb.owner.real_name
newmeat.subjectjob = limb.owner.job
newmeat.reagents.add_reagent(/datum/reagent/consumable/nutriment, (removednutriment / /datum/reagent/consumable/nutriment::nutriment_factor))
/datum/surgery_operation/limb/lipoplasty/mechanic
name = "engage expulsion valve" //gross
rnd_name = "Nutrient Reserve Expulsion (Excise Fat)"
implements = list(
TOOL_WRENCH = 1.05,
TOOL_CROWBAR = 1.05,
/obj/item/shovel/serrated = 1.33,
/obj/item/melee/energy/sword = 1.33,
TOOL_SAW = 1.67,
/obj/item/hatchet = 3.33,
/obj/item/knife = 3.33,
TOOL_SCALPEL = 4,
/obj/item = 5,
)
preop_sound = 'sound/items/tools/ratchet.ogg'
success_sound = 'sound/items/handling/surgery/organ2.ogg'
required_bodytype = BODYTYPE_ROBOTIC
operation_flags = parent_type::operation_flags | OPERATION_MECHANIC