Files
Pooble aaeb5fdf28 Skin Masquerade: Epidermal Applicator, Lifelike Quirk, and the Skinmonger Implant (#31185)
* adds the epidermal applicator, lifelike quirk, and skinmonger traitor implant

* lint

* lint

* attack chain fix

* more linty fixes

* more lint

* fix some buggy bugs, synthetic skinned body parts recolor to their host

* make emp on skinmonger work, fix a skinmonger bug

* make bruising / denting examine text not betray the masquerade

* burn away synthetic skin with acid

* comment / code structure / description tweaks

* i sell pharmaceuticals and pharmaceutical accessories

* code review comments

* oops

* god damn it

* god damn it (x2)

* Update code/modules/surgery/organs/augments_internal.dm

Co-authored-by: 1080pCat <96908085+1080pCat@users.noreply.github.com>
Signed-off-by: Pooble <90473506+poobsie@users.noreply.github.com>

* lower syndi level for implant

* Update code/modules/research/designs/medical_designs.dm

Co-authored-by: JimKil3 <47290811+JimKil3@users.noreply.github.com>
Signed-off-by: Pooble <90473506+poobsie@users.noreply.github.com>

* Update code/game/objects/items/tools/epidermal_applicator.dm

Co-authored-by: JimKil3 <47290811+JimKil3@users.noreply.github.com>
Signed-off-by: Pooble <90473506+poobsie@users.noreply.github.com>

* Update code/modules/surgery/organs/organ_external.dm

Co-authored-by: JimKil3 <47290811+JimKil3@users.noreply.github.com>
Signed-off-by: Pooble <90473506+poobsie@users.noreply.github.com>

* Update code/modules/surgery/organs/organ_external.dm

Co-authored-by: JimKil3 <47290811+JimKil3@users.noreply.github.com>
Signed-off-by: Pooble <90473506+poobsie@users.noreply.github.com>

* tweaks for review

* Update code/__DEFINES/dcs/datum_signals.dm

Co-authored-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com>
Signed-off-by: Pooble <90473506+poobsie@users.noreply.github.com>

---------

Signed-off-by: Pooble <90473506+poobsie@users.noreply.github.com>
Co-authored-by: 1080pCat <96908085+1080pCat@users.noreply.github.com>
Co-authored-by: JimKil3 <47290811+JimKil3@users.noreply.github.com>
Co-authored-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com>
2026-03-22 22:08:25 +00:00

1294 lines
54 KiB
Plaintext

/obj/item/organ/internal/cyberimp
name = "cybernetic implant"
desc = "a state-of-the-art implant that improves a baseline's functionality."
status = ORGAN_ROBOT
var/implant_color = "#FFFFFF"
var/implant_overlay
var/crit_fail = FALSE //Used by certain implants to disable them.
tough = TRUE // Immune to damage
augment_state ='icons/mob/human_races/robotic.dmi'
/obj/item/organ/internal/cyberimp/Initialize(mapload, mob/M = null)
. = ..()
if(implant_overlay)
var/mutable_appearance/overlay = mutable_appearance(icon, implant_overlay)
overlay.color = implant_color
add_overlay(overlay)
/obj/item/organ/internal/cyberimp/emp_act()
return // These shouldn't be hurt by EMPs in the standard way
/obj/item/organ/internal/cyberimp/examine(mob/user)
. = ..()
. += SPAN_NOTICE("It looks like it belongs in the [parse_zone(parent_organ)].")
//[[[[BRAIN]]]]
/obj/item/organ/internal/cyberimp/brain
name = "cybernetic brain implant"
desc = "injectors of extra sub-routines for the brain."
icon_state = "brain_implant"
implant_overlay = "brain_implant_overlay"
parent_organ = "head"
materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_SILVER = 500, MAT_GOLD = 1000)
/obj/item/organ/internal/cyberimp/brain/emp_act(severity)
if(!owner || emp_proof)
return
var/weaken_time = (5 + (severity - 1 ? 0 : 5)) STATUS_EFFECT_CONSTANT
owner.Weaken(weaken_time)
to_chat(owner, SPAN_WARNING("Your body seizes up!"))
return weaken_time
/obj/item/organ/internal/cyberimp/brain/anti_drop
name = "Anti-drop implant"
desc = "This cybernetic brain implant will allow you to force your hand muscles to contract, preventing item dropping. Twitch ear to toggle."
icon_state = "brain_implant_antidrop"
var/active = FALSE
var/l_hand_ignore = FALSE
var/r_hand_ignore = FALSE
var/obj/item/l_hand_obj = null
var/obj/item/r_hand_obj = null
implant_overlay = null
slot = "brain_antidrop"
origin_tech = "materials=4;programming=5;biotech=4"
actions_types = list(/datum/action/item_action/organ_action/toggle)
/obj/item/organ/internal/cyberimp/brain/anti_drop/ui_action_click()
active = !active
if(active)
l_hand_obj = owner.l_hand
r_hand_obj = owner.r_hand
if(l_hand_obj)
if(owner.l_hand.flags & NODROP)
l_hand_ignore = TRUE
else
owner.l_hand.set_nodrop(TRUE, owner)
l_hand_ignore = FALSE
if(r_hand_obj)
if(owner.r_hand.flags & NODROP)
r_hand_ignore = TRUE
else
owner.r_hand.set_nodrop(TRUE, owner)
r_hand_ignore = FALSE
if(!l_hand_obj && !r_hand_obj)
to_chat(owner, SPAN_NOTICE("You are not holding any items, your hands relax..."))
active = FALSE
else
var/msg = 0
msg += !l_hand_ignore && l_hand_obj ? 1 : 0
msg += !r_hand_ignore && r_hand_obj ? 2 : 0
switch(msg)
if(1)
to_chat(owner, SPAN_NOTICE("Your left hand's grip tightens."))
if(2)
to_chat(owner, SPAN_NOTICE("Your right hand's grip tightens."))
if(3)
to_chat(owner, SPAN_NOTICE("Both of your hand's grips tighten."))
else
release_items()
to_chat(owner, SPAN_NOTICE("Your hands relax..."))
l_hand_obj = null
r_hand_obj = null
/obj/item/organ/internal/cyberimp/brain/anti_drop/emp_act(severity)
if(!owner || emp_proof)
return
var/range = severity ? 10 : 5
var/atom/A
var/obj/item/L_item = owner.l_hand
var/obj/item/R_item = owner.r_hand
release_items()
..()
if(L_item)
A = pick(oview(range, owner))
L_item.throw_at(A, range, 2)
to_chat(owner, SPAN_NOTICE("Your left arm spasms and throws [L_item]!"))
l_hand_obj = null
if(R_item)
A = pick(oview(range, owner))
R_item.throw_at(A, range, 2)
to_chat(owner, SPAN_NOTICE("Your right arm spasms and throws [R_item]!"))
r_hand_obj = null
/obj/item/organ/internal/cyberimp/brain/anti_drop/proc/release_items()
active = FALSE
if(!l_hand_ignore && l_hand_obj)
l_hand_obj.set_nodrop(FALSE, owner)
if(!r_hand_ignore && r_hand_obj)
r_hand_obj.set_nodrop(FALSE, owner)
/obj/item/organ/internal/cyberimp/brain/anti_drop/remove(mob/living/carbon/M, special = 0)
if(active)
ui_action_click()
return ..()
/obj/item/organ/internal/cyberimp/brain/anti_drop/hardened
name = "Hardened Anti-drop implant"
desc = "A military-grade version of the standard implant, for NT's more elite forces."
origin_tech = "materials=6;programming=5;biotech=5"
materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_SILVER = 500, MAT_GOLD = 1000)
emp_proof = TRUE
/obj/item/organ/internal/cyberimp/brain/anti_stam
name = "CNS Rebooter implant"
desc = "This implant will automatically give you back control over your central nervous system, reducing downtime when fatigued. Incompatible with the Neural Jumpstarter."
icon_state = "brain_implant_rebooter"
slot = "brain_antistun"
origin_tech = "materials=5;programming=4;biotech=5"
/// How much we multiply the owners stamina regen block modifier by.
var/stamina_crit_time_multiplier = 0.4
/// Are we currently modifying somoeones stamina regen block modifier? If so, we will want to undo it on removal.
var/currently_modifying_stamina = FALSE
COOLDOWN_DECLARE(implant_cooldown)
/obj/item/organ/internal/cyberimp/brain/anti_stam/insert(mob/living/carbon/M, special = FALSE)
..()
RegisterSignal(M, COMSIG_CARBON_ENTER_STAMINACRIT, PROC_REF(on_enter))
RegisterSignal(M, COMSIG_CARBON_EXIT_STAMINACRIT, PROC_REF(on_exit))
RegisterSignal(M, COMSIG_CARBON_STAMINA_REGENERATED, PROC_REF(on_regen))
/obj/item/organ/internal/cyberimp/brain/anti_stam/remove(mob/living/carbon/M, special = FALSE)
UnregisterSignal(M, list(COMSIG_CARBON_ENTER_STAMINACRIT, COMSIG_CARBON_EXIT_STAMINACRIT, COMSIG_CARBON_STAMINA_REGENERATED))
on_exit()
return ..()
/obj/item/organ/internal/cyberimp/brain/anti_stam/proc/on_enter()
SIGNAL_HANDLER // COMSIG_CARBON_ENTER_STAMINACRIT
if(status & ORGAN_DEAD)
return
if(currently_modifying_stamina || !COOLDOWN_FINISHED(src, implant_cooldown))
return
owner.stamina_regen_block_modifier *= stamina_crit_time_multiplier
currently_modifying_stamina = TRUE
/obj/item/organ/internal/cyberimp/brain/anti_stam/proc/on_exit()
SIGNAL_HANDLER // COMSIG_CARBON_EXIT_STAMINACRIT
if(!currently_modifying_stamina)
return
owner.stamina_regen_block_modifier /= stamina_crit_time_multiplier
currently_modifying_stamina = FALSE
/obj/item/organ/internal/cyberimp/brain/anti_stam/proc/on_regen()
SIGNAL_HANDLER // COMSIG_CARBON_STAMINA_REGENERATED
owner.update_stamina() //This is here so they actually get unstaminacrit when it triggers, vs 2-4 seconds later
/obj/item/organ/internal/cyberimp/brain/anti_stam/emp_act(severity)
..()
COOLDOWN_START(src, implant_cooldown, 1 MINUTES / severity)
/obj/item/organ/internal/cyberimp/brain/anti_stam/hardened
name = "Hardened CNS Rebooter implant"
desc = "A military-grade version of the standard implant, for NT's more elite forces."
origin_tech = "materials=6;programming=5;biotech=5"
emp_proof = TRUE
/obj/item/organ/internal/cyberimp/brain/anti_sleep
name = "Neural Jumpstarter implant"
desc = "This implant will automatically attempt to jolt you awake when it detects you have fallen unconscious. Has a short cooldown, incompatible with the CNS Rebooter."
implant_color = "#0356fc"
slot = "brain_antistun" //one or the other not both.
origin_tech = "materials=5;programming=4;biotech=5"
var/cooldown = FALSE
/obj/item/organ/internal/cyberimp/brain/anti_sleep/on_life()
..()
if(crit_fail)
return
if(status & ORGAN_DEAD)
return FALSE
if(owner.stat == UNCONSCIOUS && !cooldown)
owner.AdjustSleeping(-200 SECONDS)
owner.AdjustParalysis(-200 SECONDS)
to_chat(owner, SPAN_NOTICE("You feel a rush of energy course through your body!"))
cooldown = TRUE
addtimer(CALLBACK(src, PROC_REF(sleepy_timer_end)), 50)
/obj/item/organ/internal/cyberimp/brain/anti_sleep/proc/sleepy_timer_end()
cooldown = FALSE
to_chat(owner, SPAN_NOTICE("You hear a small beep in your head as your Neural Jumpstarter finishes recharging."))
/obj/item/organ/internal/cyberimp/brain/anti_sleep/emp_act(severity)
. = ..()
if(crit_fail || emp_proof)
return
crit_fail = TRUE
owner.AdjustSleeping(400 SECONDS)
cooldown = TRUE
addtimer(CALLBACK(src, PROC_REF(reboot)), 90 / severity)
/obj/item/organ/internal/cyberimp/brain/anti_sleep/proc/reboot()
crit_fail = FALSE
cooldown = FALSE
/obj/item/organ/internal/cyberimp/brain/anti_sleep/hardened
name = "Hardened Neural Jumpstarter implant"
desc = "A military-grade version of the standard implant, for NT's more elite forces."
origin_tech = "materials=6;programming=5;biotech=5"
emp_proof = TRUE
/obj/item/organ/internal/cyberimp/brain/anti_sleep/hardened/compatible
desc = "A military-grade version of the standard implant, for NT's more elite forces. This one is compatible with the CNS Rebooter implant."
slot = "brain_antisleep"
/obj/item/organ/internal/cyberimp/brain/clown_voice
name = "Comical implant"
desc = SPAN_SANS("Uh oh.")
implant_color = "#DEDE00"
slot = "brain_clownvoice"
origin_tech = "materials=2;biotech=2"
materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_BANANIUM = 200)
/obj/item/organ/internal/cyberimp/brain/clown_voice/insert(mob/living/carbon/M, special = FALSE)
..()
ADD_TRAIT(M, TRAIT_COMIC_SANS, "augment")
/obj/item/organ/internal/cyberimp/brain/clown_voice/remove(mob/living/carbon/M, special = FALSE)
REMOVE_TRAIT(M, TRAIT_COMIC_SANS, "augment")
return ..()
// actual translating done in human/handle_speech_problems
/obj/item/organ/internal/cyberimp/brain/speech_translator
name = "Speech translator implant"
desc = "While known as a translator, this implant actually generates speech based on the user's thoughts when activated, completely bypassing the need to speak."
implant_color = "#C0C0C0"
slot = "brain_speechtranslator"
w_class = WEIGHT_CLASS_TINY
origin_tech = "materials=4;biotech=6"
actions_types = list(/datum/action/item_action/organ_action/toggle)
var/active = TRUE
var/speech_span = ""
var/speech_verb = "states"
/obj/item/organ/internal/cyberimp/brain/speech_translator/clown
name = "Comical speech translator implant"
implant_color = "#DEDE00"
speech_span = "sans"
/obj/item/organ/internal/cyberimp/brain/speech_translator/emp_act(severity)
if(emp_proof)
return
if(owner && active && !crit_fail)
to_chat(owner, SPAN_DANGER("Your translator implant shuts down with a harsh buzz."))
addtimer(CALLBACK(src, PROC_REF(reboot)), 60 SECONDS)
crit_fail = TRUE
active = FALSE
/obj/item/organ/internal/cyberimp/brain/speech_translator/proc/reboot()
crit_fail = FALSE
if(owner)
to_chat(owner, SPAN_NOTICE("Your translator implant beeps."))
SEND_SOUND(owner, sound('sound/machines/twobeep.ogg'))
/obj/item/organ/internal/cyberimp/brain/speech_translator/ui_action_click()
if(owner && crit_fail)
to_chat(owner, SPAN_WARNING("The implant is still rebooting."))
else if(owner && !active)
to_chat(owner, SPAN_NOTICE("You turn on your translator implant."))
active = TRUE
else if(owner && active)
to_chat(owner, SPAN_NOTICE("You turn off your translator implant."))
active = FALSE
/obj/item/organ/internal/cyberimp/brain/wire_interface
name = "Wire interface implant"
desc = "This cybernetic brain implant will allow you to interface with electrical currents to sense the purpose of wires."
implant_color = "#fff782"
slot = "brain_wire_interface"
origin_tech = "materials=5;programming=4;biotech=4"
materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_SILVER = 400, MAT_GOLD = 400)
/obj/item/organ/internal/cyberimp/brain/wire_interface/insert(mob/living/carbon/M, special = FALSE)
..()
ADD_TRAIT(M, TRAIT_SHOW_WIRE_INFO, "show_wire_info[UID()]")
/obj/item/organ/internal/cyberimp/brain/wire_interface/remove(mob/living/carbon/M, special = FALSE)
REMOVE_TRAIT(M, TRAIT_SHOW_WIRE_INFO, "show_wire_info[UID()]")
return ..()
/obj/item/organ/internal/cyberimp/brain/wire_interface/emp_act(severity)
if(!owner || emp_proof)
return
var/time_of_emp = world.time // This lets us be emp'd multiple times, applying the trait multiple times, extending the cooldown
ADD_TRAIT(owner, TRAIT_WIRE_BLIND, "emp'd_at_[time_of_emp]")
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(callback_remove_trait), owner, TRAIT_WIRE_BLIND, "emp'd_at_[time_of_emp]"), (2 MINUTES / severity))
/obj/item/organ/internal/cyberimp/brain/wire_interface/hardened
name = "Hardened Wire interface implant"
desc = "This wire interface implant is actually wireless, to avoid issues with electromagnetic pulses."
origin_tech = "materials=6;programming=6;biotech=6"
emp_proof = TRUE
// An implant that injects you with mephedrone on demand, acting like a bootleg sandevistan
/obj/item/organ/internal/cyberimp/brain/sensory_enhancer
name = "\improper Qani-Laaca sensory computer"
desc = "An experimental implant replacing the spine of organics. When activated, it can give a temporary boost to mental processing speed, \
which many users perceive as a slowing of time and quickening of their ability to act. Due to its nature, it is incompatible with \
systems that heavily influence the user's nervous system, like the central nervous system rebooter. \
As a bonus effect, you are immune to the burst of heart damage that comes at the end of mephedrone usage, as the computer is able to regulate \
your heart's rhythm back to normal after its use."
icon_state = "sandy"
implant_overlay = null
implant_color = null
slot = "brain_antistun"
emp_proof = TRUE
actions_types = list(/datum/action/item_action/organ_action/toggle/sensory_enhancer)
origin_tech = "combat=6;biotech=6;syndicate=4"
materials = list(MAT_METAL = 10000, MAT_SILVER = 2000, MAT_PLASMA = 10000, MAT_DIAMOND = 4000, MAT_BLUESPACE = 4000)
augment_icon = "sandy"
always_show_augment = TRUE // A bit too big and bright to hide with synthetic skin.
///The icon state used for the on mob sprite. Default is sandy. Drask and vox have their own unique sprites
var/custom_mob_sprite = "sandy"
COOLDOWN_DECLARE(sensory_enhancer_cooldown)
/obj/item/organ/internal/cyberimp/brain/sensory_enhancer/rnd
emp_proof = FALSE
/obj/item/organ/internal/cyberimp/brain/sensory_enhancer/examine(mob/user)
. = ..()
. += SPAN_USERDANGER("Epilepsy Warning: Drug has vibrant visual effects!")
/obj/item/organ/internal/cyberimp/brain/sensory_enhancer/examine_more(mob/user)
. = ..()
. += "<i>Developed by Biotech Solutions this revolutionary full spinal cord replacement implant uses an integrated chemical synthesizer designed to administer Mephedrone: \
a potent stimulant and hyper-movement drug. This implant dramatically enhances the user's reflexes, with many reporting an almost time-slowing effect during its operation.</i>"
. += "<i>Biotech's experimentation with stimulant drug research has long been a cornerstone of their competitive edge, especially against their rival: \
Interydyne Pharmaceuticals, whose efforts yielded a drug capable of enhancing reflexes, although they were never mitigate the adverse effects of said product. \
A premature leak of the prototype implant pressured the company into accelerating its development, leaving the drug's side effects unresolved. \
They completed the spinal implant, which is uniquely equipped with built-in vials for Mephedrone delivery. \
Its material is solid plastitanium, and while strong in material, it surprisingly feels light, considering its spinal integration.</i>"
. += "<i>The implant is highly sought after because of its extreme capabilities in combat. Many military groups pay a handsome fee simply for the licensing of the item. \
In spite of this, recent Biotech shipments have come under fire from piracy, with the company quick to blame Interdyne for said attacks. Said allegations remain unverified.</i>"
/obj/item/organ/internal/cyberimp/brain/sensory_enhancer/insert(mob/living/carbon/M, special = 0)
. = ..()
ADD_TRAIT(M, TRAIT_MEPHEDRONE_ADAPTED, "[UID()]")
/obj/item/organ/internal/cyberimp/brain/sensory_enhancer/remove(mob/living/carbon/M, special = 0)
. = ..()
REMOVE_TRAIT(M, TRAIT_MEPHEDRONE_ADAPTED, "[UID()]")
/obj/item/organ/internal/cyberimp/brain/sensory_enhancer/render()
. = ..()
if(!.)
return
if(isvox(owner))
custom_mob_sprite = "vox_sandy"
else if(isdrask(owner))
custom_mob_sprite = "drask_sandy"
else
custom_mob_sprite = "sandy"
var/mutable_appearance/our_MA = mutable_appearance(augment_state, custom_mob_sprite, layer = -INTORGAN_LAYER)
return our_MA
/obj/item/organ/internal/cyberimp/brain/sensory_enhancer/emp_act(severity)
. = ..()
if(!.)
return
if(!COOLDOWN_FINISHED(src, sensory_enhancer_cooldown)) //Not on cooldown? Drug them up. Heavily. We don't want people self emping to bypass cooldown.
return
if(!prob(100 / severity) || !owner)
return
for(var/datum/action/item_action/organ_action/toggle/sensory_enhancer/SE in owner.actions)
SE.Trigger(FALSE, TRUE, TRUE)
/datum/action/item_action/organ_action/toggle/sensory_enhancer
name = "Activate Qani-Laaca System"
desc = "Activates your Qani-Laaca computer and grants you its powers. LMB: Short, safer activation. ALT/MIDDLE: Longer, more powerful, more dangerous activation."
button_icon = 'icons/obj/surgery.dmi'
button_icon_state = "sandy"
/// Keeps track of how much mephedrone we inject into people on activation
var/injection_amount = 10
/datum/action/item_action/organ_action/toggle/sensory_enhancer/AltTrigger()
Trigger(FALSE, TRUE)
/datum/action/item_action/organ_action/toggle/sensory_enhancer/Trigger(left_click, attack_self, emp_triggered = FALSE)
. = ..()
if(istype(target, /obj/item/organ/internal/cyberimp/brain/sensory_enhancer))
var/obj/item/organ/internal/cyberimp/brain/sensory_enhancer/ourtarget = target
if(!COOLDOWN_FINISHED(ourtarget, sensory_enhancer_cooldown))
to_chat(owner, SPAN_WARNING("[ourtarget] is still on cooldown for another [round(COOLDOWN_TIMELEFT(ourtarget, sensory_enhancer_cooldown), 1 SECONDS) / 10] seconds!"))
return
COOLDOWN_START(ourtarget, sensory_enhancer_cooldown, 5 MINUTES)
injection_amount = 10
if(!left_click)
injection_amount = 20
if(emp_triggered)
injection_amount = 40 //Time for a quick medical visit
Activate()
/datum/action/item_action/organ_action/toggle/sensory_enhancer/proc/Activate(atom/target)
var/mob/living/carbon/human/human_owner = owner
human_owner.reagents.add_reagent("mephedrone", injection_amount)
owner.visible_message(SPAN_DANGER("[owner.name] jolts suddenly as two small glass vials are fired from ports in the implant on [owner.p_their()] spine, shattering as they land."), \
SPAN_USERDANGER("You jolt suddenly as your Qani-Laaca system ejects two empty glass vials rearward, shattering as they land."))
playsound(human_owner, 'sound/goonstation/items/hypo.ogg', 80, TRUE)
var/obj/item/telegraph_vial = new /obj/item/qani_laaca_telegraph(get_turf(owner))
var/turf/turf_we_throw_at = get_edge_target_turf(owner, REVERSE_DIR(owner.dir))
telegraph_vial.throw_at(turf_we_throw_at, 5, 1)
// Safety net in case the injection amount doesn't get reset. Apparently it happened to someone in a round.
injection_amount = initial(injection_amount)
/obj/item/qani_laaca_telegraph
name = "spent Qani-Laaca cartridge"
desc = "A small glass vial, usually kept in a large stack inside a Qani-Laaca implant, that is broken open and ejected \
each time the implant is used. If you're looking at one long enough to think about it this long, you either have fast eyes \
or were lucky enough to catch one before it broke."
icon = 'icons/obj/surgery.dmi'
icon_state = "blastoff_ampoule_empty"
w_class = WEIGHT_CLASS_TINY
/obj/item/qani_laaca_telegraph/Initialize(mapload)
. = ..()
AddElement(/datum/element/shatters_when_thrown, /obj/effect/decal/cleanable/glass, 1, "shatter")
transform = transform.Scale(0.75, 0.75)
/obj/item/organ/internal/cyberimp/brain/hackerman_deck
name = "\improper Binyat wireless hacking system"
desc = "A rare-to-find neural chip that allows its user to interface with nearby machinery from a distance \
and affect it in (usually) beneficial ways. Due to the wireless connection, fine manipulation \
isn't possible, however the deck will drop a payload into the target's systems that will attempt \
hacking for you."
icon_state = "hackerman"
implant_overlay = null
implant_color = null
slot = "brain_antistun"
origin_tech = "materials=4;combat=6;biotech=6;powerstorage=2;syndicate=3"
stealth_level = 4 //Only surgery or a body scanner with the highest tier of stock parts can detect this.
/obj/item/organ/internal/cyberimp/brain/hackerman_deck/examine_more(mob/user)
. = ..()
. += "<i>Considered Cybersun Incorporated's most recent and developed implant system focused on hacking from a range while being undetectable from normal means. \
The Binyat Wireless Hacking System (BWHS) is a stealth-built implant that gives its user a rudimentary electronic interface on whatever can be perceived. \
It uses a micro jammer to hide its existence from even the most advanced scanning systems.<i>"
. += "<i>Originally designed as a hand-held device for long-range testing of Cybersun's electronic security systems, \
the easy integration of the components into a neural implant led to a revaluation of the device's potential. \
Development would commence to create the first sets of prototypes, focusing on tricking scanners with no false positives, \
and being able to hack from afar. The System does have a major flaw, however, as Cybersun R&D was never able to miniaturize its cooling systems to a practical level. \
Repeated use will lead to skin irritation, internal burns, and even severe nerve damage in extreme cases.<i>"
. += "<i>As of modern times, the BWHS is heavily vetted under Cybersun Inc. due to its dangerous nature and rather difficult detection. \
However, this hasn't stopped the flow of these implants from reaching the black market, whether by inside or outside influences.</i>"
/obj/item/organ/internal/cyberimp/brain/hackerman_deck/insert(mob/living/carbon/M, special = 0)
. = ..()
add_spell()
RegisterSignal(M, COMSIG_BODY_TRANSFER_TO, PROC_REF(on_body_transfer))
/obj/item/organ/internal/cyberimp/brain/hackerman_deck/remove(mob/living/carbon/M, special = 0)
. = ..()
if(M.mind)
M.mind.RemoveSpell(/datum/spell/hackerman_deck)
UnregisterSignal(M, COMSIG_BODY_TRANSFER_TO)
/obj/item/organ/internal/cyberimp/brain/hackerman_deck/proc/on_body_transfer()
SIGNAL_HANDLER
for(var/datum/action/A in owner.actions)
if(A.name == "Activate Ranged Hacking") //Bit snowflake, but the action doesn't remove right otherwise
A.Remove(owner)
addtimer(CALLBACK(src, PROC_REF(add_spell)), 1 SECONDS) //Give the mind a moment to settle in
add_spell()
/obj/item/organ/internal/cyberimp/brain/hackerman_deck/proc/add_spell()
if(owner.mind)
owner.mind.RemoveSpell(/datum/spell/hackerman_deck) //Just to be sure.
owner.mind.AddSpell(new /datum/spell/hackerman_deck(null))
/obj/item/organ/internal/cyberimp/brain/hackerman_deck/emp_act(severity)
owner.adjustStaminaLoss(40 / severity)
owner.adjust_bodytemperature(400 / severity)
to_chat(owner, SPAN_WARNING("Your [name] heats up drastically!"))
return TRUE
/datum/spell/hackerman_deck
name = "Activate Ranged Hacking"
desc = "Click on any machine to hack them. Has a short range of only three tiles."
clothes_req = FALSE
invocation = "none"
antimagic_flags = NONE
selection_activated_message = "You warm up your Binyat deck, there's an idle buzzing at the back of your mind as it awaits a target."
selection_deactivated_message = "Your hacking deck makes an almost disappointed sounding buzz at the back of your mind as it powers down."
action_icon_state = "hackerman"
action_background_icon_state = "bg_pulsedemon"
/// How many times have we successfully hacked in the last minute? Increases burn damage by 3 for each value above 0.
var/recent_hacking = 0
/datum/spell/hackerman_deck/create_new_targeting()
var/datum/spell_targeting/clicked_atom/C = new()
C.range = 3
C.try_auto_target = FALSE
return C
/datum/spell/hackerman_deck/on_mind_transfer(mob/living/L)
if(!ishuman(L))
return FALSE
var/mob/living/carbon/human/H = L
var/obj/item/organ/internal/cyberimp/brain/hackerman_deck/our_deck = H.get_int_organ(/obj/item/organ/internal/cyberimp/brain/hackerman_deck)
if(!our_deck)
return FALSE
return TRUE
/datum/spell/hackerman_deck/cast(list/targets, mob/user)
var/atom/target = targets[1]
if(get_dist(user, target) > 3) //fucking cameras holy shit
to_chat(user, SPAN_WARNING("Your implant is not robust enough to hack at that distance!"))
cooldown_handler.start_recharge(cooldown_handler.recharge_duration * 0.3)
return
if(istype(user.loc, /obj/machinery/atmospherics)) //Come now, no emaging all the doors on station from a pipe
to_chat(user, SPAN_WARNING("Your implant is unable to get a lock on anything in the pipes!"))
return
var/beam
if(!isturf(user.loc)) //Using it inside a locker or stealth box is fine! Let us make sure the beam can be seen though.
beam = user.loc.Beam(target, icon_state = "sm_arc_supercharged", time = 3 SECONDS)
else
beam = user.Beam(target, icon_state = "sm_arc_supercharged", time = 3 SECONDS)
user.visible_message(SPAN_WARNING("[user] makes an unusual buzzing sound as the air between them and [target] crackles."), \
SPAN_WARNING("The air between you and [target] begins to crackle audibly as the Binyat gets to work and heats up in your head!"))
if(!do_after(user, 3 SECONDS, target))
qdel(beam)
cooldown_handler.start_recharge(cooldown_handler.recharge_duration * 0.3)
return
if(!target.emag_act(user))
to_chat(user, SPAN_WARNING("You are unable to hack this!"))
cooldown_handler.start_recharge(cooldown_handler.recharge_duration * 0.3)
return
target.add_hiddenprint(user)
playsound(target, 'sound/machines/terminal_processing.ogg', 15, TRUE)
var/mob/living/carbon/human/human_owner = user
human_owner.adjustFireLoss(5 + (recent_hacking * 3))
recent_hacking++
addtimer(CALLBACK(src, PROC_REF(lower_recent_hacking)), 1 MINUTES)
/datum/spell/hackerman_deck/proc/lower_recent_hacking()
recent_hacking--
//[[[[MOUTH]]]]
/obj/item/organ/internal/cyberimp/mouth
parent_organ = "mouth"
/obj/item/organ/internal/cyberimp/mouth/breathing_tube
name = "breathing tube implant"
desc = "This simple implant adds an internals connector to your back, allowing you to use internals without a mask and protecting you from being choked."
icon_state = "implant_mask"
slot = "breathing_tube"
w_class = WEIGHT_CLASS_TINY
origin_tech = "materials=2;biotech=3"
materials = list(MAT_METAL = 600, MAT_GLASS = 250)
augment_icon = "breathing_tube"
/obj/item/organ/internal/cyberimp/mouth/breathing_tube/render()
. = ..()
if(!.)
return
var/mutable_appearance/our_MA = mutable_appearance(augment_state, augment_icon, layer = -INTORGAN_LAYER)
return our_MA
/obj/item/organ/internal/cyberimp/mouth/breathing_tube/emp_act(severity)
if(emp_proof)
return
if(prob(60/severity) && owner)
to_chat(owner, SPAN_WARNING("Your breathing tube suddenly closes!"))
owner.AdjustLoseBreath(4 SECONDS)
//[[[[CHEST]]]]
/obj/item/organ/internal/cyberimp/chest
name = "cybernetic torso implant"
desc = "implants for the organs in your torso."
icon_state = "chest_implant"
implant_overlay = "chest_implant_overlay"
/obj/item/organ/internal/cyberimp/chest/nutriment
name = "Nutriment pump implant"
desc = "This implant will synthesize a small amount of nutriment and pumps it directly into your bloodstream when you are starving."
icon_state = "nutriment_implant"
implant_overlay = null
var/hunger_threshold = NUTRITION_LEVEL_STARVING
var/synthesizing = 0
var/poison_amount = 5
var/disabled_by_emp = FALSE
slot = "stomach"
origin_tech = "materials=2;powerstorage=2;biotech=2"
materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_GOLD = 500)
augment_icon = "nutripump"
/obj/item/organ/internal/cyberimp/chest/nutriment/examine(mob/user)
. = ..()
if(emp_proof)
. += " The implant has been hardened. It is invulnerable to EMPs."
/obj/item/organ/internal/cyberimp/chest/nutriment/on_life()
if(!owner)
return
if(synthesizing)
return
if(disabled_by_emp)
return
if(owner.stat == DEAD)
return
if(status & ORGAN_DEAD)
return FALSE
if(owner.nutrition <= hunger_threshold)
synthesizing = TRUE
to_chat(owner, SPAN_NOTICE("You feel less hungry..."))
owner.adjust_nutrition(50)
addtimer(CALLBACK(src, PROC_REF(synth_cool)), 50)
/obj/item/organ/internal/cyberimp/chest/nutriment/proc/synth_cool()
synthesizing = FALSE
/obj/item/organ/internal/cyberimp/chest/nutriment/proc/emp_cool()
disabled_by_emp = FALSE
/obj/item/organ/internal/cyberimp/chest/nutriment/emp_act(severity)
if(!owner || emp_proof)
return
owner.vomit(100, FALSE, TRUE, 3, FALSE) // because when else do we ever use projectile vomiting
owner.visible_message(SPAN_WARNING("The contents of [owner]'s stomach erupt violently from [owner.p_their()] mouth!"),
SPAN_WARNING("You feel like your insides are burning as you vomit profusely!"),
SPAN_WARNING("You hear vomiting and a sickening splattering against the floor!"))
owner.reagents.add_reagent("????",poison_amount / severity) //food poisoning
disabled_by_emp = TRUE // Disable the implant for a little bit so this effect actually matters
synthesizing = FALSE
addtimer(CALLBACK(src, PROC_REF(emp_cool)), 60 SECONDS)
/obj/item/organ/internal/cyberimp/chest/nutriment/render()
. = ..()
if(!.)
return
var/mutable_appearance/our_MA = mutable_appearance(augment_state, augment_icon, layer = -INTORGAN_LAYER)
return our_MA
/obj/item/organ/internal/cyberimp/chest/nutriment/plus
name = "Nutriment pump implant PLUS"
desc = "This implant will synthesize a small amount of nutriment and pumps it directly into your bloodstream when you are hungry."
icon_state = "adv_nutriment_implant"
hunger_threshold = NUTRITION_LEVEL_HUNGRY
poison_amount = 10
origin_tech = "materials=4;powerstorage=3;biotech=3"
materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_GOLD = 500, MAT_URANIUM = 750)
augment_icon = "nutripump_adv"
/obj/item/organ/internal/cyberimp/chest/nutriment/hardened
name = "hardened nutriment pump implant"
emp_proof = TRUE
/obj/item/organ/internal/cyberimp/chest/nutriment/plus/hardened
name = "hardened nutriment pump implant PLUS"
emp_proof = TRUE
/obj/item/organ/internal/cyberimp/chest/reviver
name = "Reviver implant"
desc = "This implant will attempt to revive and heal you out of critical condition or death. For the faint of heart!"
icon_state = "reviver_implant"
implant_overlay = null
origin_tech = "materials=5;programming=5;biotech=6"
materials = list(MAT_METAL = 800, MAT_GLASS = 800, MAT_GOLD = 300, MAT_URANIUM = 500)
slot = "heartdrive"
augment_icon = "reviver"
/// How long the implant will go on cooldown for once the user has exited crit, in seconds.
var/revive_cost = 0 SECONDS
/// Are we in the progress of healing the user?
var/reviving = FALSE
/// Have we defibed someone this heal period? If so, do not heal past crit without an upgraded heart, as it is low on juice.
var/has_defibed = FALSE
/// How long we are on cooldown for
COOLDOWN_DECLARE(reviver_cooldown)
/// How long till we can try to defib again
COOLDOWN_DECLARE(defib_cooldown)
/// This check is an aditional minute delay applied to nuggeted IPCS, so they are not endlessly instantly reviving.
COOLDOWN_DECLARE(nugget_contingency)
/// The trigger when nuggeted is detected. Resets when revived. Prevents the cooldown from being applied again.
var/applied_nugget_cooldown = FALSE
/obj/item/organ/internal/cyberimp/chest/reviver/hardened
name = "Hardened reviver implant"
emp_proof = TRUE
/obj/item/organ/internal/cyberimp/chest/reviver/hardened/Initialize(mapload)
. = ..()
desc += " The implant has been hardened. It is invulnerable to EMPs."
/obj/item/organ/internal/cyberimp/chest/reviver/render()
. = ..()
if(!.)
return
var/mutable_appearance/our_MA = mutable_appearance(augment_state, augment_icon, layer = -INTORGAN_LAYER)
return our_MA
/obj/item/organ/internal/cyberimp/chest/reviver/dead_process()
if(status & ORGAN_DEAD)
return FALSE
try_heal() // Allows implant to work even on dead people
/obj/item/organ/internal/cyberimp/chest/reviver/on_life()
if(status & ORGAN_DEAD)
return FALSE
try_heal()
/obj/item/organ/internal/cyberimp/chest/reviver/proc/try_heal()
if(reviving)
if(owner.stat != DEAD && reached_heal_threshold()) //Don't stop healing when they are dead.
COOLDOWN_START(src, reviver_cooldown, revive_cost)
reviving = FALSE
to_chat(owner, SPAN_NOTICE("Your reviver implant shuts down and starts recharging. It will be ready again in [DisplayTimeText(revive_cost)]."))
applied_nugget_cooldown = FALSE
else
addtimer(CALLBACK(src, PROC_REF(heal)), 3 SECONDS)
return
if(!COOLDOWN_FINISHED(src, reviver_cooldown) || owner.suiciding || !COOLDOWN_FINISHED(src, nugget_contingency)) // don't heal while you're in cooldown!
return
if(owner.health <= 0 || owner.stat == DEAD)
if(ismachineperson(owner))
if(!applied_nugget_cooldown && length(owner.bodyparts) <= 2)
COOLDOWN_START(src, nugget_contingency, 1 MINUTES)
applied_nugget_cooldown = TRUE
return
revive_cost = 0
reviving = TRUE
has_defibed = FALSE
to_chat(owner, SPAN_NOTICE("You feel a faint buzzing as your reviver implant starts patching your wounds..."))
COOLDOWN_START(src, defib_cooldown, 8 SECONDS) // 5 seconds after heal proc delay
/obj/item/organ/internal/cyberimp/chest/reviver/proc/heal()
if(QDELETED(owner))
return
// This is not on defib check so it doesnt revive IPCs either in a demon.
if(HAS_TRAIT(owner, TRAIT_UNREVIVABLE))
return
if(COOLDOWN_FINISHED(src, defib_cooldown))
revive_dead()
/// boolean that stands for if PHYSICAL damage being patched
var/body_damage_patched = FALSE
if(owner.getOxyLoss())
owner.adjustOxyLoss(-3)
revive_cost += 0.5 SECONDS
if(owner.getBruteLoss())
owner.adjustBruteLoss(-2, robotic = TRUE)
revive_cost += 4 SECONDS
body_damage_patched = TRUE
if(owner.getFireLoss())
owner.adjustFireLoss(-2, robotic = TRUE)
revive_cost += 4 SECONDS
body_damage_patched = TRUE
if(owner.getToxLoss())
owner.adjustToxLoss(-1)
revive_cost += 4 SECONDS
if(body_damage_patched && prob(25)) // healing is called every few seconds, not every tick
if(owner.stat != CONSCIOUS)
owner.visible_message(SPAN_WARNING("[owner]'s body [pick("twitches", "shifts", "shivers", "spasms", "vibrates")] a bit."), \
SPAN_NOTICE("You feel like something is patching your injured body."))
else // No twitching if awake.
to_chat(owner, SPAN_NOTICE("You feel like something is patching your injured body."))
/obj/item/organ/internal/cyberimp/chest/reviver/proc/revive_dead()
if(!COOLDOWN_FINISHED(src, defib_cooldown) || owner.stat != DEAD || !can_defib())
return
var/mob/dead/observer/ghost = owner.get_ghost()
if(ghost)
to_chat(ghost, SPAN_GHOSTALERT("You are being revived by [src]!"))
window_flash(ghost.client)
SEND_SOUND(ghost, sound('sound/effects/genetics.ogg'))
COOLDOWN_START(src, defib_cooldown, 16 SECONDS)
playsound(get_turf(owner), 'sound/machines/defib_charge.ogg', 50, FALSE)
owner.grab_ghost()
owner.visible_message(SPAN_WARNING("[owner]'s body spasms violently!"))
addtimer(CALLBACK(src, PROC_REF(zap_em)), 5 SECONDS)
/obj/item/organ/internal/cyberimp/chest/reviver/proc/zap_em()
playsound(owner, 'sound/machines/defib_zap.ogg', 75, TRUE, -1)
// Inflict some brain damage scaling with time spent dead
var/time_dead = world.time - owner.timeofdeath
var/obj/item/organ/internal/brain/sponge = owner.get_int_organ(/obj/item/organ/internal/brain)
var/defib_time_brain_damage = min(100 * time_dead / BASE_DEFIB_TIME_LIMIT, 89) // 20 from 1 minute onward, +20 per minute up to 99 (10 organ damage flat added after)
if(time_dead > DEFIB_TIME_LOSS && defib_time_brain_damage > sponge.damage)
owner.setBrainLoss(defib_time_brain_damage)
// Turns out it takes some raw materials to heal you so much and defib you from inside. We took some material from your organs and iron from blood, hope you do not mind!
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
for(var/obj/item/organ/internal/I in H.internal_organs)
I.receive_damage(10, TRUE)
H.blood_volume *= 0.85
revive_cost += 10 MINUTES // Additional 10 minutes cooldown after revival.
owner.SetLoseBreath(0) //Reset the heart attack losebreath of hell
owner.set_heartattack(FALSE)
owner.update_revive()
owner.KnockOut()
owner.Paralyse(10 SECONDS)
owner.emote("gasp")
owner.Jitter(20 SECONDS)
has_defibed = TRUE
SEND_SIGNAL(owner, COMSIG_LIVING_MINOR_SHOCK)
add_attack_logs(owner, owner, "Revived with [src]")
/obj/item/organ/internal/cyberimp/chest/reviver/proc/can_defib()
if(!owner)
return FALSE
// They will get up on their own.
if(ismachineperson(owner))
return FALSE
// Slight tweak, revive if brute burn and oxygen loss *combined* are above 210, to avoid spam defibing at like, 200+ brute burn damage or 200 o2 loss
if(!owner.is_revivable() || owner.getBruteLoss() + owner.getFireLoss() + owner.getOxyLoss() >= 210 || HAS_TRAIT(owner, TRAIT_HUSK) || owner.blood_volume < BLOOD_VOLUME_SURVIVE)
return FALSE
// Let us break this on multiple lines
// Clone loss is a new addition outside defib code, to avoid endless revive hell.
// Avoid defibing with over 125 toxin loss as well. This also means toxin will delay someone from being revived *much* longer.
if(!owner.get_organ_slot("brain") || HAS_TRAIT(owner, TRAIT_FAKEDEATH) || HAS_TRAIT(owner, TRAIT_BADDNA) || owner.getCloneLoss() >= 180 || owner.getToxLoss() >= 125)
return FALSE
return TRUE
/obj/item/organ/internal/cyberimp/chest/reviver/proc/reached_heal_threshold()
// By default, 0 health. Won't heal you out of shock alone, will need some medical attention still if you do not have meds!
// Will heal you out of crit though with 2 ticks of extra healing, due to callback.
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
var/heal_threshold = 0
var/obj/item/organ/internal/heart/cybernetic/upgraded/U = H.get_int_organ(/obj/item/organ/internal/heart/cybernetic/upgraded)
if(U) // The heart assists in healing, and will heal you out of shock.
heal_threshold = 25
if(!has_defibed) // Not low on power, can heal you out of shock.
heal_threshold = 25
if(H.health > heal_threshold)
return TRUE
return FALSE
/obj/item/organ/internal/cyberimp/chest/reviver/emp_act(severity)
if(!owner || emp_proof)
return
if(reviving)
revive_cost += 40 SECONDS
COOLDOWN_START(src, defib_cooldown, 20 SECONDS)
else
COOLDOWN_START(src, reviver_cooldown, 20 SECONDS)
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
if(H.stat != DEAD && prob(50 / severity) && H.can_heartattack())
H.set_heartattack(TRUE)
addtimer(CALLBACK(src, PROC_REF(undo_heart_attack)), 600 / severity)
/obj/item/organ/internal/cyberimp/chest/reviver/proc/undo_heart_attack()
var/mob/living/carbon/human/H = owner
if(!istype(H))
return
H.set_heartattack(FALSE)
H.adjustOxyLoss(-100) ///In the unlikely case that you are still alive, this should get you maybe to livable circumstances.
H.SetLoseBreath(0)
if(H.stat == CONSCIOUS)
to_chat(H, SPAN_NOTICE("You feel your heart beating again!"))
/obj/item/organ/internal/cyberimp/chest/bluespace_anchor
name = "bluespace anchor implant"
desc = "This large cybernetic implant anchors you in bluespace, preventing almost any teleportation effects from working. It disrupts GPS systems however."
icon_state = "bluespace_anchor"
implant_overlay = null
slot = "bluespace_anchor"
origin_tech = "bluespace=6;biotech=4"
materials = list(MAT_METAL = 10000, MAT_BLUESPACE = 2000)
/obj/item/organ/internal/cyberimp/chest/bluespace_anchor/insert(mob/living/carbon/M, special = FALSE)
..()
RegisterSignal(M, COMSIG_MOVABLE_TELEPORTING, PROC_REF(on_teleport))
RegisterSignal(M, COMSIG_MOB_PRE_JAUNT, PROC_REF(on_jaunt))
for(var/obj/item/bio_chip/tracking/T in M)
if(T && T.implanted)
qdel(T)
/obj/item/organ/internal/cyberimp/chest/bluespace_anchor/remove(mob/living/carbon/M, special = FALSE)
UnregisterSignal(M, COMSIG_MOVABLE_TELEPORTING)
UnregisterSignal(M, COMSIG_MOB_PRE_JAUNT)
return ..()
/// Blocks teleports and stuns the would-be-teleportee.
/obj/item/organ/internal/cyberimp/chest/bluespace_anchor/proc/on_teleport(mob/living/teleportee, atom/destination, channel)
SIGNAL_HANDLER // COMSIG_MOVABLE_TELEPORTED
to_chat(teleportee, SPAN_USERDANGER("You feel yourself teleporting, but are suddenly flung back to where you just were!"))
teleportee.Weaken(5 SECONDS)
var/datum/effect_system/spark_spread/spark_system = new()
spark_system.set_up(5, TRUE, teleportee)
spark_system.start()
return COMPONENT_BLOCK_TELEPORT
/// Prevents a user from entering a jaunt.
/obj/item/organ/internal/cyberimp/chest/bluespace_anchor/proc/on_jaunt(mob/living/jaunter)
SIGNAL_HANDLER // COMSIG_MOB_PRE_JAUNT
to_chat(jaunter, SPAN_USERDANGER("As you attempt to jaunt, you slam directly into the barrier between realities and are sent crashing back into corporeality!"))
jaunter.Weaken(5 SECONDS)
var/datum/effect_system/spark_spread/spark_system = new()
spark_system.set_up(5, TRUE, jaunter)
spark_system.start()
return COMPONENT_BLOCK_JAUNT
/obj/item/organ/internal/cyberimp/chest/ipc_repair
name = "Reactive Repair Implant"
desc = "This implant reworks the IPC frame, in order to incorporate materials that return to their original shape after being damaged. Requires power to function."
implant_color = "#0ac0d8"
origin_tech = "materials=4;programming=4;biotech=4;magnets=4;engineering=4"
materials = list(MAT_METAL = 12500, MAT_SILVER = 12000, MAT_GOLD = 2500, MAT_PLASMA = 5000)
slot = "stomach" //Can't have a nutriment pump with it.
requires_machine_person = TRUE
/obj/item/organ/internal/cyberimp/chest/ipc_repair/on_life()
if(crit_fail)
return
if(status & ORGAN_DEAD)
return FALSE
if(owner.maxHealth == owner.health)
owner.adjust_nutrition(-0.25)
return //Passive damage scanning
owner.adjustBruteLoss(-0.5, robotic = TRUE)
owner.adjustFireLoss(-0.5, robotic = TRUE)
owner.adjust_nutrition(-2) //Very power inefficent. Hope you got an APC nearby.
/obj/item/organ/internal/cyberimp/chest/ipc_repair/emp_act(severity)
if(!owner || emp_proof || crit_fail)
return
crit_fail = TRUE
addtimer(VARSET_CALLBACK(src, crit_fail, FALSE), 30 SECONDS / severity)
/obj/item/organ/internal/cyberimp/chest/ipc_joints
name = "IPC ER-OR Joint Implant"
desc = "This is a basetype. Notify a coder!"
implant_color = "#eeff00"
origin_tech = "materials=5;programming=4;biotech=4"
materials = list(MAT_METAL = 12500, MAT_SILVER = 12000, MAT_GOLD = 2500, MAT_PLASMA = 5000)
slot = "joints"
requires_machine_person = TRUE
/obj/item/organ/internal/cyberimp/chest/ipc_joints/magnetic_joints
name = "Magnetic Joints Implant"
desc = "This implant modifies IPC joints to use magnets, allowing easy re-attachment and fluid movement."
implant_color = "#670db1"
origin_tech = "materials=4;programming=4;biotech=4;magnets=4;engineering=4"
/obj/item/organ/internal/cyberimp/chest/ipc_joints/magnetic_joints/emp_act(severity)
if(!owner || emp_proof)
return
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
to_chat(H, SPAN_USERDANGER("Your magnetic joints lose power!"))
for(var/obj/item/organ/external/E in H.bodyparts)
if(E.body_part != UPPER_TORSO && E.body_part != LOWER_TORSO)
E.droplimb(TRUE) //lego disasemble sound
/obj/item/organ/internal/cyberimp/chest/ipc_joints/magnetic_joints/insert(mob/living/carbon/M, special = FALSE)
..()
ADD_TRAIT(M, TRAIT_IPC_JOINTS_MAG, "ipc_joint[UID()]")
/obj/item/organ/internal/cyberimp/chest/ipc_joints/magnetic_joints/remove(mob/living/carbon/M, special = FALSE)
REMOVE_TRAIT(M, TRAIT_IPC_JOINTS_MAG, "ipc_joint[UID()]")
return ..()
/obj/item/organ/internal/cyberimp/chest/ipc_joints/sealed
name = "Sealed Joints Implant"
desc = "This implant seals and reinforces IPC joints, securing the limbs better for industrial work, though prone to locking up."
implant_color = "#b10d0d"
origin_tech = "materials=4;programming=4;biotech=4;engineering=4;combat=4;"
/obj/item/organ/internal/cyberimp/chest/ipc_joints/sealed/emp_act(severity)
if(!owner || emp_proof)
return
var/weaken_time = (10 + (severity - 1 ? 0 : 10)) SECONDS
owner.Weaken(weaken_time) //Pop it and lock it
to_chat(owner, SPAN_WARNING("Your body seizes up!"))
return weaken_time
/obj/item/organ/internal/cyberimp/chest/ipc_joints/sealed/insert(mob/living/carbon/M, special = FALSE)
..()
ADD_TRAIT(M, TRAIT_IPC_JOINTS_SEALED, "ipc_joint[UID()]")
owner.physiology.stamina_mod *= 1.15 //15% more stamina damage, representing extra friction in limbs. I guess.
/obj/item/organ/internal/cyberimp/chest/ipc_joints/sealed/remove(mob/living/carbon/M, special = FALSE)
REMOVE_TRAIT(M, TRAIT_IPC_JOINTS_SEALED, "ipc_joint[UID()]")
owner.physiology.stamina_mod /= 1.15
return ..()
/obj/item/organ/internal/cyberimp/chest/ipc_joints/emp_shield
name = "Electromagnetic Shielding Implant"
desc = "This implant improves the conductivity of the IPC frame, providing partial protection against EMPs."
implant_color = "#301beeff"
origin_tech = "materials=4;programming=4;biotech=4;engineering=4;combat=4;"
/obj/item/organ/internal/cyberimp/chest/ipc_joints/emp_shield/insert(mob/living/carbon/M, special = FALSE)
..()
ADD_TRAIT(M, TRAIT_EMP_RESIST, "ipc[UID()]")
/obj/item/organ/internal/cyberimp/chest/ipc_joints/emp_shield/remove(mob/living/carbon/M, special = FALSE)
REMOVE_TRAIT(M, TRAIT_EMP_RESIST, "ipc[UID()]")
return ..()
/obj/item/organ/internal/cyberimp/chest/ipc_joints/sealed_and_emp
name = "Experimental Defensive Implant"
desc = "This implant deploys experimental nanobots into the IPC chassis to harden joints and provide partial protection against EMPs."
implant_color = "#065513ff"
origin_tech = "materials=5;programming=5;biotech=5;engineering=5;combat=5;"
/obj/item/organ/internal/cyberimp/chest/ipc_joints/sealed_and_emp/insert(mob/living/carbon/M, special = FALSE)
..()
ADD_TRAIT(M, TRAIT_IPC_JOINTS_SEALED, "ipc_joint[UID()]")
ADD_TRAIT(M, TRAIT_EMP_RESIST, "ipc_joint[UID()]")
/obj/item/organ/internal/cyberimp/chest/ipc_joints/sealed_and_emp/remove(mob/living/carbon/M, special = FALSE)
REMOVE_TRAIT(M, TRAIT_IPC_JOINTS_SEALED, "ipc_joint[UID()]")
REMOVE_TRAIT(M, TRAIT_EMP_RESIST, "ipc_joint[UID()]")
return ..()
/obj/item/organ/internal/cyberimp/chest/ipc_joints/flayer_pacification
name = "\improper Nanite pacifier"
desc = "This implant acts on mindflayer nanobots like smoke does to bees, rendering them significantly more docile."
implant_color = COLOR_BLACK
origin_tech = "materials=4;programming=4;biotech=5;combat=4;"
materials = list(MAT_METAL = 10000, MAT_SILVER = 8000, MAT_GOLD = 3000, MAT_PLASMA = 10000)
/obj/item/organ/internal/cyberimp/chest/ipc_joints/flayer_pacification/insert(mob/living/carbon/M, special)
..()
ADD_TRAIT(M, TRAIT_MINDFLAYER_NULLIFIED, UNIQUE_TRAIT_SOURCE(src))
SEND_SIGNAL(M, COMSIG_FLAYER_RETRACT_IMPLANTS, TRUE)
/obj/item/organ/internal/cyberimp/chest/ipc_joints/flayer_pacification/remove(mob/living/carbon/M, special)
REMOVE_TRAIT(M, TRAIT_MINDFLAYER_NULLIFIED, UNIQUE_TRAIT_SOURCE(src))
return ..()
/obj/item/organ/internal/cyberimp/chest/ipc_food
name = "Culinary Processing Implant"
desc = "This implant emulates the functions of a gastrointestinal system, allowing IPCs to eat and experience taste."
implant_color = "#d8780a"
origin_tech = "materials=2;powerstorage=2;biotech=2"
materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_GOLD = 500)
slot = "gastrointestinal"
requires_machine_person = TRUE
/obj/item/organ/internal/cyberimp/chest/ipc_food/insert(mob/living/carbon/M, special = FALSE)
..()
ADD_TRAIT(M, TRAIT_IPC_CAN_EAT, "ipc_food[UID()]")
/obj/item/organ/internal/cyberimp/chest/ipc_food/remove(mob/living/carbon/M, special = FALSE)
REMOVE_TRAIT(M, TRAIT_IPC_CAN_EAT, "ipc_food[UID()]")
return ..()
/obj/item/organ/internal/cyberimp/chest/skinmonger
name = "\improper Skinmonger"
desc = "A strange implant that continuously produces and replaces synthetic skin. \
Will not apply skin to a monitor-shaped head."
implant_color = "#FFDDAA"
slot = "chest_synthetic_skin"
w_class = WEIGHT_CLASS_TINY
origin_tech = "materials=6;biotech=7;syndicate=1"
augment_icon = "nutripump"
/// Whether regeneration is allowed. This is disabled temporarily by an EMP
var/regeneration_active = TRUE
/// How long to wait after finding a target body part to replace skin on
var/regen_cooldown = 30 SECONDS
/// Whether we're currently regenerating
var/regenerating = FALSE
/// Normally synthetic skin doesn't have memory of the identity we're disguised as. This implant does, though
var/configured_identity = "Unknown"
/// Flag for tracking if we've used up the implant's initial deployment of skin
var/initial_surge_used = FALSE
/obj/item/organ/internal/cyberimp/chest/skinmonger/insert(mob/living/carbon/M, special = 0)
. = ..()
if(!initial_surge_used)
apply_full_synthetic_skin(M)
to_chat(M, SPAN_WARNING("In an instant, a surge of skin wraps around you and binds itself to your body!"))
playsound(M, 'sound/surgery/organ2.ogg', 70, TRUE, frequency = 0.8)
initial_surge_used = TRUE
/obj/item/organ/internal/cyberimp/chest/skinmonger/remove(mob/living/carbon/M, special = 0)
. = ..()
regenerating = FALSE
remove_all_synthetic_skin(M)
// Called when synthetic skin is removed from any part - starts regeneration cycle
/obj/item/organ/internal/cyberimp/chest/skinmonger/proc/start_regeneration()
if(!regeneration_active || regenerating)
return
regenerating = TRUE
// Wait before we trigger the first regen.
addtimer(CALLBACK(src, PROC_REF(regenerate_next_part)), regen_cooldown)
/obj/item/organ/internal/cyberimp/chest/skinmonger/proc/regenerate_next_part()
if(!owner || !regeneration_active || !regenerating)
return
var/mob/living/carbon/human/H = owner
var/list/unskinned_parts = list()
// Find all robotic parts without synthetic skin.
for(var/obj/item/organ/external/E in H.bodyparts)
if(!E.is_robotic() || E.has_synthetic_skin)
continue
// Skip monitor heads
if(E.limb_name == "head" && E.model)
var/datum/robolimb/R = GLOB.all_robolimbs[E.model]
if(R && R.is_monitor)
continue
unskinned_parts += E
// If no parts need skin, kill the regen cycle
if(!length(unskinned_parts))
regenerating = FALSE
return
// Pick a random part and apply skin
var/obj/item/organ/external/chosen_part = pick(unskinned_parts)
chosen_part.has_synthetic_skin = TRUE
// Apply owner's skin color to synthetic skin
if(ishuman(H))
chosen_part.synthetic_skin_colour = H.skin_colour
// Set identity for head regeneration
if(chosen_part.limb_name == "head")
var/identity_to_use = configured_identity
chosen_part.synthetic_skin_identity = identity_to_use
if(ishuman(H))
H.real_name = identity_to_use
// Chest and lower body tied together for regeneration
if(chosen_part.limb_name == "chest")
var/obj/item/organ/external/groin_limb = H.bodyparts_by_name["groin"]
if(groin_limb && groin_limb.is_robotic() && !groin_limb.has_synthetic_skin)
groin_limb.has_synthetic_skin = TRUE
groin_limb.synthetic_skin_colour = H.skin_colour
groin_limb.force_icon = null
groin_limb.mob_icon = null
groin_limb.compile_icon()
if(chosen_part.limb_name == "groin")
var/obj/item/organ/external/chest_limb = H.bodyparts_by_name["chest"]
if(chest_limb && chest_limb.is_robotic() && !chest_limb.has_synthetic_skin)
chest_limb.has_synthetic_skin = TRUE
chest_limb.synthetic_skin_colour = H.skin_colour
chest_limb.force_icon = null
chest_limb.mob_icon = null
chest_limb.compile_icon()
// Refresh sprite
chosen_part.force_icon = null
chosen_part.mob_icon = null
chosen_part.compile_icon()
H.update_body(rebuild_base = TRUE)
to_chat(H, SPAN_NOTICE("You feel a wave of synthetic skin gush forth and bind to your [chosen_part.name]."))
// Schedule next regeneration if more parts need skin. Otherwise, we're done
if(length(unskinned_parts) > 1)
addtimer(CALLBACK(src, PROC_REF(regenerate_next_part)), regen_cooldown)
else
regenerating = FALSE
// One-time application of skin across the entire chassis when the implant is inserted.
/obj/item/organ/internal/cyberimp/chest/skinmonger/proc/apply_full_synthetic_skin(mob/living/carbon/human/target)
if(!ishuman(target))
return
var/mob/living/carbon/human/H = target
var/head_skinned = FALSE
for(var/obj/item/organ/external/E in H.bodyparts)
if(!E.is_robotic() || E.has_synthetic_skin)
continue
// Skip monitor heads
if(E.limb_name == "head" && E.model)
var/datum/robolimb/R = GLOB.all_robolimbs[E.model]
if(R && R.is_monitor)
continue
E.has_synthetic_skin = TRUE
// Apply owner's skin color to synthetic skin
E.synthetic_skin_colour = H.skin_colour
// Set configured identity for head
if(E.limb_name == "head")
E.synthetic_skin_identity = configured_identity
head_skinned = TRUE
// Clear sprite cache
E.force_icon = null
E.mob_icon = null
E.compile_icon()
// Apply facial identity if head was skinned
if(head_skinned)
H.real_name = configured_identity
H.update_body(rebuild_base = TRUE)
/obj/item/organ/internal/cyberimp/chest/skinmonger/proc/remove_all_synthetic_skin(mob/living/carbon/human/target)
if(!ishuman(target))
return
var/mob/living/carbon/human/H = target
for(var/obj/item/organ/external/E in H.bodyparts)
if(E.is_robotic() && E.has_synthetic_skin)
E.remove_synthetic_skin(silent = TRUE) // silent because it spams the user otherwise
to_chat(H, SPAN_WARNING("You feel your synthetic skin melt away."))
H.update_body(rebuild_base = TRUE)
// EMP wipes all synthetic skin and puts the implant on cooldown
/obj/item/organ/internal/cyberimp/chest/skinmonger/emp_act(severity)
. = ..()
regenerating = FALSE
regeneration_active = FALSE
remove_all_synthetic_skin(owner)
addtimer(CALLBACK(src, PROC_REF(restart_regeneration)), regen_cooldown)
/obj/item/organ/internal/cyberimp/chest/skinmonger/proc/restart_regeneration()
if(owner)
regeneration_active = TRUE
start_regeneration()
//BOX O' IMPLANTS
/obj/item/storage/box/cyber_implants
name = "boxed cybernetic implants"
desc = "A sleek, sturdy box."
icon_state = "cyber_implants_box"
var/list/boxed = list(
/obj/item/autosurgeon/organ/syndicate/thermal_eyes,
/obj/item/autosurgeon/organ/syndicate/xray_eyes,
/obj/item/autosurgeon/organ/syndicate/anti_stam,
/obj/item/autosurgeon/organ/syndicate/reviver)
var/amount = 5
/obj/item/storage/box/cyber_implants/populate_contents()
var/implant
while(length(contents) <= amount)
implant = pick(boxed)
new implant(src)
/obj/item/storage/box/cyber_implants/empty/populate_contents()
return