Adds the self-surgery skillchip as a fairly rare black market item (#91606)

## About The Pull Request

This PR adds a skillchip that allows the user to perform normal
surgeries on themselves, albeit with a 1.5x speed penalty and a flat 33%
increase to the probability of screwing up each step. You can find this
skillchip occasionally on the black market. It is also contraband, and
can be detected by n-spect scanners.

## Why It's Good For The Game

Provides a risky alternate means of obtaining surgical intervention,
such as if you either can't trust anybody else to do surgery on you or
can't be trusted to have certain surgeries done on you.

## Changelog

🆑
add: The Centcom Department of Import Control has become aware of the
use of highly-illegal and medically dubious self-surgery skillchips
aboard company stations. We suspect they are being sold to the station
through the black market.
/🆑
This commit is contained in:
Y0SH1M4S73R
2025-07-05 17:43:54 +10:00
committed by GitHub
parent 58d23eb77f
commit fa573fa539
9 changed files with 77 additions and 4 deletions
@@ -326,3 +326,11 @@
/// From /obj/item/book/bible/attack() : (mob/living/user, obj/item/book/bible/bible, bless_result)
#define COMSIG_LIVING_BLESSED "living_blessed"
/// From /datum/surgery_step/initiate() : (mob/living/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, datum/surgery_step/step, list/modifiers)
#define COMSIG_LIVING_INITIATE_SURGERY_STEP "living_initiate_surgery_step"
#define COMSIG_LIVING_SURGERY_STEP_INITIATED_ON "living_surgery_step_initiated_on"
/// Index in modifiers containing the modifier to failure chance
#define FAIL_PROB_INDEX 1
/// Index in modifiers containing the modifer to surgery speed
#define SPEED_MOD_INDEX 2
+4
View File
@@ -1530,4 +1530,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Trait that signals to objects on this turf that its open (has UNDERFLOOR_INTERACTIBLE) but still covers them
#define TRAIT_UNCOVERED_TURF "uncovered_turf"
/// Trait that allows mobs to perform surgery on themselves
#define TRAIT_SELF_SURGERY "self_surgery"
// END TRAIT DEFINES
+1
View File
@@ -506,6 +506,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_SECURITY_HUD" = TRAIT_SECURITY_HUD,
"TRAIT_SEE_WORN_COLOURS" = TRAIT_SEE_WORN_COLOURS,
"TRAIT_SELF_AWARE" = TRAIT_SELF_AWARE,
"TRAIT_SELF_SURGERY" = TRAIT_SELF_SURGERY,
"TRAIT_SETTLER" = TRAIT_SETTLER,
"TRAIT_SHAVED" = TRAIT_SHAVED,
"TRAIT_SHELL_RETREATED" = TRAIT_SHELL_RETREATED,
+1 -1
View File
@@ -183,7 +183,7 @@
for(var/datum/surgery/operation as anything in surgeries)
if(IS_IN_INVALID_SURGICAL_POSITION(src, operation))
continue
if(!(operation.surgery_flags & SURGERY_SELF_OPERABLE) && (user == src))
if(!(operation.surgery_flags & SURGERY_SELF_OPERABLE) && (user == src) && !HAS_TRAIT(user, TRAIT_SELF_SURGERY))
continue
if(operation.next_step(user, modifiers))
return ITEM_INTERACT_SUCCESS
+1 -1
View File
@@ -90,7 +90,7 @@
continue
if(!is_type_in_list(target, surgery.target_mobtypes))
continue
if(user == target && !(surgery.surgery_flags & SURGERY_SELF_OPERABLE))
if(user == target && !HAS_TRAIT(user, TRAIT_SELF_SURGERY) && !(surgery.surgery_flags & SURGERY_SELF_OPERABLE))
continue
if(isnull(affecting))
@@ -203,3 +203,21 @@
))
new type(C)
return C
/datum/market_item/misc/self_surgery_skillchip
name = /obj/item/skillchip/self_surgery::name
desc = "Man, the insurance companies HATE this one. Damn fat-cats can't stand the idea of people treating their own illnesses - \
they'd rather you go to THEIR doctors, who THEY convinced to charge EXTORTIONARY prices the average Joe can't afford, all so you \
gotta sign on to THEIR packages. Most people end up paying for NOTHING for YEARS just so that they have a CHANCE at being able to afford \
treatment when they actually NEED it. \n\n Uh, what was I talking about again... Oh, yeah. This here skillchip'll let you put yourself under the knife. \
A must-have for the person who can't rely on anyone else."
item = /obj/item/skillchip/self_surgery
price_min = CARGO_CRATE_VALUE * 5
price_max = CARGO_CRATE_VALUE * 10
stock_max = 1
availability_prob = 15
/datum/market_item/misc/self_surgery_skillchip/buy(obj/item/market_uplink/uplink, mob/buyer, shipping_method, legal_status)
. = ..()
if(.)
availability_prob *= 0.5
@@ -0,0 +1,29 @@
/obj/item/skillchip/self_surgery
name = "4U70-P3R4710N skillchip"
desc = "A skillchip containing old Nanotrasen medical training protocols, which one could use to perform surgical operations on themselves. \
This one doesn't look like it's in the best condition - bit rot has probably rendered it somewhat risky to use."
auto_traits = list(TRAIT_SELF_SURGERY)
skill_name = "Self Surgery"
skill_description = "Allows you to perform surgery on yourself."
skill_icon = FA_ICON_USER_DOCTOR
activate_message = span_notice("You realize there's nothing stopping you from performing surgery on yourself.")
deactivate_message = span_notice("You suddenly feel like you should never perform surgery on yourself.")
/obj/item/skillchip/self_surgery/Initialize(mapload, is_removable)
. = ..()
ADD_TRAIT(src, TRAIT_CONTRABAND, INNATE_TRAIT)
/obj/item/skillchip/self_surgery/on_activate(mob/living/carbon/user, silent)
. = ..()
RegisterSignal(user, COMSIG_LIVING_INITIATE_SURGERY_STEP, PROC_REF(apply_surgery_penalty))
/obj/item/skillchip/self_surgery/on_deactivate(mob/living/carbon/user, silent)
. = ..()
UnregisterSignal(user, COMSIG_LIVING_INITIATE_SURGERY_STEP)
/obj/item/skillchip/self_surgery/proc/apply_surgery_penalty(mob/living/carbon/_source, mob/living/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, datum/surgery_step/step, list/modifiers)
SIGNAL_HANDLER
if(user != target)
return
modifiers[FAIL_PROB_INDEX] += 33
modifiers[SPEED_MOD_INDEX] *= 1.5
+14 -2
View File
@@ -130,8 +130,20 @@
var/modded_time = time * speed_mod
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
modded_time = min(modded_time, time * SURGERY_SLOWDOWN_CAP_MULTIPLIER)//also if that, then cap modded_time at time*modifier
fail_prob = max(0, modded_time - (time * SURGERY_SLOWDOWN_CAP_MULTIPLIER)) //if modded_time > time * modifier, then fail_prob = modded_time - time*modifier
var/list/user_modifiers = list(0, 1)
SEND_SIGNAL(user, COMSIG_LIVING_INITIATE_SURGERY_STEP, user, target, target_zone, tool, surgery, src, user_modifiers)
fail_prob += user_modifiers[FAIL_PROB_INDEX]
modded_time *= user_modifiers[SPEED_MOD_INDEX]
var/list/target_modifiers = list(0, 1)
SEND_SIGNAL(target, COMSIG_LIVING_SURGERY_STEP_INITIATED_ON, user, target, target_zone, tool, surgery, src, target_modifiers)
fail_prob += target_modifiers[FAIL_PROB_INDEX]
modded_time *= target_modifiers[SPEED_MOD_INDEX]
fail_prob = min(max(0, fail_prob),99) // clamp fail_prob between 0 and 99
modded_time = min(modded_time, time * SURGERY_SLOWDOWN_CAP_MULTIPLIER)// cap modded_time at time*modifier
if(iscyborg(user))//any immunities to surgery slowdown should go in this check.
modded_time = time * tool.toolspeed
+1
View File
@@ -4647,6 +4647,7 @@
#include "code\modules\library\skill_learning\generic_skillchips\misc.dm"
#include "code\modules\library\skill_learning\generic_skillchips\musical.dm"
#include "code\modules\library\skill_learning\generic_skillchips\point.dm"
#include "code\modules\library\skill_learning\generic_skillchips\self_surgery.dm"
#include "code\modules\library\skill_learning\job_skillchips\_job.dm"
#include "code\modules\library\skill_learning\job_skillchips\chef.dm"
#include "code\modules\library\skill_learning\job_skillchips\clown.dm"