Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serverlink implant + traitor variant! #854

Merged
merged 6 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion code/__DEFINES/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_SPINNING_WEB_TURF "spinning_web_turf"
#define TRAIT_ABDUCTOR_TRAINING "abductor-training"
#define TRAIT_ABDUCTOR_SCIENTIST_TRAINING "abductor-scientist-training"
#define TRAIT_SURGEON "surgeon"
//#define TRAIT_SURGEON "surgeon" // monke edit: replace with TRAIT_ALL_SURGERIES and TRAIT_PERFECT_SURGEON
#define TRAIT_STRONG_GRABBER "strong_grabber"
#define TRAIT_SOOTHED_THROAT "soothed-throat"
#define TRAIT_BOOZE_SLIDER "booze-slider"
Expand Down
2 changes: 2 additions & 0 deletions code/__DEFINES/~monkestation/DNA.dm
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
#define SPECIES_GOLEM_CLOCKWORK "clock_golem"

#define ORGAN_SLOT_BRAIN_SURGICAL_IMPLANT "brain_surgical"
5 changes: 4 additions & 1 deletion code/__DEFINES/~monkestation/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
#define TRAIT_NO_SLAB_INVOKE "no_slab_invoke"
/// Indicates that they've inhaled helium.
#define TRAIT_HELIUM "helium"

/// Allows the user to start any surgery, anywhere. Mostly used by abductor scientists.
#define TRAIT_ALL_SURGERIES "all_surgeries"
/// Prevents the user from ever (unintentionally) failing a surgery step, and ensures they always have the maximum surgery speed.
#define TRAIT_PERFECT_SURGEON "perfect_surgeon"
/// Station trait for when the clown has bridge access *shudders*
#define STATION_TRAIT_CLOWN_BRIDGE "clown_bridge"
3 changes: 2 additions & 1 deletion code/_globalvars/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_THERMAL_VISION" = TRAIT_THERMAL_VISION,
"TRAIT_ABDUCTOR_TRAINING" = TRAIT_ABDUCTOR_TRAINING,
"TRAIT_ABDUCTOR_SCIENTIST_TRAINING" = TRAIT_ABDUCTOR_SCIENTIST_TRAINING,
"TRAIT_SURGEON" = TRAIT_SURGEON,
"TRAIT_ALL_SURGERIES" = TRAIT_ALL_SURGERIES, // monke edit: TRAIT_ALL_SURGERIES
"TRAIT_PERFECT_SURGEON" = TRAIT_PERFECT_SURGEON, // monke edit: TRAIT_PERFECT_SURGEON
"TRAIT_STRONG_GRABBER" = TRAIT_STRONG_GRABBER,
"TRAIT_SOOTHED_THROAT" = TRAIT_SOOTHED_THROAT,
"TRAIT_BOOZE_SLIDER" = TRAIT_BOOZE_SLIDER,
Expand Down
4 changes: 2 additions & 2 deletions code/modules/antagonists/abductor/abductor.dm
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,11 @@
break

/datum/antagonist/abductor/scientist/on_gain()
owner.add_traits(list(TRAIT_ABDUCTOR_SCIENTIST_TRAINING, TRAIT_SURGEON), ABDUCTOR_ANTAGONIST)
owner.add_traits(list(TRAIT_ABDUCTOR_SCIENTIST_TRAINING, TRAIT_ALL_SURGERIES), ABDUCTOR_ANTAGONIST) // monke edit: TRAIT_ALL_SURGERIES
return ..()

/datum/antagonist/abductor/scientist/on_removal()
owner.remove_traits(list(TRAIT_ABDUCTOR_SCIENTIST_TRAINING, TRAIT_SURGEON), ABDUCTOR_ANTAGONIST)
owner.remove_traits(list(TRAIT_ABDUCTOR_SCIENTIST_TRAINING, TRAIT_ALL_SURGERIES), ABDUCTOR_ANTAGONIST) // monke edit: TRAIT_ALL_SURGERIES
return ..()

/datum/antagonist/abductor/admin_add(datum/mind/new_owner,mob/admin)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/surgery/surgery.dm
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
return FALSE

// True surgeons (like abductor scientists) need no instructions
if(HAS_TRAIT(user, TRAIT_SURGEON) || (!isnull(user.mind) && HAS_TRAIT(user.mind, TRAIT_SURGEON)))
if(HAS_TRAIT(user, TRAIT_ALL_SURGERIES) || (!isnull(user.mind) && HAS_TRAIT(user.mind, TRAIT_ALL_SURGERIES))) // monke edit: TRAIT_ALL_SURGERIES
if(replaced_by) // only show top-level surgeries
return FALSE
else
Expand Down
8 changes: 5 additions & 3 deletions code/modules/surgery/surgery_step.dm
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
if(!tool)
success = TRUE
if(iscyborg(user))
success = TRUE
success = TRUE

if(accept_any_item)
if(tool && tool_check(user, tool))
Expand Down Expand Up @@ -96,13 +96,15 @@

if(iscyborg(user))//any immunities to surgery slowdown should go in this check.
modded_time = time
else if(HAS_TRAIT(user, TRAIT_PERFECT_SURGEON))
modded_time = min(round(time * 0.75, 5), modded_time) // monke edit: perfect surgeon will always be at least 25% faster than normal

var/was_sleeping = (target.stat != DEAD && target.IsSleeping())

if(do_after(user, modded_time, target = target, interaction_key = user.has_status_effect(/datum/status_effect/hippocratic_oath) ? target : DOAFTER_SOURCE_SURGERY)) //If we have the hippocratic oath, we can perform one surgery on each target, otherwise we can only do one surgery in total.
if(do_after(user, modded_time, target = target, interaction_key = HAS_TRAIT(user, TRAIT_PERFECT_SURGEON) ? target : DOAFTER_SOURCE_SURGERY)) //If we have perfect surgery, we can perform one surgery on each target, otherwise we can only do one surgery in total.

var/chem_check_result = chem_check(target)
if((prob(100-fail_prob) || (iscyborg(user) && !silicons_obey_prob)) && chem_check_result && !try_to_fail)
if((HAS_TRAIT(user, TRAIT_PERFECT_SURGEON) || prob(100-fail_prob) || (iscyborg(user) && !silicons_obey_prob)) && chem_check_result && !try_to_fail) // monke edit: TRAIT_PERFECT_SURGEON

if(success(user, target, target_zone, tool, surgery))
play_success_sound(user, target, target_zone, tool, surgery)
Expand Down
7 changes: 7 additions & 0 deletions monkestation/code/datums/status_effects/buffs.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/datum/status_effect/hippocratic_oath/on_apply()
. = ..()
ADD_TRAIT(owner, TRAIT_PERFECT_SURGEON, HIPPOCRATIC_OATH_TRAIT)

/datum/status_effect/hippocratic_oath/on_remove()
. = ..()
REMOVE_TRAIT(owner, TRAIT_PERFECT_SURGEON, HIPPOCRATIC_OATH_TRAIT)
7 changes: 7 additions & 0 deletions monkestation/code/modules/cargo/packs/medical.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/datum/supply_pack/medical/serverlink_implant
name = "Serverlink Implant Set"
desc = "A crate containing two implants, which can be surgically implanted to download advanced surgical knowledge into the user's brain."
cost = CARGO_CRATE_VALUE * 8
access = ACCESS_SURGERY
contains = list(/obj/item/organ/internal/cyberimp/brain/linked_surgery = 2)
crate_name = "serverlink implant crate"
13 changes: 13 additions & 0 deletions monkestation/code/modules/research/designs/medical_designs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,16 @@
RND_CATEGORY_TOOLS + RND_SUBCATEGORY_TOOLS_MEDICAL
)
departmental_flags = DEPARTMENT_BITFLAG_MEDICAL

/datum/design/linked_surgery
name = "surgical serverlink brain implant"
desc = "A brain implant with a bluespace technology that lets you perform an advanced surgery through your station research server."
id = "linked_surgery"
build_path = /obj/item/organ/internal/cyberimp/brain/linked_surgery
build_type = PROTOLATHE | AWAY_LATHE | MECHFAB
materials = list(/datum/material/iron = 600, /datum/material/glass = 600, /datum/material/silver = 500, /datum/material/gold = 1000, /datum/material/bluespace = 250)
construction_time = 6 SECONDS
category = list(
RND_CATEGORY_CYBERNETICS + RND_SUBCATEGORY_CYBERNETICS_IMPLANTS_UTILITY
)
departmental_flags = DEPARTMENT_BITFLAG_MEDICAL
11 changes: 11 additions & 0 deletions monkestation/code/modules/research/techweb/all_nodes.dm
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,14 @@
"mag_autorifle_ic",
)
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)

/datum/techweb_node/linked_surgery
id = "linked_surgery"
display_name = "Surgical Serverlink Brain Implant"
description = "A bluespace implant which a holder can read surgical programs from their server with."
prereq_ids = list("exp_surgery", "micro_bluespace")
design_ids = list("linked_surgery")
boost_item_paths = list(/obj/item/organ/internal/cyberimp/brain/linked_surgery)
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000)
hidden = TRUE
experimental = TRUE
126 changes: 126 additions & 0 deletions monkestation/code/modules/surgery/organs/augments.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,129 @@
desc = "An internal power cord hooked up to a battery. Useful if you run on volts."
contents = newlist(/obj/item/apc_powercord)
zone = "l_arm"

/obj/item/organ/internal/cyberimp/brain/linked_surgery
name = "surgical serverlink brain implant"
desc = "A brain implant with a bluespace technology that lets you perform an advanced surgery through your station research server."
slot = ORGAN_SLOT_BRAIN_SURGICAL_IMPLANT
actions_types = list(/datum/action/item_action/organ_action/toggle)
var/list/loaded_surgeries = list()
var/static/datum/techweb/linked_techweb
Comment on lines +12 to +13
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code doc these


/obj/item/organ/internal/cyberimp/brain/linked_surgery/Initialize()
. = ..()
if(isnull(linked_techweb))
linked_techweb = SSresearch.science_tech

/obj/item/organ/internal/cyberimp/brain/linked_surgery/proc/on_step_completion(mob/living/user, datum/surgery_step/current_step, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

SIGNAL_HANDLER
if(CHECK_BITFIELD(organ_flags, ORGAN_FAILING))
return
var/possible_steps = list()
if(current_step.repeatable)
possible_steps += "[current_step.name]"
var/datum/surgery_step/next_step = surgery.get_surgery_next_step()
if(!isnull(next_step))
possible_steps += "[next_step.name]"
qdel(next_step)
if(length(possible_steps))
target.balloon_alert(owner, "next step: [english_list(possible_steps, and_text = " or ")]")
else
target.balloon_alert(owner, "surgery done!")


/obj/item/organ/internal/cyberimp/brain/linked_surgery/proc/check_surgery(mob/user, datum/surgery/surgery, mob/patient)
SIGNAL_HANDLER
if(CHECK_BITFIELD(organ_flags, ORGAN_FAILING))
return
if(surgery.replaced_by in loaded_surgeries)
return COMPONENT_CANCEL_SURGERY
if(surgery.type in loaded_surgeries)
return COMPONENT_FORCE_SURGERY

/obj/item/organ/internal/cyberimp/brain/linked_surgery/on_insert(mob/living/carbon/organ_owner, special)
. = ..()
update_surgeries(download_from_held = FALSE, silent = TRUE)
RegisterSignal(organ_owner, COMSIG_SURGERY_STARTING, PROC_REF(check_surgery))
RegisterSignal(organ_owner, COMSIG_MOB_SURGERY_STEP_SUCCESS, PROC_REF(on_step_completion))

/obj/item/organ/internal/cyberimp/brain/linked_surgery/on_remove(mob/living/carbon/organ_owner, special)
. = ..()
UnregisterSignal(organ_owner, list(COMSIG_SURGERY_STARTING, COMSIG_MOB_SURGERY_STEP_SUCCESS))

/obj/item/organ/internal/cyberimp/brain/linked_surgery/ui_action_click(mob/user, actiontype)
if(CHECK_BITFIELD(organ_flags, ORGAN_FAILING))
to_chat(user, span_warning("\The [src] does not respond!"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

\the is unneeded

return
update_surgeries()

/obj/item/organ/internal/cyberimp/brain/linked_surgery/proc/update_surgeries(download_from_held = TRUE, silent = FALSE)
var/list/prev_amt = length(loaded_surgeries)
for(var/design in linked_techweb.researched_designs)
var/datum/design/surgery/surgery_design = SSresearch.techweb_design_by_id(design)
if(!istype(surgery_design))
continue
loaded_surgeries |= surgery_design.surgery
if(download_from_held)
for(var/held_item in owner.held_items)
if(!held_item)
continue
var/list/surgeries_to_add = list()
if(istype(held_item, /obj/item/disk/surgery))
var/obj/item/disk/surgery/surgery_disk = held_item
for(var/surgery in surgery_disk.surgeries)
surgeries_to_add |= surgery
else if(istype(held_item, /obj/item/disk/tech_disk))
var/obj/item/disk/tech_disk/tech_disk = held_item
for(var/design in tech_disk.stored_research.researched_designs)
var/datum/design/surgery/surgery_design = SSresearch.techweb_design_by_id(design)
if(!istype(surgery_design))
continue
surgeries_to_add |= surgery_design.surgery
else if(istype(held_item, /obj/item/disk/nuclear))
// funny joke message
if(!silent)
to_chat(owner, span_warning("Do you <i>want</i> to explode? You can't get surgery data from \the [held_item]!"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
to_chat(owner, span_warning("Do you <i>want</i> to explode? You can't get surgery data from \the [held_item]!"))
to_chat(owner, span_warning("Do you <i>want</i> to explode? You can't get surgery data from [held_item]!"))

continue
else
continue
if(!length(surgeries_to_add))
owner.balloon_alert(owner, "no new surgery data found")
continue
owner.balloon_alert(owner, "downloading surgery data...")
if(!do_after(owner, 5 SECONDS, held_item))
owner.balloon_alert(owner, "surgery download interrupted!")
return
loaded_surgeries |= surgeries_to_add
if(silent)
return
var/new_amt = length(loaded_surgeries)
var/diff = new_amt - prev_amt
if(diff)
owner.balloon_alert(owner, "installed [diff] new surgeries, [new_amt] total loaded")
else
owner.balloon_alert(owner, "no new surgery data found")

/obj/item/organ/internal/cyberimp/brain/linked_surgery/perfect
name = "hacked surgical serverlink brain implant"
desc = "A brain implant with a bluespace technology that lets you perform any advanced surgery through hacked Nanotrasen servers."
organ_flags = ORGAN_SYNTHETIC | ORGAN_HIDDEN
organ_traits = list(TRAIT_PERFECT_SURGEON)
actions_types = null
var/list/blocked_surgeries = list(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code doc

/datum/surgery/advanced/brainwashing_sleeper,
/datum/surgery/advanced/necrotic_revival,
/datum/surgery/organ_extraction
)

/obj/item/organ/internal/cyberimp/brain/linked_surgery/perfect/update_surgeries(download_from_held = TRUE, silent = FALSE)
loaded_surgeries.Cut()
for(var/datum/surgery/surgery as() in GLOB.surgeries_list)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as anything is the proper way

if(surgery.type in blocked_surgeries)
continue
if(!length(surgery.steps))
continue
loaded_surgeries |= surgery.type

/obj/item/organ/internal/cyberimp/brain/linked_surgery/perfect/debug
blocked_surgeries = list()
2 changes: 2 additions & 0 deletions monkestation/code/modules/surgery/organs/autosurgeon.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/obj/item/autosurgeon/syndicate/hacked_linked_surgery
starting_organ = /obj/item/organ/internal/cyberimp/brain/linked_surgery/perfect
10 changes: 10 additions & 0 deletions monkestation/code/modules/uplink/uplink_items/job.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,13 @@

/datum/uplink_item/role_restricted/modified_syringe_gun
surplus = 50

/datum/uplink_item/role_restricted/hacked_linked_surgery
name = "Syndicate Surgery Implant"
desc = "A powerful brain implant, capable of uploading perfect, forbidden surgical knowledge to its users mind, \
allowing them to do just about any surgery, anywhere, without making any (unintentional) mistakes. \
Comes with a syndicate autosurgeon for immediate self-application."
cost = 12
item = /obj/item/autosurgeon/syndicate/hacked_linked_surgery
restricted_roles = list(JOB_CHIEF_MEDICAL_OFFICER, JOB_MEDICAL_DOCTOR, JOB_PARAMEDIC, JOB_ROBOTICIST)
surplus = 50
3 changes: 3 additions & 0 deletions tgstation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -5653,6 +5653,7 @@
#include "monkestation\code\datums\quirks\positive_quirks.dm"
#include "monkestation\code\datums\station_traits\negative_traits.dm"
#include "monkestation\code\datums\station_traits\neutral_traits.dm"
#include "monkestation\code\datums\status_effects\buffs.dm"
#include "monkestation\code\datums\status_effects\disorient.dm"
#include "monkestation\code\datums\status_effects\food_buffs.dm"
#include "monkestation\code\datums\wires\particle_accelerator.dm"
Expand Down Expand Up @@ -6021,6 +6022,7 @@
#include "monkestation\code\modules\cargo\crates\security.dm"
#include "monkestation\code\modules\cargo\crates\service.dm"
#include "monkestation\code\modules\cargo\markets\market_items.dm"
#include "monkestation\code\modules\cargo\packs\medical.dm"
#include "monkestation\code\modules\cargoborg\code\cargo_module.dm"
#include "monkestation\code\modules\cargoborg\code\cargo_teleporter.dm"
#include "monkestation\code\modules\cargoborg\code\cargoborg_items.dm"
Expand Down Expand Up @@ -6598,6 +6600,7 @@
#include "monkestation\code\modules\surgery\bodyparts\oozeling_bodyparts.dm"
#include "monkestation\code\modules\surgery\bodyparts\simian_bodyparts.dm"
#include "monkestation\code\modules\surgery\organs\augments.dm"
#include "monkestation\code\modules\surgery\organs\autosurgeon.dm"
#include "monkestation\code\modules\surgery\organs\external\anime.dm"
#include "monkestation\code\modules\surgery\organs\external\floran_accessories.dm"
#include "monkestation\code\modules\surgery\organs\external\goblin_accessories.dm"
Expand Down
Loading