diff --git a/aurorastation.dme b/aurorastation.dme
index 78288be2a19..0f7cec43c83 100644
--- a/aurorastation.dme
+++ b/aurorastation.dme
@@ -1133,11 +1133,23 @@
#include "code\game\objects\items\weapons\grenades\spawnergrenade.dm"
#include "code\game\objects\items\weapons\implants\implant.dm"
#include "code\game\objects\items\weapons\implants\implantcase.dm"
-#include "code\game\objects\items\weapons\implants\implantcircuits.dm"
#include "code\game\objects\items\weapons\implants\implanter.dm"
-#include "code\game\objects\items\weapons\implants\implantfreedom.dm"
#include "code\game\objects\items\weapons\implants\implantpad.dm"
-#include "code\game\objects\items\weapons\implants\implantuplink.dm"
+#include "code\game\objects\items\weapons\implants\implants\adrenaline.dm"
+#include "code\game\objects\items\weapons\implants\implants\aggression.dm"
+#include "code\game\objects\items\weapons\implants\implants\anti-augment.dm"
+#include "code\game\objects\items\weapons\implants\implants\chem.dm"
+#include "code\game\objects\items\weapons\implants\implants\circuit.dm"
+#include "code\game\objects\items\weapons\implants\implants\compressed_matter.dm"
+#include "code\game\objects\items\weapons\implants\implants\death_alarm.dm"
+#include "code\game\objects\items\weapons\implants\implants\emp.dm"
+#include "code\game\objects\items\weapons\implants\implants\explosive.dm"
+#include "code\game\objects\items\weapons\implants\implants\freedom.dm"
+#include "code\game\objects\items\weapons\implants\implants\health_tracker.dm"
+#include "code\game\objects\items\weapons\implants\implants\loyalty.dm"
+#include "code\game\objects\items\weapons\implants\implants\mindshield.dm"
+#include "code\game\objects\items\weapons\implants\implants\tracking.dm"
+#include "code\game\objects\items\weapons\implants\implants\uplink.dm"
#include "code\game\objects\items\weapons\material\ashtray.dm"
#include "code\game\objects\items\weapons\material\bats.dm"
#include "code\game\objects\items\weapons\material\caltrops.dm"
diff --git a/code/__defines/_macros.dm b/code/__defines/_macros.dm
index 4e69dac1985..62c88d2a9f8 100644
--- a/code/__defines/_macros.dm
+++ b/code/__defines/_macros.dm
@@ -21,6 +21,7 @@
#define SPAN_SUBTLE(X) ("" + X + "")
#define SPAN_SOGHUN(X) ("" + X + "")
#define SPAN_VOTE(X) ("" + X + "")
+#define SPAN_HEAR(X) ("" + X + "")
#define SPAN_SIZE(size, text) ("" + text + "")
diff --git a/code/_onclick/hud/action.dm b/code/_onclick/hud/action.dm
index acba5cca978..2c7a2b09f53 100644
--- a/code/_onclick/hud/action.dm
+++ b/code/_onclick/hud/action.dm
@@ -228,6 +228,32 @@
/datum/action/item_action/hands_free
check_flags = AB_CHECK_ALIVE|AB_CHECK_INSIDE
+/datum/action/item_action/hands_free/activate
+ name = "Activate"
+
+/datum/action/item_action/hands_free/activate/implant
+ action_type = AB_ITEM_USE_ICON
+ button_icon = 'icons/obj/action_buttons/implants.dmi'
+ button_icon_state = "default"
+
+/datum/action/item_action/hands_free/activate/implant/adrenaline
+ button_icon_state = "adrenal"
+
+/datum/action/item_action/hands_free/activate/implant/chemical
+ button_icon_state = "reagents"
+
+/datum/action/item_action/hands_free/activate/implant/compressed
+ button_icon_state = "storage"
+
+/datum/action/item_action/hands_free/activate/implant/emp
+ button_icon_state = "emp"
+
+/datum/action/item_action/hands_free/activate/implant/explosive
+ button_icon_state = "explosive"
+
+/datum/action/item_action/hands_free/activate/implant/freedom
+ button_icon_state = "freedom"
+
/datum/action/item_action/organ
action_type = AB_ITEM_USE_ICON
button_icon = 'icons/obj/action_buttons/organs.dmi'
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 22531ab2c27..8248b6c5434 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -358,7 +358,7 @@
switch(href_list["implant"])
if("remove")
- for(var/obj/item/implant/mindshield/I in H.contents)
+ for(var/obj/item/implant/mindshield/loyalty/I in H.contents)
for(var/obj/item/organ/external/organs in H.organs)
if(I in organs.implants)
qdel(I)
diff --git a/code/datums/uplink/implants.dm b/code/datums/uplink/implants.dm
index 14300bef4d3..26abc434bd3 100644
--- a/code/datums/uplink/implants.dm
+++ b/code/datums/uplink/implants.dm
@@ -7,18 +7,19 @@
/datum/uplink_item/item/implants/imp_freedom
name = "Freedom Implant"
telecrystal_cost = 1
+ desc = "A box containing a freedom implant case and implanter."
path = /obj/item/storage/box/syndie_kit/imp_freedom
-/datum/uplink_item/item/implants/imp_compress
- name = "Compressed Matter Implant"
- desc = "A box containing a single implanter and matter cartridge. To remove an unintended target, use the implanter in-hand then open the cartridge with a screwdriver."
- bluecrystal_cost = 1
- path = /obj/item/storage/box/syndie_kit/imp_compress
+/datum/uplink_item/item/implants/imp_emp
+ name = "EMP Implant"
+ telecrystal_cost = 1
+ desc = "A box containing an EMP implant case and implanter."
+ path = /obj/item/storage/box/syndie_kit/imp_emp
/datum/uplink_item/item/implants/imp_explosive
name = "Explosive Implant (DANGER!)"
bluecrystal_cost = 3
- desc = "A box containing an explosive implant and implanter. Use the implant in-hand to set the explosion size and trigger phrase."
+ desc = "A box containing an explosive implant case and implanter. Use the implant case with the implant pad to set the explosion size, trigger phrase, and trigger code."
path = /obj/item/storage/box/syndie_kit/imp_explosive
/datum/uplink_item/item/implants/imp_deadman
diff --git a/code/game/machinery/body_scanner.dm b/code/game/machinery/body_scanner.dm
index 85f14d6089b..d1f1860a84f 100644
--- a/code/game/machinery/body_scanner.dm
+++ b/code/game/machinery/body_scanner.dm
@@ -736,9 +736,16 @@
if (e.implants.len)
var/unk = 0
var/list/organic = list()
- for(var/atom/movable/I in e.implants)
- if(is_type_in_list(I, known_implants))
- wounds += "\a [I.name] implanted:"
+ var/imp
+ for(var/I in e.implants)
+ if(istype(I, /obj/item/implant))
+ var/obj/item/implant/A = I
+ if (A.hidden)
+ return
+ else if(A.known)
+ imp += "[I] implanted:"
+ else
+ unk += 1
else if(istype(I, /obj/effect/spider))
organic += I
else
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 627b7c42884..2ca6594e149 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -376,23 +376,6 @@
else if (mess)
icon_state = "pod_g"
-//Health Tracker Implant
-
-/obj/item/implant/health
- name = "health implant"
- var/healthstring = ""
-
-/obj/item/implant/health/proc/sensehealth()
- if(!implanted)
- return "ERROR"
- else
- if(isliving(implanted))
- var/mob/living/L = implanted
- healthstring = "[round(L.getOxyLoss())] - [round(L.getFireLoss())] - [round(L.getToxLoss())] - [round(L.getBruteLoss())]"
- if(!healthstring)
- healthstring = "ERROR"
- return healthstring
-
//Disk stuff.
//The return of data disks?? Just for transferring between genetics machine/cloning machine.
//TO-DO: Make the genetics machine accept them.
diff --git a/code/game/objects/items/devices/uplink_random_lists.dm b/code/game/objects/items/devices/uplink_random_lists.dm
index 1089a4f81cb..af954589f94 100644
--- a/code/game/objects/items/devices/uplink_random_lists.dm
+++ b/code/game/objects/items/devices/uplink_random_lists.dm
@@ -70,7 +70,7 @@ var/datum/uplink_random_selection/default_uplink_selection = new/datum/uplink_ra
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/ai_module, 25, 0)
items += new/datum/uplink_random_item(/datum/uplink_item/item/implants/imp_freedom)
- items += new/datum/uplink_random_item(/datum/uplink_item/item/implants/imp_compress)
+ items += new/datum/uplink_random_item(/datum/uplink_item/item/implants/imp_emp)
items += new/datum/uplink_random_item(/datum/uplink_item/item/implants/imp_explosive)
items += new/datum/uplink_random_item(/datum/uplink_item/item/medical/sinpockets, reselect_propbability = 20)
diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm
index 3891f3b8244..6118816a08c 100644
--- a/code/game/objects/items/weapons/implants/implant.dm
+++ b/code/game/objects/items/weapons/implants/implant.dm
@@ -3,44 +3,120 @@
/obj/item/implant
+ abstract_type = /obj/item/implant
name = "implant"
- icon = 'icons/obj/device.dmi'
- icon_state = "implant"
+ icon = 'icons/obj/item/implants.dmi'
w_class = ITEMSIZE_TINY
+ /**
+ * This gives the user an action button that allows them to activate the implant.
+ * If the implant needs no action button, then null this out.
+ * Or, if you want to add a unique action button, then replace this.
+ */
+ default_action_type = /datum/action/item_action/hands_free/activate/implant
+ action_button_name = "Activate Implant"
var/implanted = null
+ ///The mob that has been implanted with this
var/mob/imp_in = null
+ ///The organ/limb that has been implanted with this
var/obj/item/organ/external/part = null
- var/implant_color = "b"
- var/allow_reagents = 0
+ ///Implant icon name, used for getting the name of the implant for usage in the implant case name.
+ var/implant_icon = null
+ ///Implant color, used for overlaying the implant into an implanter.
+ var/implant_color = null
var/malfunction = 0
+ ///If advanced scanners would name these in results
+ var/known
+ ///If scanners can locate this implant at all
+ var/hidden
/obj/item/implant/Initialize()
. = ..()
implants += src
-/obj/item/implant/proc/trigger(emote, source as mob)
+/obj/item/implant/proc/trigger(emote, source)
+ return
+
+/obj/item/implant/ui_action_click()
+ INVOKE_ASYNC(src, PROC_REF(activate), "action_button")
+
+/obj/item/implant/item_action_slot_check(slot, mob/user)
+ return user = imp_in
+
+/obj/item/implant/proc/hear(message)
return
/obj/item/implant/proc/activate()
return
- // What does the implant do upon injection?
- // return 0 if the implant fails (ex. Revhead and loyalty implant.)
- // return 1 if the implant succeeds (ex. Nonrevhead and loyalty implant.)
-/obj/item/implant/proc/implanted(var/mob/source, mob/user)
- return 1
+/**
+ * What does the implant do upon injection?
+ * return FALSE if the implant fails (ex. Revhead and loyalty implant.)
+ * return TRUE if the implant succeeds (ex. Nonrevhead and loyalty implant.)
+*/
+/obj/item/implant/proc/implanted(mob/source)
+ return TRUE
+/obj/item/implant/proc/canImplant(mob/M, mob/user, target_zone)
+ var/mob/living/carbon/human/H = M
+ if(istype(H) && !H.get_organ(target_zone))
+ to_chat(user, SPAN_WARNING("\The [M] is missing that body part!"))
+ return FALSE
+ return TRUE
+
+/obj/item/implant/proc/implantInMob(mob/M, target_zone)
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ var/obj/item/organ/external/affected = H.get_organ(target_zone)
+ if(affected)
+ affected.implants += src
+ part = affected
+
+ forceMove(M)
+ imp_in = M
+ implanted = TRUE
+ implanted(M)
+
+ return TRUE
+
+///Remove implant from mob.
+/obj/item/implant/proc/removed()
+ imp_in = null
+ if(part)
+ part.implants -= src
+ part = null
+ implanted = FALSE
+
+///Called in surgery when incision is retracted open / ribs are opened - basically before you can take the implant out
+/obj/item/implant/proc/exposed()
+ return
+
+///Get implant specifications for the implant pad
/obj/item/implant/proc/get_data()
return "No information available"
-/obj/item/implant/proc/hear(message, source as mob)
- return
+/obj/item/implant/interact(user)
+ var/datum/browser/popup = new(user, capitalize(name), capitalize(name), 300, 700, src)
+ var/dat = "Implant Mini-Computer:
"
+ dat += get_data()
+ if(malfunction)
+ popup.title = "??? Implant"
+ dat = stars(dat,10)
+ popup.set_content(dat)
+ popup.open()
-/obj/item/implant/proc/islegal()
- return 0
+/**
+ * Determines if the implant is known as a legal implant or not.
+ *
+ * If TRUE, increases the chance of removal during surgery
+ */
+/obj/item/implant/proc/isLegal()
+ return FALSE
-/obj/item/implant/proc/meltdown() //breaks it down, making implant unrecongizible
- to_chat(imp_in, "You feel something melting inside [part ? "your [part.name]" : "you"]!")
+///Breaks the implant down, making it unrecognizable
+/obj/item/implant/proc/meltdown()
+ if(malfunction == MALFUNCTION_PERMANENT)
+ return
+ to_chat(imp_in, SPAN_DANGER("You feel something melting inside [part ? "your [part.name]" : "you"]!"))
if (part)
part.take_damage(burn = 15, used_weapon = "Electronics meltdown")
else
@@ -59,690 +135,5 @@
implants -= src
return ..()
-/obj/item/implant/proc/removed()
- imp_in = null
- if(part)
- part.implants -= src
- part = null
- implanted = 0
-
-/obj/item/implant/attackby(obj/item/I, mob/user)
- if(istype(I, /obj/item/implanter))
- var/obj/item/implanter/implanter = I
- if(implanter.imp)
- to_chat(user, SPAN_NOTICE("\The [implanter] already has an implant loaded."))
- return // It's full.
- user.drop_from_inventory(src)
- forceMove(implanter)
- implanter.imp = src
- implanter.update()
- else
- ..()
-
-/obj/item/implant/tracking
- name = "tracking implant"
- desc = "Track with this."
- var/id = 1.0
-
-/obj/item/implant/tracking/Initialize()
- var/list/tracking_list = list()
- for(var/obj/item/implant/tracking/T in implants)
- tracking_list += T
- id = length(tracking_list) + 1
- . = ..()
-
-/obj/item/implant/tracking/get_data()
- . = {"Implant Specifications:
-Name: Tracking Beacon
-Life: 10 minutes after death of host
-Important Notes: None
-
-Implant Details:
-Function: Continuously transmits low power signal. Useful for tracking.
-Special Features:
-Neuro-Safe- Specialized shell absorbs excess voltages self-destructing the chip if
-a malfunction occurs thereby securing safety of subject. The implant will melt and
-disintegrate into bio-safe elements.
-Integrity: Gradient creates slight risk of being overcharged and frying the
-circuitry. As a result neurotoxins can cause massive damage.
-Implant Specifics:
"}
-
-/obj/item/implant/tracking/emp_act(severity)
- if (malfunction) //no, dawg, you can't malfunction while you are malfunctioning
- return
- malfunction = MALFUNCTION_TEMPORARY
-
- var/delay = 20
- switch(severity)
- if(1)
- if(prob(60))
- meltdown()
- if(2)
- delay = rand(5*60*10,15*60*10) //from 5 to 15 minutes of free time
-
- spawn(delay)
- malfunction--
-
-//BS12 Explosive
-/obj/item/implant/explosive
- name = "explosive implant"
- desc = "A military grade micro bio-explosive. Highly dangerous."
- var/elevel = "Localized Limb"
- var/phrase
- var/setup_done = FALSE //Have we set this yet?
- var/uses_codewords = TRUE
- var/list/possible_explosions = list("Localized Limb", "Destroy Body")
- icon_state = "implant_evil"
-
-/obj/item/implant/explosive/Initialize()
- . = ..()
- if(uses_codewords)
- phrase = "You are [pick(adjectives)]"
-
-/obj/item/implant/explosive/get_data()
- . = {"
-Implant Specifications:
-Name: Robust Corp RX-78 Intimidation Class Implant
-Life: Activates upon codephrase.
-Important Notes: Explodes
-
-Implant Details:
-Function: Contains a compact, electrically detonated explosive that detonates upon receiving a specially encoded signal or upon host death.
-Special Features: Explodes. Explosion severity can be altered.
-Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."}
-
-/obj/item/implant/explosive/attackby(obj/item/I, mob/user)
- if(uses_codewords)
- if(istype(I, /obj/item/implanter))
- var/obj/item/implanter/implanter = I
- if(implanter.imp)
- to_chat(user, SPAN_NOTICE("\The [implanter] already has an implant loaded."))
- return // It's full.
- if(!setup_done)
- var/choice = alert("\The [src]'s default settings have not been changed. Continue?", "Ready for Implantation?", "Yes", "Cancel")
- if(choice == "Cancel")
- return
- to_chat(user, "You load \the [src] into \the [I]. The current setting is \"[elevel]\" and the current phrase is \"[phrase]\".")
- user.drop_from_inventory(src)
- forceMove(implanter)
- implanter.imp = src
- implanter.update()
- else
- ..()
-
-/obj/item/implant/explosive/hear_talk(mob/M, msg)
- hear(msg)
-
-/obj/item/implant/explosive/hear(var/msg)
- var/list/replacechars = list("\"" = "",">" = "","<" = "","(" = "",")" = "")
- msg = replace_characters(msg, replacechars)
- if(findtext(msg,phrase))
- activate()
-
-/obj/item/implant/explosive/activate()
- if(malfunction == MALFUNCTION_PERMANENT)
- return
-
- if(!imp_in)
- small_countdown()
- return
-
- message_admins("Explosive implant triggered in [imp_in] ([imp_in.key]). (JMP) ")
- log_game("Explosive implant triggered in [imp_in] ([imp_in.key]).")
- if(ishuman(imp_in))
- var/mob/living/carbon/human/T = imp_in
- if(elevel == "Localized Limb" && part)
- small_countdown()
- return //to avoid hotspot_expose.
- if(elevel == "Destroy Body")
- explosion(get_turf(T), -1, 0, 2, 6)
- T.gib()
- if(elevel == "Full Explosion")
- explosion_spread(get_turf(T), rand(8,13))
- T.gib()
- else if(ismob(imp_in))
- var/mob/M = imp_in
- M.gib()
-
- var/turf/F = get_turf(imp_in)
- if(F)
- F.hotspot_expose(3500,125)
- qdel(src)
-
-/obj/item/implant/explosive/proc/small_countdown()
- if(!imp_in)
- visible_message(SPAN_WARNING("Something begins beeping..."))
- if(ishuman(imp_in))
- var/message = "Something beeps inside of [imp_in][part ? "'s [part.name]" : ""]..." //for some reason SPAN_X and span() both hate having this in-line
- imp_in.visible_message(SPAN_WARNING(message))
- else if(ismob(imp_in))
- imp_in.visible_message(SPAN_WARNING("Something beeps inside of [imp_in]..."))
- playsound(loc, 'sound/items/countdown.ogg', 75, 1, -3)
- addtimer(CALLBACK(src, PROC_REF(small_boom)), 25)
-
-/obj/item/implant/explosive/proc/small_boom()
- if(!imp_in)
- explosion(get_turf(src), -1, 0, 2, 4)
- if(ishuman(imp_in) && part)
- //No tearing off these parts since it's pretty much killing. Mangle them.
- if(part.vital && !istype(part, /obj/item/organ/external/head)) //Head explodes
- part.createwound(BRUISE, 70)
- part.add_pain(50)
- imp_in.visible_message(SPAN_WARNING("[imp_in]'s [part.name] bursts open with a horrible ripping noise!"),
- SPAN_DANGER("Your [part.name] bursts open with a horrible ripping noise!"),
- SPAN_WARNING("You hear a horrible ripping noise."))
- else
- part.droplimb(0,DROPLIMB_BLUNT)
- playsound(get_turf(imp_in), BP_IS_ROBOTIC(part) ? 'sound/effects/meteorimpact.ogg' : 'sound/effects/splat.ogg')
- else if(ismob(imp_in))
- var/mob/M = imp_in
- M.gib() //Simple mobs just get got
- qdel(src)
-
-/proc/explosion_spread(turf/epicenter, power, adminlog = 1, z_transfer = UP|DOWN)
- var/datum/explosiondata/data = new
- data.epicenter = epicenter
- data.rec_pow = power
- data.spreading = TRUE
- data.adminlog = adminlog
- data.z_transfer = z_transfer
- SSexplosives.queue(data)
-
-/obj/item/implant/explosive/implanted(mob/source, mob/user)
- if(user.mind)
- user.mind.store_memory("\The [src] in [source] can be activated by saying something containing the phrase ''[phrase]'', say [phrase] to attempt to activate.", 0, 0)
- to_chat(usr, "\The [src] in [source] can be activated by saying something containing the phrase ''[phrase]'', say [phrase] to attempt to activate.")
- return TRUE
-
-/obj/item/implant/explosive/attack_self(mob/user)
- elevel = input(user, "What sort of explosion would you prefer?", "Implant Intent") as null|anything in possible_explosions
- phrase = input("Choose activation phrase:") as text
- var/list/replacechars = list("\"" = "",">" = "","<" = "","(" = "",")" = "")
- phrase = replace_characters(phrase, replacechars)
- user.mind.store_memory("\The [src] can be activated by saying something containing the phrase ''[phrase]'', say [phrase] to attempt to activate.", 0, 0)
- to_chat(user, "\The [src] can be activated by saying something containing the phrase ''[phrase]'', say [phrase] to attempt to activate.")
- setup_done = TRUE
-
-/obj/item/implant/explosive/emp_act(severity)
- if(malfunction)
- return
- malfunction = MALFUNCTION_TEMPORARY
- switch (severity)
- if(2.0) //Weak EMP will make implant tear limbs off.
- if(prob(50))
- small_countdown()
- if(1.0) //strong EMP will melt implant either making it go off, or disarming it
- if(prob(70))
- if(prob(50))
- small_countdown()
- else
- if(prob(50))
- activate() //50% chance of bye bye
- else
- meltdown() //50% chance of implant disarming
- addtimer(CALLBACK(src, PROC_REF(self_correct)), 20)
-
-/obj/item/implant/explosive/proc/self_correct()
- malfunction--
-
-/obj/item/implant/explosive/islegal()
- return FALSE
-
-/obj/item/implant/explosive/New()
- ..()
- become_hearing_sensitive(ROUNDSTART_TRAIT)
-
-/obj/item/implant/explosive/Destroy()
- return ..()
-
-/obj/item/implant/explosive/full
- possible_explosions = list("Localized Limb", "Destroy Body", "Full Explosion")
-
-/obj/item/implant/explosive/deadman
- name = "deadman explosive"
- desc = "A military grade micro bio-explosive that detonates upon death."
- icon_state = "implant_evil"
- uses_codewords = FALSE
-
-/obj/item/implant/explosive/deadman/get_data()
- . = {"
-Implant Specifications:
-Name: Robust Corp RX-78 Employee Management Implant
-Life: Activates upon death.
-Important Notes: Explodes
-
-Implant Details:
-Function: Contains a compact, electrically detonated explosive that detonates upon receiving a specially encoded signal or upon host death.
-Special Features: Explodes
-Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."}
-
-/obj/item/implant/explosive/deadman/attack_self(mob/user)
- return
-
-/obj/item/implant/explosive/deadman/hear(var/msg)
- return
-
-/obj/item/implant/explosive/deadman/process()
- if(malfunction)
- STOP_PROCESSING(SSprocessing, src)
- return
- if (!implanted)
- return
- var/mob/M = imp_in
-
- if(M.stat == DEAD)
- activate()
-
-/obj/item/implant/explosive/deadman/activate(var/cause)
- small_countdown(src)
- STOP_PROCESSING(SSprocessing, src)
-
-/obj/item/implant/explosive/deadman/small_boom()
- if(imp_in)
- explosion(get_turf(src), -1, 0, 1, 6)
- imp_in.gib()
- qdel(src)
-
-/obj/item/implant/explosive/deadman/implanted(mob/source)
- START_PROCESSING(SSprocessing, src)
- return TRUE
-
-/obj/item/implant/explosive/deadman/emp_act(severity)
- if(malfunction)
- return
- malfunction = MALFUNCTION_TEMPORARY
- switch (severity)
- if(3.0)
- if(prob(1))
- small_countdown()
- else if(prob(5))
- meltdown()
- if(2.0)
- if(prob(5))
- small_countdown()
- else if (prob(10))
- meltdown()
- if(1.0)
- if(prob(10))
- small_countdown()
- else if (prob(30))
- meltdown()
-
-/obj/item/implant/chem
- name = "chemical implant"
- desc = "Injects things."
- allow_reagents = 1
-
-/obj/item/implant/chem/get_data()
- . = {"
-Implant Specifications:
-Name: Robust Corp MJ-420 Prisoner Management Implant
-Life: Deactivates upon death but remains within the body.
-Important Notes: Due to the system functioning off of nutrients in the implanted subject's body, the subject
-will suffer from an increased appetite.
-
-Implant Details:
-Function: Contains a small capsule that can contain various chemicals. Upon receiving a specially encoded signal
-the implant releases the chemicals directly into the blood stream.
-Special Features:
-Micro-Capsule- Can be loaded with any sort of chemical agent via the common syringe and can hold 50 units.
-Can only be loaded while still in its original case.
-Integrity: Implant will last so long as the subject is alive. However, if the subject suffers from malnutrition,
-the implant may become unstable and either pre-maturely inject the subject or simply break."}
-
-
-/obj/item/implant/chem/New()
- ..()
- var/datum/reagents/R = new/datum/reagents(50)
- reagents = R
- R.my_atom = src
-
-
-/obj/item/implant/chem/trigger(emote, source as mob)
- if(emote == "deathgasp")
- src.activate(src.reagents.total_volume)
- return
-
-
-/obj/item/implant/chem/activate(var/cause)
- if((!cause) || (!src.imp_in)) return 0
- var/mob/living/carbon/R = src.imp_in
- src.reagents.trans_to_mob(R, cause, CHEM_BLOOD)
- to_chat(R, "You hear a faint *beep*.")
- if(!src.reagents.total_volume)
- to_chat(R, "You hear a faint click from your chest.")
- spawn(0)
- qdel(src)
-
-/obj/item/implant/chem/emp_act(severity)
- if (malfunction)
- return
- malfunction = MALFUNCTION_TEMPORARY
-
- switch(severity)
- if(1)
- if(prob(60))
- activate(20)
- if(2)
- if(prob(30))
- activate(5)
-
- spawn(20)
- malfunction--
-
-/obj/item/implant/mindshield
- name = "mind shield implant"
- desc = "A controversial and debatably unethical neurostimulator and autohypnosis device. When implanted against the amygdala, it ensures the host maintains a consistent personality, preventing outside interference through brainwashing or hypnotic suggestion."
-
-/obj/item/implant/mindshield/get_data()
- . = {"
-Implant Specifications:
-Name: [current_map.company_name] Employee Management Implant
-Life: Ten years.
-Important Notes: Personnel injected with this device tend to be much more resistant to brain washing and other external influences.
-
-Implant Details:
-Function: Contains a small pod of nanobots that manipulate the host's mental functions.
-Special Features: Will prevent and cure most forms of brainwashing.
-Integrity: Implant will last so long as the nanobots are inside the bloodstream."}
-
-/obj/item/implant/mindshield/emp_act(severity)
- if (malfunction)
- return
- malfunction = MALFUNCTION_TEMPORARY
-
- activate("emp")
- if(severity == 1)
- if(prob(50))
- meltdown()
- else if (prob(50))
- malfunction = MALFUNCTION_PERMANENT
- return
- spawn(20)
- malfunction--
-
-/obj/item/implant/mindshield/ipc
- name = "software protection chip"
- desc = "A dedicated processor core designed to identify and terminate malignant software, ensuring a synthetics protection from outside hacking."
-
-/obj/item/implant/mindshield/ipc/implanted(mob/M)
- if (!isipc(M))
- return
-
- ..()
-
-/obj/item/implant/mindshield/sol
- name = "loyalty implant"
- desc = "Makes you loyal to the Sol Alliance, or to a certain individual."
-
-/obj/item/implant/mindshield/sol/implanted(mob/M)
- if(!istype(M, /mob/living/carbon/human)) return 0
- var/mob/living/carbon/human/H = M
- var/datum/antagonist/antag_data = get_antag_data(H.mind.special_role)
- if(antag_data && (antag_data.flags & ANTAG_IMPLANT_IMMUNE))
- H.visible_message("[H] seems to resist the implant!", "You feel the tendrils of the Sol Alliance try to invade your mind!")
- return 0
- else
- clear_antag_roles(H.mind, 1)
- to_chat(H, "You feel a surge of loyalty towards Admiral Michael Frost.")
- return 1
-
-/obj/item/implant/adrenalin
- name = "adrenalin"
- desc = "Removes all stuns and knockdowns."
- var/uses
-
-/obj/item/implant/adrenalin/get_data()
- . = {"
-Implant Specifications:
-Name: Cybersun Industries Adrenalin Implant
-Life: Five days.
-Important Notes: Illegal
-
-Implant Details: Subjects injected with implant can activate a massive injection of adrenalin.
-Function: Contains nanobots to stimulate body to mass-produce Adrenalin.
-Special Features: Will prevent and cure most forms of brainwashing.
-Integrity: Implant can only be used three times before the nanobots are depleted."}
-
-
-/obj/item/implant/adrenalin/trigger(emote, mob/source as mob)
- if (src.uses < 1)
- return 0
- if (emote == "pale")
- src.uses--
- to_chat(source, "You feel a sudden surge of energy!")
- source.SetStunned(0)
- source.SetWeakened(0)
- source.SetParalysis(0)
-
-
-/obj/item/implant/adrenalin/implanted(mob/source)
- source.mind.store_memory("A implant can be activated by using the pale emote, say *pale to attempt to activate.", 0, 0)
- to_chat(source, "The implanted freedom implant can be activated by using the pale emote, say *pale to attempt to activate.")
- return 1
-
-
-/obj/item/implant/death_alarm
- name = "death alarm implant"
- desc = "An alarm which monitors host vital signs and transmits a radio message upon death."
- var/mobname = "Will Robinson"
-
-/obj/item/implant/death_alarm/get_data()
- . = {"
-Implant Specifications:
-Name: [current_map.company_name] \"Profit Margin\" Class Employee Lifesign Sensor
-Life: Activates upon death.
-Important Notes: Alerts crew to crewmember death.
-
-Implant Details:
-Function: Contains a compact radio signaler that triggers when the host's lifesigns cease.
-Special Features: Alerts crew to crewmember death.
-Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."}
-
-/obj/item/implant/death_alarm/process()
- if (!implanted)
- return
- var/mob/M = imp_in
-
- if(QDELETED(M)) // If the mob got gibbed
- M = null
- activate()
- else if(M.stat == 2)
- activate("death")
-
-/obj/item/implant/death_alarm/activate(var/cause)
- var/mob/M = imp_in
- var/area/t = get_area(M)
- switch (cause)
- if("death")
- var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null)
- if(istype(t, /area/antag) || istype(t, /area/shuttle/mercenary) || istype(t, /area/shuttle/syndicate_elite) )
- //give the syndies a bit of stealth
- a.autosay("[mobname] has died in Space!", "[mobname]'s Death Alarm")
- else
- a.autosay("[mobname] has died in [t.name]!", "[mobname]'s Death Alarm")
- qdel(a)
- STOP_PROCESSING(SSprocessing, src)
- if ("emp")
- var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null)
- var/name = prob(50) ? t.name : pick(the_station_areas)
- a.autosay("[mobname] has died in [name]!", "[mobname]'s Death Alarm")
- qdel(a)
- else
- var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset(null)
- a.autosay("[mobname] has died-zzzzt in-in-in...", "[mobname]'s Death Alarm")
- qdel(a)
- STOP_PROCESSING(SSprocessing, src)
-
-/obj/item/implant/death_alarm/emp_act(severity) //for some reason alarms stop going off in case they are emp'd, even without this
- if (malfunction) //so I'm just going to add a meltdown chance here
- return
- malfunction = MALFUNCTION_TEMPORARY
-
- activate("emp") //let's shout that this dude is dead
- if(severity == 1)
- if(prob(40)) //small chance of obvious meltdown
- meltdown()
- else if (prob(60)) //but more likely it will just quietly die
- malfunction = MALFUNCTION_PERMANENT
- STOP_PROCESSING(SSprocessing, src)
-
- spawn(20)
- malfunction--
-
-/obj/item/implant/death_alarm/implanted(mob/source as mob)
- mobname = source.real_name
- START_PROCESSING(SSprocessing, src)
- return 1
-
-/obj/item/implant/compressed
- name = "compressed matter implant"
- desc = "Based on compressed matter technology, can store a single item."
- icon_state = "implant_evil"
- var/activation_emote = "sigh"
- var/obj/item/scanned = null
-
-/obj/item/implant/compressed/attackby(var/obj/item/T, mob/user)
- if(T.isscrewdriver())
- if(!scanned)
- to_chat(user, SPAN_NOTICE("There is nothing to remove from the implant."))
- else
- to_chat(user, SPAN_NOTICE("You remove \the [scanned] from the implant."))
- user.put_in_hands(scanned)
- scanned = null
- if(istype(T, /obj/item/implanter))
- var/obj/item/implanter/implanter = T
- if(implanter.imp)
- to_chat(user, SPAN_NOTICE("\The [implanter] already has an implant loaded."))
- return
- user.drop_from_inventory(src)
- forceMove(implanter)
- implanter.imp = src
- implanter.update()
- else
- ..()
-
-/obj/item/implant/compressed/get_data()
- . = {"
-Implant Specifications:
-Name: [current_map.company_name] \"Profit Margin\" Class Employee Lifesign Sensor
-Life: Activates upon death.
-Important Notes: Alerts crew to crewmember death.
-
-Implant Details:
-Function: Contains a compact radio signaler that triggers when the host's lifesigns cease.
-Special Features: Alerts crew to crewmember death.
-Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."}
-
-/obj/item/implant/compressed/trigger(emote, mob/source as mob)
- if (src.scanned == null)
- return 0
-
- if (emote == src.activation_emote)
- to_chat(source, "The air glows as \the [src.scanned.name] uncompresses.")
- activate()
-
-/obj/item/implant/compressed/activate()
- var/turf/t = get_turf(src)
- if (imp_in)
- imp_in.put_in_hands(scanned)
- else
- scanned.forceMove(t)
- qdel(src)
-
-/obj/item/implant/compressed/implanted(mob/source as mob)
- src.activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
- if (source.mind)
- source.mind.store_memory("Compressed matter implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", 0, 0)
- to_chat(source, "The implanted compressed matter implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.")
- return 1
-
-/obj/item/implant/compressed/islegal()
- return 0
-
-/obj/item/implant/aggression
- name = "aggression implant"
- desc = "An implant that microdoses its user with chemicals that induce anger."
-
-/obj/item/implant/aggression/get_data()
- . = {"
- Implant Specifications:
- Name: Aggression Implant
- Life: N/A.
- Important Notes: Users injected with this device get increasingly angry to a breaking point. Users tend to expire before the implant does.
-
- Implant Details:
- Function: Contains a small pod of nanobots that manipulate the host's mental functions.
- Integrity: Implant will last so long as the nanobots are inside the bloodstream."}
-
-/obj/item/implant/aggression/implanted(mob/M)
- if(!istype(M, /mob/living/carbon/human))
- return FALSE
-
- var/mob/living/carbon/human/H = M
-
- for(var/obj/item/implant/mindshield/I in H)
- if(I.implanted)
- to_chat(H, SPAN_DANGER("Rage surges through your body, but the nanobots from your mind shield implant stop it soon after it starts!"))
- return TRUE
-
- var/datum/antagonist/antag_data = get_antag_data(H.mind.special_role)
- if(antag_data?.flags & ANTAG_IMPLANT_IMMUNE)
- H.visible_message("[H] seems to resist the implant!", "You feel rage overtake your body, but you manage to fend it off by sheer will!")
- log_and_message_admins("[key_name(H)] was implanted by an aggression implant, but was not effected.", H)
- else if(antag_data?.id == MODE_LOYALIST)
- clear_antag_roles(H.mind, 1)
- to_chat(H, SPAN_DANGER("You feel a surge of rage override your loyalty!"))
- log_and_message_admins("[key_name(H)] was implanted by an aggression implant, clearing their loyalist status!", H)
- else
- to_chat(H, SPAN_DANGER("You feel a surge of rage course through your body and very soul!"))
- log_and_message_admins("[key_name(H)] was implanted by an aggression implant!", H)
- return TRUE
-
-/obj/item/implant/aggression/emp_act(severity)
- if(malfunction)
- return
- malfunction = MALFUNCTION_TEMPORARY
-
- activate("emp")
- if(severity == 1)
- if(prob(50))
- meltdown()
- else if(prob(50))
- malfunction = MALFUNCTION_PERMANENT
- return
- spawn(20)
- malfunction--
-
-/obj/item/implant/anti_augment
- name = "augmentation disrupter implant"
- desc = "An implant that emits signals able to disrupt the use of commonly used augments."
-
-/obj/item/implant/anti_augment/get_data()
- . = {"
-Implant Specifications:
-Name: Augmentation Disrupter Implant
-Life: Three Months.
-Important Notes: Emits a signal able to block most augments from functioning..
-
-Implant Details:
-Function: Emits a short radio wave that will block most augments.
-Special Features: Will stop the host from using any augment they might have.
-Integrity: Implant will last so long as it inside the host."}
-
-/obj/item/implant/anti_augment/emp_act(severity)
- switch(severity)
- if(1.0)
- if (prob(75))
- qdel(src)
- if(2.0)
- if (prob(50))
- qdel(src)
- if(3.0)
- if (prob(25))
- qdel(src)
- return
-
-
#undef MALFUNCTION_TEMPORARY
#undef MALFUNCTION_PERMANENT
diff --git a/code/game/objects/items/weapons/implants/implantcase.dm b/code/game/objects/items/weapons/implants/implantcase.dm
index 49b2f572cb4..4ccb03863e6 100644
--- a/code/game/objects/items/weapons/implants/implantcase.dm
+++ b/code/game/objects/items/weapons/implants/implantcase.dm
@@ -1,183 +1,86 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
-
+/**
+ * Item used to store implants. Can be renamed with a pen. Implants are moved between these and implanters when a mob uses an implanter on the case.
+ */
/obj/item/implantcase
- name = "glass case"
- desc = "A case containing an implant."
- icon = 'icons/obj/items.dmi'
- icon_state = "implantcase-0"
+ name = "implant case"
+ desc = "An aluminium case, which can safely contain an implant."
+ icon = 'icons/obj/item/implants.dmi'
+ icon_state = "implantcase"
item_state = "implantcase"
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_TINY
+ ///The implant within the case
var/obj/item/implant/imp = null
-/obj/item/implantcase/proc/update()
- if (src.imp)
- src.icon_state = text("implantcase-[]", src.imp.implant_color)
- else
- src.icon_state = "implantcase-0"
- return
+/obj/item/implantcase/Initialize(mapload)
+ . = ..()
+ if(ispath(imp))
+ imp = new imp(src)
+ update_description()
+ update_icon()
-/obj/item/implantcase/attackby(obj/item/I as obj, mob/user as mob)
- ..()
+/obj/item/implantcase/proc/update_description()
+ if(imp)
+ desc = "An aluminium case, containing \a [imp]."
+ origin_tech = imp.origin_tech
+ else
+ desc = "An aluminium case, which can safely contain an implant."
+ origin_tech.Cut()
+
+
+/obj/item/implantcase/update_icon()
+ cut_overlays()
+ if (imp)
+ var/overlay_icon_state = "implantstorage_[imp.implant_icon]"
+ var/mutable_appearance/overlay_implant_icon = mutable_appearance(icon, overlay_icon_state)
+ add_overlay(overlay_implant_icon)
+
+/obj/item/implantcase/attackby(obj/item/I, mob/user)
if (I.ispen())
- var/t = input(user, "What would you like the label to be?", text("[]", src.name), null) as text
+ var/t = input(user, "What would you like the label to be?", text("[]", src.name), null)
if (user.get_active_hand() != I)
return
- if((!in_range(src, usr) && src.loc != user))
+ if((!in_range(src, usr) && loc != user))
return
t = sanitizeSafe(t, MAX_NAME_LEN)
if(t)
- src.name = text("Glass Case - '[]'", t)
+ src.name = text("implant case - '[]'", t)
+ desc = "An aluminium case, containing \a [t] implant."
else
- src.name = "Glass Case"
+ src.name = "implant case"
+ desc = "An aluminium case, which can safely contain an implant."
else if(istype(I, /obj/item/reagent_containers/syringe))
- if(!src.imp) return
- if(!src.imp.allow_reagents) return
- if(src.imp.reagents.total_volume >= src.imp.reagents.maximum_volume)
- to_chat(user, "\The [src] is full.")
- else
- var/trans = I.reagents.trans_to_obj(src.imp, 5)
- if (trans > 0)
- to_chat(user, "You inject [trans] units of the solution. The syringe now contains [I.reagents.total_volume] units.")
+ imp.attackby(I, user)
else if (istype(I, /obj/item/implanter))
var/obj/item/implanter/M = I
- if (M.imp)
- if ((src.imp || M.imp.implanted))
- return
+ if (M.imp && !imp && !M.imp.implanted)
M.imp.forceMove(src)
- src.imp = M.imp
+ imp = M.imp
M.imp = null
- src.update()
- M.update()
+ else if (imp && !M.imp)
+ imp.forceMove(M)
+ M.imp = src.imp
+ imp = null
+ update_description()
+ update_icon()
+ M.update_icon()
+ else if (istype(I, /obj/item/implant))
+ if(imp == null)
+ to_chat(user, SPAN_NOTICE("You slide \the [I] into \the [src]."))
+ user.drop_from_inventory(I,src)
+ imp = I
else
- if (src.imp)
- if (M.imp)
- return
- src.imp.forceMove(M)
- M.imp = src.imp
- src.imp = null
- update()
- M.update()
- return
-
-
-/obj/item/implantcase/tracking
- name = "glass case - 'tracking'"
- desc = "A case containing a tracking implant."
- icon_state = "implantcase-b"
-
-/obj/item/implantcase/tracking/New()
- src.imp = new /obj/item/implant/tracking( src )
+ to_chat(user, SPAN_WARNING("\The [src] already has an implant inside of it!"))
+ update_description()
+ update_icon()
+ else if(istype(I, /obj/item/implantpad))
+ var/obj/item/implantpad/pad = I
+ if(!pad.case)
+ user.drop_from_inventory(src,pad)
+ pad.case = src
+ pad.update_icon()
+ else
+ to_chat(user, SPAN_WARNING("\The [pad] already has an implant case attached to it!"))
..()
- return
-
-/obj/item/implantcase/explosive
- name = "glass case - 'explosive'"
- desc = "A case containing an explosive implant."
- icon_state = "implantcase-r"
-
-/obj/item/implantcase/explosive/New()
- src.imp = new /obj/item/implant/explosive( src )
- ..()
- return
-
-
-/obj/item/implantcase/chem
- name = "glass case - 'chem'"
- desc = "A case containing a chemical implant."
- icon_state = "implantcase-b"
-
-/obj/item/implantcase/chem/New()
- src.imp = new /obj/item/implant/chem( src )
- ..()
- return
-
-
-/obj/item/implantcase/loyalty
- name = "glass case - 'mind shield'"
- desc = "A case containing a mind shield implant."
- icon_state = "implantcase-r"
-
-/obj/item/implantcase/loyalty/New()
- src.imp = new /obj/item/implant/mindshield( src )
- ..()
- return
-
-
-/obj/item/implantcase/death_alarm
- name = "glass case - 'death alarm'"
- desc = "A case containing a death alarm implant."
- icon_state = "implantcase-b"
-
-/obj/item/implantcase/death_alarm/New()
- src.imp = new /obj/item/implant/death_alarm( src )
- ..()
- return
-
-
-/obj/item/implantcase/freedom
- name = "glass case - 'freedom'"
- desc = "A case containing a freedom implant."
- icon_state = "implantcase-r"
-
-/obj/item/implantcase/freedom/New()
- src.imp = new /obj/item/implant/freedom( src )
- ..()
- return
-
-
-/obj/item/implantcase/adrenalin
- name = "glass case - 'adrenalin'"
- desc = "A case containing an adrenalin implant."
- icon_state = "implantcase-b"
-
-/obj/item/implantcase/adrenalin/New()
- src.imp = new /obj/item/implant/adrenalin( src )
- ..()
- return
-
-
-/obj/item/implantcase/explosive/deadman
- name = "glass case - 'explosive'"
- desc = "A case containing an explosive."
- icon_state = "implantcase-r"
-
-/obj/item/implantcase/explosive/deadman/New()
- src.imp = new /obj/item/implant/explosive/deadman( src )
- ..()
- return
-
-
-/obj/item/implantcase/health
- name = "glass case - 'health'"
- desc = "A case containing a health tracking implant."
- icon_state = "implantcase-b"
-
-/obj/item/implantcase/health/New()
- src.imp = new /obj/item/implant/health( src )
- ..()
- return
-
-
-/obj/item/implantcase/aggression
- name = "glass case - 'aggression'"
- desc = "A case containing an aggression inducing implant."
- icon_state = "implantcase-b"
-
-/obj/item/implantcase/aggression/New()
- src.imp = new /obj/item/implant/aggression(src)
- ..()
- return
-
-
-/obj/item/implantcase/anti_augment
- name = "glass case - 'augmentation disrupter'"
- desc = "A case containing an augmentation disrupter implant."
- icon_state = "implantcase-b"
-
-/obj/item/implantcase/anti_augment/New()
- src.imp = new /obj/item/implant/anti_augment(src)
- ..()
- return
diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/game/objects/items/weapons/implants/implanter.dm
index 6dfc7b56764..abcd38e60e6 100644
--- a/code/game/objects/items/weapons/implants/implanter.dm
+++ b/code/game/objects/items/weapons/implants/implanter.dm
@@ -1,32 +1,35 @@
/obj/item/implanter
name = "implanter"
- icon = 'icons/obj/item/reagent_containers/syringe.dmi'
+ icon = 'icons/obj/item/implants.dmi'
contained_sprite = TRUE
- icon_state = "implanter0"
- item_state = "syringe_0"
+ icon_state = "implanter-0"
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_SMALL
matter = list(DEFAULT_WALL_MATERIAL = 320, MATERIAL_GLASS = 800)
var/obj/item/implant/imp = null
-/obj/item/implanter/attack_self(var/mob/user)
- if(!imp)
- return ..()
- imp.forceMove(get_turf(src))
- user.put_in_hands(imp)
- to_chat(user, "You remove \the [imp] from \the [src].")
- name = "implanter"
- imp = null
- update()
- return
+/obj/item/implanter/New()
+ if(ispath(imp))
+ imp = new imp(src)
+ ..()
+ update_icon()
-/obj/item/implanter/proc/update()
+/obj/item/implanter/update_icon()
+ cut_overlays()
+ icon_state = "implanter-[imp ? "1" : "0"]"
if (imp)
- icon_state = "implanter1"
+ var/mutable_appearance/overlay_implant_icon = mutable_appearance(icon, "implanter-overlay")
+ overlay_implant_icon.color = imp.implant_color
+ add_overlay(overlay_implant_icon)
+
+/obj/item/implanter/attackby(obj/item/I, mob/user)
+ if(!imp && istype(I, /obj/item/implant) && user.unEquip(I,src))
+ to_chat(usr, SPAN_NOTICE("You slide \the [I] into \the [src]."))
+ imp = I
+ update_icon()
else
- icon_state = "implanter0"
- return
+ ..()
/obj/item/implanter/attack(mob/living/carbon/human/M, mob/user, var/target_zone)
if(!istype(M))
@@ -35,15 +38,15 @@
var/obj/item/organ/external/affected = M.get_organ(target_zone)
if(user && imp && affected)
- M.visible_message("[user] is attempting to implant [M] in \the [affected.name].")
+ M.visible_message(SPAN_WARNING("[user] is attempting to implant [M] in \the [affected.name]."))
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
user.do_attack_animation(M)
var/turf/T1 = get_turf(M)
- if (T1 && ((M == user) || do_after(user, 50)))
+ if (T1 && ((M == user) || do_after(user, 5 SECONDS)))
if(user && M && (get_turf(M) == T1) && src && imp)
- M.visible_message("[M] has been implanted by [user] in the [affected.name].")
+ M.visible_message(SPAN_WARNING("[M] has been implanted by [user] in the [affected.name]."))
admin_attack_log(user, M, "Implanted using \the [name] ([imp.name])", "Implanted with \the [name] ([imp.name])", "used an implanter, [name] ([imp.name]), on")
@@ -54,101 +57,12 @@
affected.implants += imp
imp.part = affected
BITSET(M.hud_updateflag, IMPLOYAL_HUD)
- if(istype(imp, /obj/item/implanter/loyalty))
- to_chat(M, "")
imp = null
- update()
+ update_icon()
return
-/obj/item/implanter/loyalty
- name = "implanter-loyalty"
-
-/obj/item/implanter/loyalty/New()
- imp = new /obj/item/implant/mindshield(src)
- ..()
- update()
- return
-
-/obj/item/implanter/explosive
- name = "implanter (E)"
-
-/obj/item/implanter/explosive/New()
- imp = new /obj/item/implant/explosive(src)
- ..()
- update()
- return
-
-/obj/item/implanter/adrenalin
- name = "implanter-adrenalin"
-
-/obj/item/implanter/adrenalin/New()
- imp = new /obj/item/implant/adrenalin(src)
- ..()
- update()
- return
-
-/obj/item/implanter/compressed
- name = "implanter (C)"
-
-/obj/item/implanter/compressed/New()
- imp = new /obj/item/implant/compressed( src )
- ..()
- update()
- return
-
-/obj/item/implanter/compressed/attack(mob/M as mob, mob/user as mob)
- var/obj/item/implant/compressed/c = imp
- if (!c) return
- if (c.scanned == null)
- to_chat(user, "Please scan an object with the implanter first.")
- return
- ..()
-
-/obj/item/implanter/compressed/afterattack(atom/A, mob/user as mob, proximity)
- if(!proximity)
- return
- if(istype(A,/obj/item) && imp)
- var/obj/item/implant/compressed/c = imp
- if(istype(A,/obj/item/implant/compressed))
- to_chat(user, SPAN_NOTICE("The implant is loaded into the implanter."))
- return
- if (c.scanned)
- to_chat(user, SPAN_WARNING("Something is already scanned inside the implant!"))
- return
- c.scanned = A
- if(istype(A.loc,/mob/living/carbon/human))
- var/mob/living/carbon/human/H = A.loc
- H.remove_from_mob(A)
- else if(istype(A.loc,/obj/item/storage))
- var/obj/item/storage/S = A.loc
- S.remove_from_storage(A)
- A.loc.contents.Remove(A)
- update()
-
-/obj/item/implanter/freedom/Initialize()
- imp = new /obj/item/implant/freedom( src )
- . = ..()
- update()
-
-/obj/item/implanter/uplink
- name = "implanter (U)"
-
-/obj/item/implanter/uplink/Initialize()
- imp = new /obj/item/implant/uplink( src )
- . = ..()
- update()
-
-/obj/item/implanter/anti_augment
- name = "implanter-augmentation disrupter"
-
-/obj/item/implanter/anti_augment/New()
- imp = new /obj/item/implant/anti_augment(src)
- ..()
- update()
- return
-
/obj/item/implanter/ipc_tag
name = "IPC tag implanter"
desc = "A special implanter used for implanting synthetics with a special tag."
@@ -157,9 +71,9 @@
/obj/item/implanter/ipc_tag/Initialize()
. = ..()
ipc_tag = new /obj/item/organ/internal/ipc_tag(src)
- update()
+ update_icon()
-/obj/item/implanter/ipc_tag/update()
+/obj/item/implanter/ipc_tag/update_icon()
if(ipc_tag)
icon_state = "cimplanter1"
else
@@ -195,7 +109,7 @@
ipc_tag.serial_number = uppertext(dd_limittext(md5(M.real_name), 12))
ipc_tag = null
- update()
+ update_icon()
/obj/item/implanter/ipc_tag/attackby(obj/item/I, mob/user)
if(I.isscrewdriver())
@@ -206,7 +120,7 @@
ipc_tag.forceMove(get_turf(user))
user.put_in_hands(ipc_tag)
ipc_tag = null
- update()
+ update_icon()
return
if(istype(I, /obj/item/organ/internal/ipc_tag))
if(ipc_tag)
@@ -214,6 +128,6 @@
return
ipc_tag = I
user.drop_from_inventory(I, src)
- update()
+ update_icon()
return
..()
diff --git a/code/game/objects/items/weapons/implants/implantfreedom.dm b/code/game/objects/items/weapons/implants/implantfreedom.dm
deleted file mode 100644
index 20ce9ea08ab..00000000000
--- a/code/game/objects/items/weapons/implants/implantfreedom.dm
+++ /dev/null
@@ -1,74 +0,0 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
-
-/obj/item/implant/freedom
- name = "freedom implant"
- desc = "Use this to escape from those evil Red Shirts."
- implant_color = "r"
- var/activation_emote = "chuckle"
- var/uses = 1
-
-/obj/item/implant/freedom/New()
- uses = rand(1, 5)
- ..()
-
-/obj/item/implant/freedom/trigger(emote, mob/living/carbon/source)
- if(!activation_emote)
- return
- if(uses < 1)
- to_chat(source, SPAN_WARNING("\The [src] gives a faint beep inside your head, indicating that it's out of uses!"))
- activation_emote = null //Disable this to allow them to emote normally
- return
- if(emote == activation_emote)
- uses--
- to_chat(source, "You feel a faint click.")
- if(source.handcuffed)
- var/obj/item/W = source.handcuffed
- source.handcuffed = null
- if(source.buckled_to && source.buckled_to.buckle_require_restraints)
- source.buckled_to.unbuckle()
- source.update_inv_handcuffed()
- if(source.client)
- source.client.screen -= W
- if(W)
- W.forceMove(source.loc)
- dropped(source)
- if (W)
- W.layer = initial(W.layer)
- if(source.legcuffed)
- var/obj/item/W = source.legcuffed
- source.legcuffed = null
- source.update_inv_legcuffed()
- if(source.client)
- source.client.screen -= W
- if(W)
- W.forceMove(source.loc)
- dropped(source)
- if(W)
- W.layer = initial(W.layer)
- return
-
-
-/obj/item/implant/freedom/implanted(mob/living/carbon/source)
- activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
- if(source.mind)
- source.mind.store_memory("\The [src] can be activated by using the [activation_emote] emote, say *[activation_emote] to attempt to activate.")
- to_chat(source, "The implanted [src] can be activated by using the [activation_emote] emote, say *[activation_emote] to attempt to activate.")
- return TRUE
-
-
-/obj/item/implant/freedom/get_data()
- var/dat = {"
-Implant Specifications:
-Name: Freedom Beacon
-Life: optimum 5 uses
-Important Notes: Illegal
-
-Implant Details:
-Function: Transmits a specialized cluster of signals to override handcuff locking
-mechanisms
-Special Features:
-Neuro-Scan- Analyzes certain shadow signals in the nervous system
-Integrity: The battery is extremely weak and commonly after injection its
-life can drive down to only 1 use.
-No Implant Specifics"}
- return dat
diff --git a/code/game/objects/items/weapons/implants/implantpad.dm b/code/game/objects/items/weapons/implants/implantpad.dm
index f0bd1cbcd44..a2ffd62317d 100644
--- a/code/game/objects/items/weapons/implants/implantpad.dm
+++ b/code/game/objects/items/weapons/implants/implantpad.dm
@@ -1,7 +1,7 @@
/obj/item/implantpad
name = "implantpad"
desc = "A device used to modify implants."
- icon = 'icons/obj/items.dmi'
+ icon = 'icons/obj/item/implants.dmi'
icon_state = "implantpad-0"
item_state = "electronic"
throw_speed = 1
@@ -12,16 +12,23 @@
var/listening = TRUE
/obj/item/implantpad/update_icon()
+ cut_overlays()
icon_state = "implantpad-[case ? "1" : "0"]"
+ if(case.imp)
+ var/obj/item/implant/caseimplant = case.imp
+ var/implant_overlay_icon_state = "implantstorage_[caseimplant.implant_icon]"
+ var/mutable_appearance/implant_case_implant_overlay = mutable_appearance(icon, implant_overlay_icon_state)
+ add_overlay(implant_case_implant_overlay)
+
/obj/item/implantpad/attack_hand(mob/user)
- if(src.case && (user.l_hand == src || user.r_hand == src))
+ if(case && (user.l_hand == src || user.r_hand == src))
user.put_in_active_hand(case)
- src.case.add_fingerprint(user)
- src.case = null
+ case.add_fingerprint(user)
+ case = null
- src.add_fingerprint(user)
+ add_fingerprint(user)
update_icon()
return
return ..()
@@ -30,28 +37,17 @@
if(istype(C, /obj/item/implantcase))
if(!case)
user.drop_from_inventory(C,src)
- src.case = C
+ case = C
update_icon()
else
- to_chat(user, SPAN_WARNING("\The [src] already has an implant case inside it!"))
- return
+ to_chat(user, SPAN_WARNING("\The [src] already has an implant case attached to it!"))
..()
/obj/item/implantpad/attack_self(mob/user)
- user.set_machine(src)
- var/dat = "Implant Mini-Computer:
"
- if (src.case)
- if(src.case.imp)
- if(istype(src.case.imp, /obj/item/implant))
- dat += src.case.imp.get_data()
- else
- dat += "The implant casing is empty."
+ if(case.imp)
+ case.imp.interact(user)
else
- dat += "Please insert an implant casing!"
-
- var/datum/browser/implantpad_win = new(user, "implantpad", capitalize_first_letters(name))
- implantpad_win.set_content(dat)
- implantpad_win.open()
+ to_chat(user, SPAN_WARNING("There's no implant loaded in \the [src]!"))
/obj/item/implantpad/Topic(href, href_list)
..()
@@ -68,4 +64,4 @@
src.attack_self(M)
src.add_fingerprint(usr)
else
- usr << browse(null, "window=implantpad")
\ No newline at end of file
+ usr << browse(null, "window=implantpad")
diff --git a/code/game/objects/items/weapons/implants/implants/adrenaline.dm b/code/game/objects/items/weapons/implants/implants/adrenaline.dm
new file mode 100644
index 00000000000..5f3ff7dea20
--- /dev/null
+++ b/code/game/objects/items/weapons/implants/implants/adrenaline.dm
@@ -0,0 +1,41 @@
+/obj/item/implant/adrenaline
+ name = "adrenaline implant"
+ desc = "Removes all stuns and knockdowns."
+ icon_state = "implant_chem" //Temporary, this is currently unused so no need for a custom sprite
+ implant_icon = "chem" //Ditto
+ implant_color = "#eba7eb" //Ditto
+ origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 2, TECH_ILLEGAL = 2)
+ default_action_type = /datum/action/item_action/hands_free/activate/implant/adrenaline
+ action_button_name = "Activate Adrenaline Implant"
+ var/uses = 3
+
+/obj/item/implant/adrenaline/get_data()
+ . = {"
+Implant Specifications:
+Name: Kumar Arms ZV-16 Combat Readiness Implant
+Life: Five days.
+Important Notes: Illegal for non-licensed personnel in Biesel space.
+
+Implant Details: Subjects injected with implant can activate a massive injection of adrenaline.
+Function: Contains nanobots to stimulate body to mass-produce Adrenaline.
+Integrity: Implant can only be used three times before the nanobots are depleted."}
+
+/obj/item/implant/adrenaline/activate()
+ if (malfunction || !imp_in)
+ return
+ if (uses < 1)
+ to_chat(imp_in, SPAN_WARNING("\The [src] gives a faint beep inside your head, indicating that it's out of uses!"))
+ return
+ uses--
+ to_chat(imp_in, SPAN_NOTICE("You feel a sudden surge of energy!"))
+ imp_in.SetStunned(0)
+ imp_in.SetWeakened(0)
+ imp_in.SetParalysis(0)
+
+/obj/item/implantcase/adrenaline
+ name = "glass case - 'adrenalin'"
+ imp = /obj/item/implant/adrenaline
+
+/obj/item/implanter/adrenaline
+ name = "implanter-adrenaline"
+ imp = /obj/item/implant/adrenaline
diff --git a/code/game/objects/items/weapons/implants/implants/aggression.dm b/code/game/objects/items/weapons/implants/implants/aggression.dm
new file mode 100644
index 00000000000..b77ee2e408b
--- /dev/null
+++ b/code/game/objects/items/weapons/implants/implants/aggression.dm
@@ -0,0 +1,67 @@
+#define MALFUNCTION_TEMPORARY 1
+#define MALFUNCTION_PERMANENT 2
+
+/obj/item/implant/aggression
+ name = "aggression implant"
+ desc = "An implant that microdoses its user with chemicals that induce anger."
+ icon_state = "implant_chem" //Temporary
+ implant_icon = "chem" //Ditto
+ implant_color = "#eba7eb" //Ditto
+ default_action_type = null
+
+/obj/item/implant/aggression/get_data()
+ . = {"
+ Implant Specifications:
+ Name: Aggression Implant
+ Life: N/A.
+ Important Notes: Users injected with this device get increasingly angry to a breaking point. Users tend to expire before the implant does.
+
+ Implant Details:
+ Function: Contains a small pod of nanobots that manipulate the host's mental functions.
+ Integrity: Implant will last so long as the nanobots are inside the bloodstream."}
+
+/obj/item/implant/aggression/implanted(mob/M)
+ if(!istype(M, /mob/living/carbon/human))
+ return FALSE
+
+ var/mob/living/carbon/human/H = M
+
+ for(var/obj/item/implant/mindshield/I in H)
+ if(I.implanted)
+ to_chat(H, SPAN_DANGER("Rage surges through your body, but the nanobots from your mind shield implant stop it soon after it starts!"))
+ return TRUE
+
+ var/datum/antagonist/antag_data = get_antag_data(H.mind.special_role)
+ if(antag_data?.flags & ANTAG_IMPLANT_IMMUNE)
+ H.visible_message("[H] seems to resist the implant!", "You feel rage overtake your body, but you manage to fend it off by sheer will!")
+ log_and_message_admins("[key_name(H)] was implanted by an aggression implant, but was not affected.", H)
+ else if(antag_data?.id == MODE_LOYALIST)
+ clear_antag_roles(H.mind, 1)
+ to_chat(H, SPAN_DANGER("You feel a surge of rage override your loyalty!"))
+ log_and_message_admins("[key_name(H)] was implanted by an aggression implant, clearing their loyalist status!", H)
+ else
+ to_chat(H, SPAN_DANGER("You feel a surge of rage course through your body and very soul!"))
+ log_and_message_admins("[key_name(H)] was implanted by an aggression implant!", H)
+ return TRUE
+
+/obj/item/implant/aggression/emp_act(severity)
+ if(malfunction)
+ return
+ malfunction = MALFUNCTION_TEMPORARY
+
+ activate("emp")
+ if(severity == 1)
+ if(prob(50))
+ meltdown()
+ else if(prob(50))
+ malfunction = MALFUNCTION_PERMANENT
+ return
+ spawn(20)
+ malfunction--
+
+#undef MALFUNCTION_TEMPORARY
+#undef MALFUNCTION_PERMANENT
+
+/obj/item/implantcase/aggression
+ name = "glass case - 'aggression'"
+ imp = /obj/item/implant/aggression
diff --git a/code/game/objects/items/weapons/implants/implants/anti-augment.dm b/code/game/objects/items/weapons/implants/implants/anti-augment.dm
new file mode 100644
index 00000000000..9267f9f9b07
--- /dev/null
+++ b/code/game/objects/items/weapons/implants/implants/anti-augment.dm
@@ -0,0 +1,44 @@
+/obj/item/implant/anti_augment
+ name = "augmentation disrupter implant"
+ desc = "An implant that emits signals able to disrupt the use of commonly used augments."
+ icon_state = "implant_excel" //Temporary
+ implant_icon = "excel" //Ditto
+ implant_color = "#ffd079" //Ditto
+ default_action_type = null
+ known = TRUE
+
+/obj/item/implant/anti_augment/get_data()
+ . = {"
+Implant Specifications:
+Name: Hephaestus Industries HP-152 Augmentation Disrupter Implant
+Life: Three Months.
+Important Notes: Emits a signal able to block most augments from functioning.
+
+Implant Details:
+Function: Emits a short radio wave that will block most augments.
+Special Features: Will stop the host from using any augment they might have.
+Integrity: Implant will last so long as it inside the host."}
+
+/obj/item/implant/anti_augment/isLegal()
+ return TRUE
+
+/obj/item/implant/anti_augment/emp_act(severity)
+ switch(severity)
+ if(1.0)
+ if (prob(75))
+ qdel(src)
+ if(2.0)
+ if (prob(50))
+ qdel(src)
+ if(3.0)
+ if (prob(25))
+ qdel(src)
+ return
+
+/obj/item/implantcase/anti_augment
+ name = "glass case - 'augmentation disrupter'"
+ imp = /obj/item/implant/anti_augment
+
+/obj/item/implanter/anti_augment
+ name = "implanter-augmentation disrupter"
+ imp = /obj/item/implant/anti_augment
diff --git a/code/game/objects/items/weapons/implants/implants/chem.dm b/code/game/objects/items/weapons/implants/implants/chem.dm
new file mode 100644
index 00000000000..9281e1289f1
--- /dev/null
+++ b/code/game/objects/items/weapons/implants/implants/chem.dm
@@ -0,0 +1,84 @@
+#define MALFUNCTION_TEMPORARY 1
+
+/obj/item/implant/chem
+ name = "chemical implant"
+ desc = "Injects things."
+ icon_state = "implant_chem"
+ implant_icon = "chem"
+ implant_color = "#eba7eb"
+ origin_tech = list(TECH_MATERIAL = 2, TECH_BIO = 3)
+ default_action_type = /datum/action/item_action/hands_free/activate/implant/chemical
+ action_button_name = "Dispense Reagents from Chemical Implant"
+ known = TRUE
+
+/obj/item/implant/chem/get_data()
+ . = {"
+Implant Specifications:
+Name: Ingkom ZV-02 Prisoner Management Implant
+Life: Deactivates upon death but remains within the body.
+Important Notes: Due to the system functioning off of nutrients in the implanted subject's body, the subject
+will suffer from an increased appetite.
+
+Implant Details:
+Function: Contains a small capsule that can contain various chemicals. Upon receiving a specially encoded signal
+the implant releases the chemicals directly into the blood stream.
+Special Features:
+Micro-Capsule- Can be loaded with any sort of chemical agent via the common syringe and can hold 50 units.
+Can only be loaded while still in its original case.
+Integrity: Implant will last so long as the subject is alive. However, if the subject suffers from malnutrition,
+the implant may become unstable and either pre-maturely inject the subject or simply break."}
+
+/obj/item/implant/chem/New()
+ ..()
+ var/datum/reagents/R = new/datum/reagents(50)
+ reagents = R
+ R.my_atom = src
+
+/obj/item/implant/chem/trigger(emote, source as mob)
+ if(emote == "deathgasp")
+ src.activate(src.reagents.total_volume)
+ return
+
+/obj/item/implant/chem/activate(cause)
+ if((malfunction) || (!iscarbon(imp_in)))
+ return 0
+ if(!cause)
+ cause = rand(1, 25)
+ var/mob/living/carbon/R = imp_in
+ src.reagents.trans_to_mob(R, cause, CHEM_BLOOD)
+ to_chat(R, SPAN_HEAR("You hear a faint *beep*."))
+ if(!reagents.total_volume)
+ to_chat(R, SPAN_WARNING("You hear a faint *click*."))
+
+/obj/item/implant/chem/attackby(obj/item/I, mob/user)
+ if(istype(I, /obj/item/reagent_containers/syringe))
+ if(reagents.total_volume >= reagents.maximum_volume)
+ to_chat(user, SPAN_WARNING("\The [src] is full."))
+ else
+ if(do_after(user, 0.5 SECONDS, src))
+ I.reagents.trans_to_obj(src, 5)
+ to_chat(user, SPAN_NOTICE("You inject 5 units of the solution. The syringe now contains [I.reagents.total_volume] units."))
+ else
+ ..()
+
+/obj/item/implant/chem/emp_act(severity)
+ if (malfunction)
+ return
+ malfunction = MALFUNCTION_TEMPORARY
+
+ switch(severity)
+ if(1)
+ if(prob(60))
+ activate(20)
+ if(2)
+ if(prob(30))
+ activate(5)
+
+ spawn(20)
+ malfunction--
+
+#undef MALFUNCTION_TEMPORARY
+
+/obj/item/implantcase/chem
+ name = "glass case - 'chem'"
+ imp = /obj/item/implant/chem
diff --git a/code/game/objects/items/weapons/implants/implantcircuits.dm b/code/game/objects/items/weapons/implants/implants/circuit.dm
similarity index 96%
rename from code/game/objects/items/weapons/implants/implantcircuits.dm
rename to code/game/objects/items/weapons/implants/implants/circuit.dm
index 6231c27149a..09c2a77c20b 100644
--- a/code/game/objects/items/weapons/implants/implantcircuits.dm
+++ b/code/game/objects/items/weapons/implants/implants/circuit.dm
@@ -3,9 +3,10 @@
desc = "It's a case, for building very tiny electronics with."
icon = 'icons/obj/assemblies/electronic_setups.dmi'
icon_state = "setup_implant"
+ known = TRUE
var/obj/item/device/electronic_assembly/implant/IC = null
-/obj/item/implant/integrated_circuit/islegal()
+/obj/item/implant/integrated_circuit/isLegal()
return TRUE
/obj/item/implant/integrated_circuit/Initialize()
diff --git a/code/game/objects/items/weapons/implants/implants/compressed_matter.dm b/code/game/objects/items/weapons/implants/implants/compressed_matter.dm
new file mode 100644
index 00000000000..674d4872853
--- /dev/null
+++ b/code/game/objects/items/weapons/implants/implants/compressed_matter.dm
@@ -0,0 +1,69 @@
+/obj/item/implant/compressed //TODO: This code is awful, and this implant is difficult to use. Port atom storage, and make the implant its own storage item
+ name = "compressed matter implant"
+ desc = "Based on compressed matter technology, can store a single item."
+ icon_state = "implant_storage"
+ implant_icon = "storage"
+ implant_color = "#143464"
+ origin_tech = list(TECH_MATERIAL = 4, TECH_BIO = 2, TECH_ILLEGAL = 2)
+ default_action_type = /datum/action/item_action/hands_free/activate/implant/compressed
+ action_button_name = "Retrieve Item from Compressed Implant"
+ hidden = TRUE
+ var/obj/item/scanned = null
+
+/obj/item/implant/compressed/attackby(var/obj/item/T, mob/user)
+ if(T.isscrewdriver())
+ if(!scanned)
+ to_chat(user, SPAN_NOTICE("There is nothing to remove from the implant."))
+ else
+ to_chat(user, SPAN_NOTICE("You remove \the [scanned] from the implant."))
+ user.put_in_hands(scanned)
+ scanned = null
+ if(istype(T, /obj/item/implanter))
+ var/obj/item/implanter/implanter = T
+ if(implanter.imp)
+ to_chat(user, SPAN_NOTICE("\The [implanter] already has an implant loaded."))
+ return
+ user.drop_from_inventory(src)
+ forceMove(implanter)
+ implanter.imp = src
+ implanter.update_icon()
+ else
+ ..()
+
+/obj/item/implant/compressed/get_data()
+ . = {"
+Implant Specifications:
+Name: NT-06 Covert Insertion Implant
+Life: Up to 6 months.
+Important Notes: Uses a localized pocket of bluespace to store an item, that cannot be detected from most external sources.
+
+Implant Details:
+Function: Can store one item, that can be retrieved at will.
+Special Features:
+Neuro-Scan- Analyzes certain shadow signals in the nervous system
+Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."}
+
+/obj/item/implant/compressed/trigger(emote, mob/source as mob)
+ if (src.scanned == null)
+ return FALSE
+
+ to_chat(source, SPAN_NOTICE("The air glows as \the [src.scanned.name] uncompresses."))
+ activate()
+
+/obj/item/implant/compressed/activate()
+ var/turf/t = get_turf(src)
+ if (imp_in)
+ imp_in.put_in_hands(scanned)
+ else
+ scanned.forceMove(t)
+ qdel(src)
+
+/obj/item/implant/compressed/implanted(mob/source as mob)
+ return TRUE
+
+/obj/item/implant/compressed/isLegal()
+ return FALSE
+
+/obj/item/implanter/compressed
+ name = "implanter (C)"
+ imp = /obj/item/implant/compressed
diff --git a/code/game/objects/items/weapons/implants/implants/death_alarm.dm b/code/game/objects/items/weapons/implants/implants/death_alarm.dm
new file mode 100644
index 00000000000..75733b37ff4
--- /dev/null
+++ b/code/game/objects/items/weapons/implants/implants/death_alarm.dm
@@ -0,0 +1,83 @@
+#define MALFUNCTION_TEMPORARY 1
+#define MALFUNCTION_PERMANENT 2
+
+/obj/item/implant/death_alarm
+ name = "death alarm implant"
+ desc = "An alarm which monitors host vital signs and transmits a radio message upon death."
+ icon_state = "implant_deathalarm"
+ implant_icon = "deathalarm"
+ implant_color = "#9cdb43"
+ origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 3, TECH_DATA = 2)
+ default_action_type = null
+ known = TRUE
+ var/mobname = "Will Robinson"
+
+/obj/item/implant/death_alarm/get_data()
+ . = {"
+Implant Specifications:
+Name: Idris Incorporated ID-15 \"Profit Margin\" Class Sapient Lifesign Sensor
+Life: Activates upon death.
+Important Notes: Alerts crew to crewmember death.
+
+Implant Details:
+Function: Contains a compact radio signaler that triggers when the host's lifesigns cease.
+Special Features: Alerts crew to crewmember death.
+Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."}
+
+/obj/item/implant/death_alarm/process()
+ if (!implanted)
+ return
+ var/mob/M = imp_in
+
+ if(QDELETED(M)) // If the mob got gibbed
+ M = null
+ activate(null)
+ else if(M.stat == DEAD)
+ activate("death")
+
+/obj/item/implant/death_alarm/activate(cause = "emp")
+ if (malfunction)
+ return
+ var/mob/M = imp_in
+ var/area/A = get_area(M)
+ var/location = A.name
+ if(cause == "emp" && prob(50))
+ location = pick(teleportbeacons)
+ if(!A.requires_power) // We assume areas that don't use power are special zones
+ var/area/default = world.area
+ location = initial(default.name)
+ var/death_message = "[mobname] has died in [location]!"
+ if(!cause)
+ death_message = "[mobname] has died-zzzzt in-in-in..."
+ STOP_PROCESSING(SSprocessing, src)
+
+ for(var/channel in list("Security", "Medical", "Command"))
+ global_announcer.autosay(death_message, "[mobname]'s Death Alarm", channel)
+
+/obj/item/implant/death_alarm/emp_act(severity) //for some reason alarms stop going off in case they are emp'd, even without this
+ if (malfunction) //so I'm just going to add a meltdown chance here
+ return
+ malfunction = MALFUNCTION_TEMPORARY
+
+ activate("emp") //let's shout that this dude is dead
+ if(severity == 1)
+ if(prob(40)) //small chance of obvious meltdown
+ meltdown()
+ else if (prob(60)) //but more likely it will just quietly die
+ malfunction = MALFUNCTION_PERMANENT
+ STOP_PROCESSING(SSprocessing, src)
+
+ spawn(20)
+ malfunction--
+
+/obj/item/implant/death_alarm/implanted(mob/source as mob)
+ mobname = source.real_name
+ START_PROCESSING(SSprocessing, src)
+ return TRUE
+
+#undef MALFUNCTION_TEMPORARY
+#undef MALFUNCTION_PERMANENT
+
+/obj/item/implantcase/death_alarm
+ name = "glass case - 'death alarm'"
+ imp = /obj/item/implant/death_alarm
diff --git a/code/game/objects/items/weapons/implants/implants/emp.dm b/code/game/objects/items/weapons/implants/implants/emp.dm
new file mode 100644
index 00000000000..9d34bf79c79
--- /dev/null
+++ b/code/game/objects/items/weapons/implants/implants/emp.dm
@@ -0,0 +1,23 @@
+/obj/item/implant/emp
+ name = "\improper EMP implant"
+ desc = "Triggers an EMP."
+ icon_state = "implant_emp"
+ implant_icon = "emp"
+ implant_color = "#249fde"
+ origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 2, TECH_ILLEGAL = 2)
+ default_action_type = /datum/action/item_action/hands_free/activate/implant/emp
+ action_button_name = "Activate EMP Implant"
+ var/uses = 3
+
+/obj/item/implant/emp/activate()
+ if (malfunction || !imp_in)
+ return
+ if (uses < 1)
+ to_chat(imp_in, SPAN_WARNING("\The [src] gives a faint beep inside your head, indicating that it's out of uses!"))
+ return
+ uses--
+ empulse(imp_in, 3, 5)
+
+/obj/item/implantcase/emp
+ name = "implant case - 'EMP'"
+ imp = /obj/item/implant/emp
diff --git a/code/game/objects/items/weapons/implants/implants/explosive.dm b/code/game/objects/items/weapons/implants/implants/explosive.dm
new file mode 100644
index 00000000000..a0356ebefc0
--- /dev/null
+++ b/code/game/objects/items/weapons/implants/implants/explosive.dm
@@ -0,0 +1,320 @@
+#define MALFUNCTION_TEMPORARY 1
+#define MALFUNCTION_PERMANENT 2
+
+//BS12 Explosive
+/obj/item/implant/explosive
+ name = "explosive implant"
+ desc = "A military grade micro bio-explosive. Highly dangerous."
+ icon_state = "implant_explosive"
+ implant_icon = "explosive"
+ implant_color = "#e46b5d"
+ origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 2, TECH_ILLEGAL = 3)
+ default_action_type = /datum/action/item_action/hands_free/activate/implant/explosive
+ action_button_name = "Activate Explosive Implant"
+ hidden = TRUE
+ var/elevel = "Localized Limb"
+ var/explodes_on_death = FALSE
+ var/phrase
+ var/code = 13
+ var/frequency = 1443
+ var/datum/radio_frequency/radio_connection
+ var/list/possible_explosions = list("Localized Limb", "Destroy Body")
+ var/warning_message = "Tampering detected. Tampering detected."
+
+/obj/item/implant/explosive/Initialize()
+ . = ..()
+ setFrequency(frequency)
+
+/obj/item/implant/explosive/get_data()
+ . = {"
+Implant Specifications:
+Name: Kumar Arms ZX-01 \"Obscuration\" Class Implant
+Life: Activates upon codephrase.
+Important Notes: Explodes
+
+Implant Details:
+Function: Contains a compact, electrically detonated explosive that detonates upon receiving a specially encoded signal or upon host death.
+Special Features: Explodes. Explosion severity can be altered.
+Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."}
+ if(!malfunction)
+ . += {"
+
Explosion yield mode:
+ [elevel ? elevel : "NONE SET"]
+ Activation phrase:
+ [phrase ? phrase : "NONE SET"]
+ Frequency:
+ -
+ -
+ [format_frequency(src.frequency)]
+ +
+ +
+ Code:
+ -
+ -
+ [src.code]
+ +
+ +
+ Tampering warning message:
+ This will be broadcasted on radio if the implant is exposed during surgery.
+ [warning_message ? warning_message : "NONE SET"]
+ "}
+
+/obj/item/implant/explosive/Topic(href, href_list)
+ ..()
+ if(href_list["freq"])
+ var/new_frequency = frequency + text2num(href_list["freq"])
+ new_frequency = sanitize_frequency(new_frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ)
+ setFrequency(new_frequency)
+ interact(usr)
+ if(href_list["code"])
+ var/adj = text2num(href_list["code"])
+ if(!adj)
+ code = input("Set radio activation code","Radio activation") as num
+ else
+ code += adj
+ code = clamp(code,1,100)
+ interact(usr)
+ if(href_list["mode"])
+ var/mod = input("Set explosion mode", "Explosion mode") as null|anything in possible_explosions
+ if(mod)
+ elevel = mod
+ interact(usr)
+ if(href_list["msg"])
+ var/msg = input("Set tampering message, or leave blank for no broadcasting.", "Anti-tampering", warning_message) as text|null
+ if(msg)
+ warning_message = msg
+ interact(usr)
+ if(href_list["phrase"])
+ var/talk = input("Set activation phrase", "Audio activation", phrase) as text|null
+ if(talk)
+ phrase = sanitizePhrase(talk)
+ interact(usr)
+
+/obj/item/implant/explosive/receive_signal(datum/signal/signal)
+ if(signal && signal.encryption == code)
+ activate()
+
+/obj/item/implant/explosive/proc/setFrequency(new_frequency)
+ if(!frequency)
+ return
+ SSradio.remove_object(src, frequency)
+ frequency = new_frequency
+ radio_connection = SSradio.add_object(src, frequency, RADIO_CHAT)
+
+/obj/item/implant/explosive/hear_talk(mob/M, msg)
+ hear(msg)
+
+/obj/item/implant/explosive/hear(var/msg)
+ if(!phrase)
+ return
+ if(findtext(sanitizePhrase(msg),phrase))
+ activate()
+ qdel(src)
+
+/obj/item/implant/explosive/exposed()
+ if(warning_message)
+ global_announcer.autosay(warning_message, "Anti-Tampering System")
+
+/obj/item/implant/explosive/proc/sanitizePhrase(phrase)
+ var/list/replacechars = list("'" = "", "\"" = "", ">" = "", "<" = "", "(" = "", ")" = "")
+ return replace_characters(phrase, replacechars)
+
+/obj/item/implant/explosive/activate()
+ if(malfunction)
+ return
+
+ if(!imp_in)
+ small_countdown()
+ return
+
+ message_admins("Explosive implant triggered in [imp_in] ([imp_in.key]). (JMP) ")
+ log_game("Explosive implant triggered in [imp_in] ([imp_in.key]).")
+ if(!elevel)
+ elevel = "Localized Limb"
+ switch(elevel)
+ if("Localized Limb")
+ if(part)
+ small_countdown()
+ return
+ if("Destroy Body")
+ explosion(get_turf(imp_in), -1, 0, 2, 6)
+ if(ismob(imp_in))
+ imp_in.gib()
+ if("Full Explosion")
+ explosion_spread(get_turf(imp_in), rand(8,13))
+ if(ismob(imp_in))
+ imp_in.gib()
+
+ var/turf/F = get_turf(imp_in)
+ if(F)
+ F.hotspot_expose(3500,125)
+ qdel(src)
+
+/obj/item/implant/explosive/proc/small_countdown()
+ if(!imp_in)
+ audible_message(SPAN_WARNING("[src] beeps ominously!"))
+ if(ishuman(imp_in))
+ var/message = "Something beeps inside of [imp_in][part ? "'s [part.name]" : ""]..." //for some reason SPAN_X and span() both hate having this in-line
+ imp_in.audible_message(SPAN_WARNING(message))
+ else if(ismob(imp_in))
+ imp_in.audible_message(SPAN_WARNING("Something beeps inside of [imp_in]..."))
+ playsound(loc, 'sound/items/countdown.ogg', 75, 1, -3)
+ addtimer(CALLBACK(src, PROC_REF(small_boom)), 25)
+
+/obj/item/implant/explosive/proc/small_boom()
+ if(!imp_in)
+ explosion(get_turf(src), -1, 0, 2, 4)
+ if(ishuman(imp_in) && part)
+ //No tearing off these parts since it's pretty much killing. Mangle them.
+ if(part.vital && !istype(part, /obj/item/organ/external/head)) //Head explodes
+ part.createwound(BRUISE, 70)
+ part.add_pain(50)
+ imp_in.visible_message(SPAN_WARNING("\The [imp_in]'s [part.name] bursts open with a horrible ripping noise!"),
+ SPAN_DANGER("Your [part.name] bursts open with a horrible ripping noise!"),
+ SPAN_WARNING("You hear a horrible ripping noise."))
+ else
+ part.droplimb(0,DROPLIMB_BLUNT)
+ playsound(get_turf(imp_in), BP_IS_ROBOTIC(part) ? 'sound/effects/meteorimpact.ogg' : 'sound/effects/splat.ogg')
+ else if(ismob(imp_in))
+ var/mob/M = imp_in
+ M.gib() //Simple mobs just get got
+ qdel(src)
+
+/proc/explosion_spread(turf/epicenter, power, adminlog = 1, z_transfer = UP|DOWN)
+ var/datum/explosiondata/data = new
+ data.epicenter = epicenter
+ data.rec_pow = power
+ data.spreading = TRUE
+ data.adminlog = adminlog
+ data.z_transfer = z_transfer
+ SSexplosives.queue(data)
+
+/obj/item/implant/explosive/implanted(mob/source, mob/user)
+ var/memo = "\The [src] in [source] can be activated by saying something containing the phrase ''[phrase]'', say [phrase] to attempt to activate. It can also be triggered with a radio signal on frequency [format_frequency(src.frequency)] with code [code]."
+ if(user.mind)
+ user.mind.store_memory(memo, 0, 0)
+ to_chat(usr, memo)
+ return TRUE
+
+/obj/item/implant/explosive/emp_act(severity)
+ if(malfunction)
+ return
+ malfunction = MALFUNCTION_TEMPORARY
+ switch (severity)
+ if(2.0) //Weak EMP will make implant tear limbs off.
+ if(prob(50))
+ small_countdown()
+ if(1.0) //strong EMP will melt implant either making it go off, or disarming it
+ if(prob(70))
+ if(prob(50))
+ small_countdown()
+ else
+ if(prob(50))
+ activate() //50% chance of bye bye
+ else
+ meltdown() //50% chance of implant disarming
+ addtimer(CALLBACK(src, PROC_REF(self_correct)), 20)
+
+/obj/item/implant/explosive/proc/self_correct()
+ malfunction--
+
+/obj/item/implant/explosive/isLegal()
+ return FALSE
+
+/obj/item/implant/explosive/New()
+ ..()
+ become_hearing_sensitive(ROUNDSTART_TRAIT)
+
+/obj/item/implant/explosive/Destroy()
+ return ..()
+
+/obj/item/implant/explosive/full
+ possible_explosions = list("Localized Limb", "Destroy Body", "Full Explosion")
+
+/obj/item/implant/explosive/deadman
+ name = "deadman explosive"
+ desc = "A military grade micro bio-explosive that detonates upon death."
+ icon_state = "implant_evil"
+
+/obj/item/implant/explosive/deadman/get_data()
+ . = {"
+Implant Specifications:
+Name: Kumar Arms ZX-01a \"Obscuration\" Class Implant
+Life: Activates upon death.
+Important Notes: Explodes
+
+Implant Details:
+Function: Contains a compact, electrically detonated explosive that detonates upon receiving a specially encoded signal or upon host death.
+Special Features: Explodes
+Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."}
+
+/obj/item/implant/explosive/deadman/attack_self(mob/user)
+ return
+
+/obj/item/implant/explosive/deadman/hear(var/msg)
+ return
+
+/obj/item/implant/explosive/deadman/process()
+ if(malfunction)
+ STOP_PROCESSING(SSprocessing, src)
+ return
+ if (!implanted)
+ return
+ var/mob/M = imp_in
+
+ if(M.stat == DEAD)
+ activate()
+
+/obj/item/implant/explosive/deadman/activate(var/cause)
+ small_countdown(src)
+ STOP_PROCESSING(SSprocessing, src)
+
+/obj/item/implant/explosive/deadman/small_boom()
+ if(imp_in)
+ explosion(get_turf(src), -1, 0, 1, 6)
+ imp_in.gib()
+ qdel(src)
+
+/obj/item/implant/explosive/deadman/implanted(mob/source)
+ START_PROCESSING(SSprocessing, src)
+ return TRUE
+
+/obj/item/implant/explosive/deadman/emp_act(severity)
+ if(malfunction)
+ return
+ malfunction = MALFUNCTION_TEMPORARY
+ switch (severity)
+ if(3.0)
+ if(prob(1))
+ small_countdown()
+ else if(prob(5))
+ meltdown()
+ if(2.0)
+ if(prob(5))
+ small_countdown()
+ else if (prob(10))
+ meltdown()
+ if(1.0)
+ if(prob(10))
+ small_countdown()
+ else if (prob(30))
+ meltdown()
+
+#undef MALFUNCTION_TEMPORARY
+#undef MALFUNCTION_PERMANENT
+
+/obj/item/implantcase/explosive
+ name = "implant case - 'explosive'"
+ imp = /obj/item/implant/explosive
+
+/obj/item/implantcase/explosive/deadman
+ name = "glass case - 'deadman'"
+ imp = /obj/item/implant/explosive/deadman
+
+/obj/item/implanter/explosive
+ name = "implanter (E)"
+ imp = /obj/item/implant/explosive
+
+/obj/item/implanter/explosive/deadman
+ name = "implanter (D)"
+ imp = /obj/item/implant/explosive/deadman
diff --git a/code/game/objects/items/weapons/implants/implants/freedom.dm b/code/game/objects/items/weapons/implants/implants/freedom.dm
new file mode 100644
index 00000000000..7fd50279779
--- /dev/null
+++ b/code/game/objects/items/weapons/implants/implants/freedom.dm
@@ -0,0 +1,77 @@
+//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
+
+/obj/item/implant/freedom
+ name = "freedom implant"
+ desc = "Use this to escape from those evil Red Shirts."
+ icon_state = "implant_freedom"
+ implant_icon = "freedom"
+ implant_color = "#88f2e0"
+ origin_tech = list(TECH_MATERIAL = 1, TECH_ILLEGAL = 2, TECH_BIO = 3)
+ default_action_type = /datum/action/item_action/hands_free/activate/implant/freedom
+ action_button_name = "Activate Freedom Implant"
+ hidden = TRUE
+ var/uses = 1
+
+/obj/item/implant/freedom/New()
+ uses = rand(1, 5)
+ ..()
+
+/obj/item/implant/freedom/activate(cause)
+ if(malfunction || !imp_in)
+ return
+ if(uses < 1)
+ to_chat(imp_in, SPAN_WARNING("\The [src] gives a faint beep inside your [part], indicating that it's out of uses!"))
+ return
+ uses--
+ to_chat(imp_in, SPAN_HEAR("You feel a faint click."))
+ if(iscarbon(imp_in))
+ var/mob/living/carbon/C_imp_in = imp_in
+ if(C_imp_in.handcuffed)
+ var/obj/item/W = C_imp_in.handcuffed
+ C_imp_in.handcuffed = null
+ if(C_imp_in.buckled_to && C_imp_in.buckled_to.buckle_require_restraints)
+ C_imp_in.buckled_to.unbuckle()
+ C_imp_in.update_inv_handcuffed()
+ if(C_imp_in.client)
+ C_imp_in.client.screen -= W
+ if(W)
+ W.forceMove(C_imp_in.loc)
+ dropped(C_imp_in)
+ if (W)
+ W.layer = initial(W.layer)
+ if(C_imp_in.legcuffed)
+ var/obj/item/W = C_imp_in.legcuffed
+ C_imp_in.legcuffed = null
+ C_imp_in.update_inv_legcuffed()
+ if(C_imp_in.client)
+ C_imp_in.client.screen -= W
+ if(W)
+ W.forceMove(C_imp_in.loc)
+ dropped(C_imp_in)
+ if(W)
+ W.layer = initial(W.layer)
+
+/obj/item/implant/freedom/get_data()
+ var/dat = {"
+Implant Specifications:
+Name: Freedom Beacon
+Life: optimum 5 uses
+Important Notes: Illegal
+
+Implant Details:
+Function: Transmits a specialized cluster of signals to override handcuff locking
+mechanisms
+Special Features:
+Neuro-Scan- Analyzes certain shadow signals in the nervous system
+Integrity: The battery is extremely weak and commonly after injection its
+life can drive down to only 1 use.
+No Implant Specifics"}
+ return dat
+
+/obj/item/implantcase/freedom
+ name = "glass case - 'freedom'"
+ imp = /obj/item/implant/freedom
+
+/obj/item/implanter/freedom
+ name = "implanter (F)"
+ imp = /obj/item/implant/freedom
diff --git a/code/game/objects/items/weapons/implants/implants/health_tracker.dm b/code/game/objects/items/weapons/implants/implants/health_tracker.dm
new file mode 100644
index 00000000000..53cfb6ea8fc
--- /dev/null
+++ b/code/game/objects/items/weapons/implants/implants/health_tracker.dm
@@ -0,0 +1,22 @@
+//Health Tracker Implant
+/obj/item/implant/health
+ name = "health implant"
+ icon_state = "implant_health"
+ implant_icon = "deathalarm" //This is intentionally the same as the death alarm
+ implant_color = "#9cdb43" //This is intentionally the same as the death alarm
+ var/healthstring = ""
+
+/obj/item/implant/health/proc/sensehealth()
+ if(!implanted)
+ return "ERROR"
+ else
+ if(isliving(implanted))
+ var/mob/living/L = implanted
+ healthstring = "[round(L.getOxyLoss())] - [round(L.getFireLoss())] - [round(L.getToxLoss())] - [round(L.getBruteLoss())]"
+ if(!healthstring)
+ healthstring = "ERROR"
+ return healthstring
+
+/obj/item/implantcase/health
+ name = "glass case - 'health'"
+ imp = /obj/item/implant/health
diff --git a/code/game/objects/items/weapons/implants/implants/loyalty.dm b/code/game/objects/items/weapons/implants/implants/loyalty.dm
new file mode 100644
index 00000000000..2052c6e2f98
--- /dev/null
+++ b/code/game/objects/items/weapons/implants/implants/loyalty.dm
@@ -0,0 +1,104 @@
+/obj/item/implant/mindshield/loyalty
+ name = "loyalty implant"
+ desc = "A controversial device, these were replaced with mindshield implants by the corporations of the spur. However, they still find usage with several entities across the spur."
+ ///The entity that the implantee should be loyal to
+ var/loyal_entity
+ ///Whether this implant will override mindshield implants. These are supposed to be older versions of mindshields, so only specially modified versions should do so.
+ var/mindshield_override = FALSE
+
+/obj/item/implant/mindshield/loyalty/get_data()
+ . = {"
+Implant Specifications:
+Name: Solarian Corporate Authority NT-02 Employee Management Implant Mk.I
+Life: Ten years.
+Important Notes: Personnel injected with this device tend to be much more loyal to the entity provided.
+
+Implant Details:
+Function: Contains a small pod of nanobots that manipulate the host's mental functions, to ensure no harmful thoughts are present against an entity.
+Special Features: Will prevent and cure most forms of brainwashing.
+Integrity: Implant will last so long as the nanobots are inside the bloodstream."
+Loyal entity:
+This is the entity that the implantee will align their thoughts to benefit.
+[loyal_entity ? loyal_entity : "NONE SET"]
+"}
+
+/obj/item/implant/mindshield/loyalty/Topic(href, href_list)
+ ..()
+ if(href_list["loyal"])
+ var/entity = input("Set loyalty target.", "Loyalty", loyal_entity) as text|null
+ if(entity)
+ loyal_entity = entity
+ interact(usr)
+
+/obj/item/implant/mindshield/loyalty/implanted(mob/M)
+ if(!istype(M, /mob/living/carbon/human))
+ return FALSE
+
+ var/mob/living/carbon/human/H = M
+
+ for(var/obj/item/implant/mindshield/I in H)
+ if(I.implanted && !mindshield_override)
+ to_chat(H, SPAN_DANGER("You almost feel your loyalties shifting, but nanobots from your mindshield implant stop it soon after it starts!"))
+ meltdown()
+ return FALSE
+ else if(I.implanted && mindshield_override)
+ to_chat(H, SPAN_DANGER("You hear a buzzing sound as your mindshield implant struggles to defend against the new implant."))
+ I.meltdown()
+
+ to_chat(H, SPAN_GOOD("You feel a sudden surge of loyalty to \the [loyal_entity]!"))
+ log_and_message_admins("[key_name(H)] was implanted by an loyalty implant, set to [loyal_entity]!", H)
+ return TRUE
+
+/obj/item/implant/mindshield/loyalty/sol
+ name = "loyalty implant - Sol Alliance"
+ desc = "A device used by the Sol Alliance, to ensure loyalty to the only human government in the spur."
+ loyal_entity = "\improper Sol Alliance"
+
+/obj/item/implant/mindshield/loyalty/nralakk
+ name = "loyalty implant - Nralakk Federation"
+ desc = "A device used by the Nralakk Federation, to ensure loyalty to its ideals and to the best caretaker of the skrellian people."
+ loyal_entity = "\improper Nralakk Federation"
+
+/obj/item/implant/mindshield/loyalty/scc
+ name = "loyalty implant - Stellar Corporate Conglomerate"
+ desc = "A device that is allegedly used by the Stellar Corporate Conglomerate, which is allegedly used to enforce loyalty to the corporate agenda for its emergency response teams and high-ranking officers."
+ loyal_entity = "\improper Stellar Corporate Conglomerate"
+
+/obj/item/implant/mindshield/loyalty/nt
+ name = "loyalty implant - NanoTrasen"
+ desc = "A device that is allegedly used by NanoTrasen, which is allegedly used to enforce loyalty to the corporate agenda for its emergency response teams and high-ranking officers."
+ loyal_entity = "NanoTrasen"
+ //They made them originally, they would know how to override them.
+ mindshield_override = TRUE
+
+/obj/item/implantcase/loyalty
+ name = "glass case - 'loyalty'"
+ imp = /obj/item/implant/mindshield/loyalty
+
+/obj/item/implanter/loyalty
+ name = "implanter-loyalty"
+ imp = /obj/item/implant/mindshield/loyalty
+
+/obj/item/implantcase/loyalty/sol
+ name = "glass case - 'loyalty - Sol Alliance'"
+ imp = /obj/item/implant/mindshield/loyalty/sol
+
+/obj/item/implanter/loyalty/sol
+ name = "implanter-loyalty - Sol Alliance"
+ imp = /obj/item/implant/mindshield/loyalty/sol
+
+/obj/item/implantcase/loyalty/nralakk
+ name = "glass case - 'loyalty - Nralakk Federation'"
+ imp = /obj/item/implant/mindshield/loyalty/nralakk
+
+/obj/item/implanter/loyalty/nralakk
+ name = "implanter-loyalty - Nralakk Federation"
+ imp = /obj/item/implant/mindshield/loyalty/nralakk
+
+/obj/item/implantcase/loyalty/scc
+ name = "glass case - 'loyalty - Stellar Corporate Conglomerate'"
+ imp = /obj/item/implant/mindshield/loyalty/scc
+
+/obj/item/implanter/loyalty/scc
+ name = "implanter-loyalty - Stellar Corporate Conglomerate"
+ imp = /obj/item/implant/mindshield/loyalty/scc
diff --git a/code/game/objects/items/weapons/implants/implants/mindshield.dm b/code/game/objects/items/weapons/implants/implants/mindshield.dm
new file mode 100644
index 00000000000..e394ed9ee8e
--- /dev/null
+++ b/code/game/objects/items/weapons/implants/implants/mindshield.dm
@@ -0,0 +1,75 @@
+#define MALFUNCTION_TEMPORARY 1
+#define MALFUNCTION_PERMANENT 2
+
+/obj/item/implant/mindshield
+ name = "mind shield implant"
+ desc = "A neurostimulator and autohypnosis device. These replaced older, controversial loyalty implants for the corporations of the spur. When implanted against the amygdala, it ensures the host maintains a consistent personality, preventing outside interference through brainwashing or hypnotic suggestion."
+ icon_state = "implant_excel"
+ implant_icon = "excel"
+ implant_color = "#ffd079"
+ origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 2, TECH_ILLEGAL = 3)
+ default_action_type = null
+ known = TRUE
+
+/obj/item/implant/mindshield/get_data()
+ . = {"
+Implant Specifications:
+Name: NanoTrasen NT-02 Employee Management Implant Mk.II
+Life: Ten years.
+Important Notes: Personnel injected with this device tend to be much more resistant to brain washing and other external influences.
+
+Implant Details:
+Function: Contains a small pod of nanobots that observe the host's mental functions, and will destroy and interfere with common techniques of intrusion.
+Special Features: Will prevent and cure most forms of brainwashing.
+Integrity: Implant will last so long as the nanobots are inside the bloodstream."}
+
+/obj/item/implant/mindshield/implanted(mob/M)
+ to_chat(M, SPAN_SUBTLE("You feel a weird feeling, as the implant's nanobots disperse through your brain."))
+ if(istype(M, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = M
+ for(var/obj/item/implant/mindshield/loyalty/I in H)
+ if(I.implanted && !I.mindshield_override)
+ to_chat(H, SPAN_DANGER("The new mindshield implant activates, destroying your loyalty implant."))
+ I.meltdown()
+ continue
+ else if(I.implanted && I.mindshield_override)
+ to_chat(H, SPAN_DANGER("You hear a buzzing sound as your loyalty implant defends itself against the new implant."))
+ meltdown()
+ return FALSE
+ return TRUE
+
+/obj/item/implant/mindshield/emp_act(severity)
+ if (malfunction)
+ return
+ malfunction = MALFUNCTION_TEMPORARY
+
+ activate("emp")
+ if(severity == 1)
+ if(prob(50))
+ meltdown()
+ else if (prob(50))
+ malfunction = MALFUNCTION_PERMANENT
+ return
+ spawn(20)
+ malfunction--
+
+/obj/item/implant/mindshield/ipc
+ name = "software protection chip"
+ desc = "A dedicated processor core designed to identify and terminate malignant software, ensuring a synthetics protection from outside hacking."
+
+/obj/item/implant/mindshield/ipc/implanted(mob/M)
+ if (!isipc(M))
+ return
+
+ ..()
+
+#undef MALFUNCTION_TEMPORARY
+#undef MALFUNCTION_PERMANENT
+
+/obj/item/implantcase/mindshield
+ name = "glass case - 'mind shield'"
+ imp = /obj/item/implant/mindshield
+
+/obj/item/implanter/mindshield
+ name = "implanter-mindshield"
+ imp = /obj/item/implant/mindshield
diff --git a/code/game/objects/items/weapons/implants/implants/tracking.dm b/code/game/objects/items/weapons/implants/implants/tracking.dm
new file mode 100644
index 00000000000..fe6657a01bd
--- /dev/null
+++ b/code/game/objects/items/weapons/implants/implants/tracking.dm
@@ -0,0 +1,70 @@
+#define MALFUNCTION_TEMPORARY 1
+
+/obj/item/implant/tracking
+ name = "tracking implant"
+ desc = "Track with this."
+ icon_state = "implant_freedom"
+ implant_icon = "freedom"
+ implant_color = "#eadb83"
+ origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 2, TECH_BLUESPACE = 2)
+ default_action_type = null
+ known = TRUE
+ var/id = 1.0
+ var/lifespan_postmortem = 10 MINUTES
+
+/obj/item/implant/tracking/Initialize()
+ var/list/tracking_list = list()
+ for(var/obj/item/implant/tracking/T in implants)
+ tracking_list += T
+ id = length(tracking_list) + 1
+ . = ..()
+
+/obj/item/implant/tracking/process()
+ if(!imp_in)
+ return
+ if(iscarbon(imp_in))
+ var/mob/living/carbon/R = imp_in
+ if(R.chem_effects[CE_NEUROTOXIC])
+ if(prob(5))
+ meltdown()
+
+/obj/item/implant/tracking/get_data()
+ . = {"Implant Specifications:
+Name: Ingkom ZV-01 Tracking Beacon
+Life: 10 minutes after death of host
+Important Notes: None
+
+Implant Details:
+Function: Continuously transmits a low power signal. Useful for tracking subjects.
+Special Features:
+Neuro-Safe- Specialized shell absorbs excess voltages self-destructing the chip if
+a malfunction occurs thereby securing safety of subject. The implant will melt and
+disintegrate into bio-safe elements.
+Integrity: Gradient creates slight risk of being overcharged and frying the
+circuitry. As a result neurotoxins can cause massive damage.
+Implant Specifics:
"}
+
+/obj/item/implant/tracking/isLegal()
+ return TRUE
+
+/obj/item/implant/tracking/emp_act(severity)
+ if (malfunction) //no, dawg, you can't malfunction while you are malfunctioning
+ return
+ malfunction = MALFUNCTION_TEMPORARY
+
+ var/delay = 20
+ switch(severity)
+ if(1)
+ if(prob(60))
+ meltdown()
+ if(2)
+ delay = rand(5*60*10,15*60*10) //from 5 to 15 minutes of free time
+
+ spawn(delay)
+ malfunction--
+
+#undef MALFUNCTION_TEMPORARY
+
+/obj/item/implantcase/tracking
+ name = "glass case - 'tracking'"
+ imp = /obj/item/implant/tracking
diff --git a/code/game/objects/items/weapons/implants/implantuplink.dm b/code/game/objects/items/weapons/implants/implants/uplink.dm
similarity index 86%
rename from code/game/objects/items/weapons/implants/implantuplink.dm
rename to code/game/objects/items/weapons/implants/implants/uplink.dm
index f22f5a62df5..a2ac8925f2a 100644
--- a/code/game/objects/items/weapons/implants/implantuplink.dm
+++ b/code/game/objects/items/weapons/implants/implants/uplink.dm
@@ -1,7 +1,12 @@
/obj/item/implant/uplink
name = "uplink"
desc = "Summon things."
+ icon_state = "implant_uplink"
+ implant_icon = "uplink"
+ implant_color = "#ffd4a3"
var/activation_emote = "chuckle"
+ default_action_type = null
+ hidden = TRUE
/obj/item/implant/uplink/New()
activation_emote = pick("blink", "blink_r", "eyebrow", "chuckle", "twitch", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
@@ -23,3 +28,7 @@
if(hidden_uplink && usr == source) // Let's not have another people activate our uplink
hidden_uplink.check_trigger(source, emote, activation_emote)
return
+
+/obj/item/implanter/uplink
+ name = "implanter (U)"
+ imp = /obj/item/implant/uplink
diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm
index a99c6f56e48..c5ca35588eb 100644
--- a/code/game/objects/items/weapons/storage/boxes.dm
+++ b/code/game/objects/items/weapons/storage/boxes.dm
@@ -530,7 +530,7 @@
name = "death alarm kit"
desc = "Box of stuff used to implant death alarms."
illustration = "implant"
- starts_with = list(/obj/item/implanter = 1, /obj/item/implantcase/death_alarm = 6)
+ starts_with = list(/obj/item/implanter = 1, /obj/item/implantcase/death_alarm = 6, /obj/item/implantpad = 1)
/obj/item/storage/box/condimentbottles
name = "box of condiment bottles"
@@ -1221,3 +1221,4 @@
/obj/item/storage/box/produce/fill()
. = ..()
make_exact_fit()
+
diff --git a/code/game/objects/items/weapons/storage/lockbox.dm b/code/game/objects/items/weapons/storage/lockbox.dm
index 1ceed545796..6addf763f9b 100644
--- a/code/game/objects/items/weapons/storage/lockbox.dm
+++ b/code/game/objects/items/weapons/storage/lockbox.dm
@@ -79,8 +79,8 @@
name = "lockbox of mind shield implants"
req_access = list(access_security)
starts_with = list(
- /obj/item/implantcase/loyalty = 3,
- /obj/item/implanter/loyalty = 1
+ /obj/item/implantcase/mindshield = 3,
+ /obj/item/implanter/mindshield = 1
)
/obj/item/storage/lockbox/anti_augment
diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm
index 629b49efbe6..40f5be5b039 100644
--- a/code/game/objects/items/weapons/storage/uplink_kits.dm
+++ b/code/game/objects/items/weapons/storage/uplink_kits.dm
@@ -6,26 +6,23 @@
/obj/item/storage/box/syndie_kit/imp_freedom
name = "box (F)"
- starts_with = list(/obj/item/implanter/freedom = 1)
-
-/obj/item/storage/box/syndie_kit/imp_freedom/fill()
- ..()
- var/obj/item/implanter/O = new(src)
- O.imp = new /obj/item/implant/freedom(O)
- O.update()
- return
+ starts_with = list(/obj/item/implantpad = 1, /obj/item/implanter = 1, /obj/item/implantcase/freedom = 1)
/obj/item/storage/box/syndie_kit/imp_compress
name = "box (C)"
- starts_with = list(/obj/item/implanter/compressed = 1)
+ starts_with = list(/obj/item/implantpad = 1, /obj/item/implanter/compressed = 1)
/obj/item/storage/box/syndie_kit/imp_explosive
name = "box (E)"
- starts_with = list(/obj/item/implanter = 1, /obj/item/implant/explosive = 1)
+ starts_with = list(/obj/item/implantpad = 1, /obj/item/implanter = 1, /obj/item/implantcase/explosive = 1)
+
+/obj/item/storage/box/syndie_kit/imp_emp
+ name = "box (M)"
+ starts_with = list(/obj/item/implantpad = 1, /obj/item/implanter = 1, /obj/item/implantcase/emp = 1)
/obj/item/storage/box/syndie_kit/imp_deadman
name = "box (D)"
- starts_with = list(/obj/item/implanter = 1, /obj/item/implant/explosive/deadman = 1)
+ starts_with = list(/obj/item/implantpad = 1, /obj/item/implanter = 1, /obj/item/implantcase/explosive/deadman = 1)
/obj/item/storage/box/syndie_kit/imp_uplink
diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm
index 2923b8a5bae..56513894de9 100644
--- a/code/game/objects/items/weapons/teleportation.dm
+++ b/code/game/objects/items/weapons/teleportation.dm
@@ -99,8 +99,8 @@ Frequency:
continue
else
var/mob/M = W.loc
- if (M.stat == 2)
- if (M.timeofdeath + 6000 < world.time)
+ if (M.stat == DEAD)
+ if (M.timeofdeath + W.lifespan_postmortem < world.time)
continue
var/turf/tr = get_turf(W)
diff --git a/code/modules/awaymissions/exile.dm b/code/modules/awaymissions/exile.dm
index fadbc540c23..7db07f94a00 100644
--- a/code/modules/awaymissions/exile.dm
+++ b/code/modules/awaymissions/exile.dm
@@ -7,7 +7,7 @@
/obj/item/implanter/exile/New()
src.imp = new /obj/item/implant/exile( src )
..()
- update()
+ update_icon()
return
diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm
index c12e806be3a..451d39ff0ce 100644
--- a/code/modules/customitems/item_defines.dm
+++ b/code/modules/customitems/item_defines.dm
@@ -23,7 +23,7 @@ All custom items with worn sprites must follow the contained sprite system: http
if (!implant_type)
return
imp = new implant_type(src)
- update()
+ update_icon()
return
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 9a616a821a9..e30dbd62985 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -1347,8 +1347,8 @@
hud_list[WANTED_HUD] = holder
if ( BITTEST(hud_updateflag, IMPLOYAL_HUD) \
- || BITTEST(hud_updateflag, IMPCHEM_HUD) \
- || BITTEST(hud_updateflag, IMPTRACK_HUD))
+ || BITTEST(hud_updateflag, IMPCHEM_HUD) \
+ || BITTEST(hud_updateflag, IMPTRACK_HUD))
var/image/holder1 = hud_list[IMPTRACK_HUD]
var/image/holder2 = hud_list[IMPLOYAL_HUD]
@@ -1361,7 +1361,7 @@
if(I.implanted)
if(istype(I,/obj/item/implant/tracking))
holder1.icon_state = "hud_imp_tracking"
- if(istype(I,/obj/item/implant/mindshield))
+ if(istype(I,/obj/item/implant/mindshield) && !istype(I,/obj/item/implant/mindshield/loyalty))
holder2.icon_state = "hud_imp_loyal"
if(istype(I,/obj/item/implant/chem))
holder3.icon_state = "hud_imp_chem"
diff --git a/code/modules/modular_computers/file_system/programs/command/teleporter.dm b/code/modules/modular_computers/file_system/programs/command/teleporter.dm
index 5260a61da3e..6f230b8a181 100644
--- a/code/modules/modular_computers/file_system/programs/command/teleporter.dm
+++ b/code/modules/modular_computers/file_system/programs/command/teleporter.dm
@@ -83,7 +83,7 @@
else
var/mob/M = I.loc
if(M.stat == DEAD)
- if(M.timeofdeath + 6000 < world.time)
+ if(M.timeofdeath + I.lifespan_postmortem < world.time)
continue
var/turf/IT = get_turf(M)
if(!IT)
diff --git a/code/modules/research/designs/protolathe/implant_designs.dm b/code/modules/research/designs/protolathe/implant_designs.dm
index 7aba0b48bbc..be6c0b9c2ac 100644
--- a/code/modules/research/designs/protolathe/implant_designs.dm
+++ b/code/modules/research/designs/protolathe/implant_designs.dm
@@ -2,12 +2,22 @@
materials = list(DEFAULT_WALL_MATERIAL = 50, MATERIAL_GLASS = 50)
p_category = "Implantable Biocircuit Designs"
+/datum/design/item/implant/adrenaline
+ name = "Adrenaline"
+ req_tech = list(TECH_MATERIAL = 1, TECH_ILLEGAL = 2, TECH_BIO = 3)
+ build_path = /obj/item/implantcase/adrenaline
+
/datum/design/item/implant/chemical
name = "Chemical"
req_tech = list(TECH_MATERIAL = 2, TECH_BIO = 3)
build_path = /obj/item/implantcase/chem
+/datum/design/item/implant/death_alarm
+ name = "Death Alarm"
+ req_tech = list(TECH_MATERIAL = 1, TECH_BIO = 3, TECH_DATA = 2)
+ build_path = /obj/item/implantcase/death_alarm
+
/datum/design/item/implant/freedom
name = "Freedom"
- req_tech = list(TECH_ILLEGAL = 2, TECH_BIO = 3)
- build_path = /obj/item/implantcase/freedom
\ No newline at end of file
+ req_tech = list(TECH_MATERIAL = 1, TECH_ILLEGAL = 2, TECH_BIO = 3)
+ build_path = /obj/item/implantcase/freedom
diff --git a/code/modules/surgery/encased.dm b/code/modules/surgery/encased.dm
index ff2089cb6f6..7c5821b0abc 100644
--- a/code/modules/surgery/encased.dm
+++ b/code/modules/surgery/encased.dm
@@ -103,6 +103,9 @@
affected.open = ORGAN_ENCASED_RETRACTED
+ for(var/obj/item/implant/I in affected.implants)
+ I.exposed()
+
/singleton/surgery_step/open_encased/retract/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
if(!ishuman(target))
return
diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm
index 1226e58e6c1..dd4b2d09025 100644
--- a/code/modules/surgery/generic.dm
+++ b/code/modules/surgery/generic.dm
@@ -183,7 +183,7 @@
/singleton/surgery_step/generic/cut_open_vaurca/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
user.visible_message("[user] has drilled into [target]'s [affected.name] carapace with \the [tool].", \
- SPAN_NOTICE("You have drilled into [target]'s [affected.name] carapace with \the [tool]."),)
+ SPAN_NOTICE("You have drilled into [target]'s [affected.name] carapace with \the [tool]."),)
affected.open = ORGAN_OPEN_INCISION
if(istype(target) && !(target.species.flags & NO_BLOOD))
@@ -281,6 +281,10 @@
user.visible_message(msg, self_msg)
affected.open = ORGAN_OPEN_RETRACTED
+ if(!affected.encased)
+ for(var/obj/item/implant/I in affected.implants)
+ I.exposed()
+
/singleton/surgery_step/generic/retract_skin/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
var/msg = SPAN_WARNING("[user]'s hand slips, tearing the edges of the incision on [target]'s [affected.name] with \the [tool]!")
diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm
index f71b7be2ae0..15089f651d9 100644
--- a/code/modules/surgery/implant.dm
+++ b/code/modules/surgery/implant.dm
@@ -192,7 +192,7 @@
if(istype(obj,/obj/item/implant))
var/obj/item/implant/imp = obj
- if(imp.islegal())
+ if(imp.isLegal())
find_prob += 60
else
find_prob += 40
diff --git a/code/stylesheet.dm b/code/stylesheet.dm
index 9080664a316..13d3a80d191 100644
--- a/code/stylesheet.dm
+++ b/code/stylesheet.dm
@@ -85,6 +85,7 @@ h1.alert, h2.alert {color: #000000;}
.rose {color: #ff5050;}
.info {color: #0000CC;}
.notice {color: #000099;}
+.hear {color: #000099; font-style: italic;}
.subtle {color: #000099; font-size: 75%; font-style: italic;}
.alium {color: #00ff00;}
.cult {color: #800080; font-weight: bold; font-style: italic;}
diff --git a/html/changelogs/GeneralCamo - Implant.yml b/html/changelogs/GeneralCamo - Implant.yml
new file mode 100644
index 00000000000..fac947cf362
--- /dev/null
+++ b/html/changelogs/GeneralCamo - Implant.yml
@@ -0,0 +1,50 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+# balance
+# admin
+# backend
+# security
+# refactor
+#################################
+
+# Your name.
+author: GeneralCamo
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - refactor: "Refactored implants to be easier to modify in the future."
+ - refactor: "Refactored the known implant system to use an implant's variable rather than a list in the body scanner, and allowed for implants completely hidden from all scanners."
+ - tweak: "Replaced the sprites for implanters, implant cases, implants, and implant pads. Sprites by Wowzewow (Wezzy)."
+ - tweak: "Implant pads are now used by placing the case onto them (or vice versa), and implanters now directly take implants from cases."
+ - rscadd: "Added the EMP implant, which will emit a burst of EMP when activated."
+ - rscdel: "Temporarily removed the compressed matter implant from the uplink, as it is difficult to use and needs new logic to fix up."
+ - rscadd: "Explosive implants now have an anti-tamper system that will warn if it is exposed in surgery, and can be triggered via radio signal as well as a custom phrase set in an implant pad."
+ - tweak: "Completely removed the emote triggering system from all implants, in favor of an action button-based system."
+ - rscadd: "Re-added loyalty implants, which still exist in the canon. These are currently unused, but variants exist for staff and event usage."
+ - bugfix: "Mindshield implants, when implanted, will no longer give the old loyalty implant messages. These are exclusive to loyalty implants."
diff --git a/icons/obj/action_buttons/implants.dmi b/icons/obj/action_buttons/implants.dmi
new file mode 100644
index 00000000000..a6aaeef180a
Binary files /dev/null and b/icons/obj/action_buttons/implants.dmi differ
diff --git a/icons/obj/item/implants.dmi b/icons/obj/item/implants.dmi
new file mode 100644
index 00000000000..78d0abcbc5b
Binary files /dev/null and b/icons/obj/item/implants.dmi differ
diff --git a/icons/obj/item/reagent_containers/syringe.dmi b/icons/obj/item/reagent_containers/syringe.dmi
index b30a98cb38a..df8d5e2ac96 100644
Binary files a/icons/obj/item/reagent_containers/syringe.dmi and b/icons/obj/item/reagent_containers/syringe.dmi differ