diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm
index 798b0e4c65..a2fbeee703 100644
--- a/code/game/machinery/computer/prisoner.dm
+++ b/code/game/machinery/computer/prisoner.dm
@@ -33,11 +33,11 @@
dat += "
Chemical Implants
"
var/turf/Tr = null
for(var/obj/item/implant/chem/C in GLOB.tracked_chem_implants)
- Tr = get_turf(C)
- if((Tr) && (Tr.z != src.z))
- continue//Out of range
if(!C.imp_in)
continue
+ Tr = get_turf(C.imp_in)
+ if((Tr) && (Tr.z != src.z))
+ continue//Out of range
dat += "ID: [C.imp_in.name] | Remaining Units: [C.reagents.total_volume]
"
dat += "| Inject: "
dat += "((1))"
@@ -48,7 +48,7 @@
for(var/obj/item/implant/tracking/T in GLOB.tracked_implants)
if(!isliving(T.imp_in))
continue
- Tr = get_turf(T)
+ Tr = get_turf(T.imp_in)
if((Tr) && (Tr.z != src.z))
continue//Out of range
diff --git a/code/game/machinery/computer/teleporter.dm b/code/game/machinery/computer/teleporter.dm
index b9b95eecd0..0bb9f51811 100644
--- a/code/game/machinery/computer/teleporter.dm
+++ b/code/game/machinery/computer/teleporter.dm
@@ -127,11 +127,11 @@
if(!I.imp_in || !isliving(I.loc))
continue
else
- var/mob/living/M = I.loc
+ var/mob/living/M = I.imp_in
if(M.stat == DEAD)
if(M.timeofdeath + 6000 < world.time)
continue
- if(is_eligible(I))
+ if(is_eligible(I.imp_in))
L[avoid_assoc_duplicate_keys(M.real_name, areaindex)] = I
var/desc = input("Please select a location to lock in.", "Locking Computer") as null|anything in L
diff --git a/code/game/objects/items/implants/implant.dm b/code/game/objects/items/implants/implant.dm
index 482cfb0d8e..e7b55d53f5 100644
--- a/code/game/objects/items/implants/implant.dm
+++ b/code/game/objects/items/implants/implant.dm
@@ -72,7 +72,7 @@
else
return FALSE
- forceMove(target)
+ moveToNullspace()
imp_in = target
target.implants += src
if(activated)
@@ -89,7 +89,6 @@
return TRUE
/obj/item/implant/proc/removed(mob/living/source, silent = FALSE, special = 0)
- moveToNullspace()
imp_in = null
source.implants -= src
for(var/X in actions)
diff --git a/code/game/objects/items/implants/implant_chem.dm b/code/game/objects/items/implants/implant_chem.dm
index b9c85c0728..a951ae5759 100644
--- a/code/game/objects/items/implants/implant_chem.dm
+++ b/code/game/objects/items/implants/implant_chem.dm
@@ -4,6 +4,7 @@
icon_state = "reagents"
container_type = OPENCONTAINER
activated = FALSE
+ var/obj/item/chemholder
/obj/item/implant/chem/get_data()
var/dat = {"Implant Specifications:
@@ -30,6 +31,21 @@
GLOB.tracked_chem_implants -= src
return ..()
+/obj/item/implant/chem/implant(mob/living/target, mob/user, silent = FALSE)
+ . = ..()
+ if(.)
+ chemholder = new(imp_in)
+ chemholder.resistance_flags |= INDESTRUCTIBLE //bomb-proofing.
+ chemholder.item_flags |= DROPDEL
+ reagents.trans_to(chemholder, reagents.total_volume)
+
+/obj/item/implant/chem/removed(mob/target, silent = FALSE, special = 0)
+ . = ..()
+ if(.)
+ chemholder.reagents.trans_to(src, chemholder.reagents.total_volume)
+ QDEL_NULL(chemholder)
+
+
/obj/item/implant/chem/trigger(emote, mob/living/source)
if(emote == "deathgasp")
if(istype(source) && !(source.stat == DEAD))
@@ -46,13 +62,12 @@
injectamount = reagents.total_volume
else
injectamount = cause
- reagents.trans_to(R, injectamount)
+ chemholder.reagents.trans_to(R, injectamount)
to_chat(R, "You hear a faint beep.")
- if(!reagents.total_volume)
+ if(!chemholder.reagents.total_volume)
to_chat(R, "You hear a faint click from your chest.")
qdel(src)
-
/obj/item/implantcase/chem
name = "implant case - 'Remote Chemical'"
desc = "A glass case containing a remote chemical implant."
diff --git a/code/game/objects/items/implants/implant_explosive.dm b/code/game/objects/items/implants/implant_explosive.dm
index e749a6c4be..a78bc45c69 100644
--- a/code/game/objects/items/implants/implant_explosive.dm
+++ b/code/game/objects/items/implants/implant_explosive.dm
@@ -11,8 +11,9 @@
var/popup = FALSE // is the DOUWANNABLOWUP window open?
var/active = FALSE
-/obj/item/implant/explosive/on_mob_death(mob/living/L, gibbed)
- activate("death")
+/obj/item/implant/sad_trombone/trigger(emote, mob/source)
+ if(emote == "deathgasp")
+ activate("death")
/obj/item/implant/explosive/get_data()
var/dat = {"Implant Specifications:
@@ -29,32 +30,18 @@
/obj/item/implant/explosive/activate(cause)
. = ..()
if(!cause || !imp_in || active)
- return 0
+ return FALSE
if(cause == "action_button" && !popup)
popup = TRUE
var/response = alert(imp_in, "Are you sure you want to activate your [name]? This will cause you to explode!", "[name] Confirmation", "Yes", "No")
popup = FALSE
if(response == "No")
- return 0
- heavy = round(heavy)
- medium = round(medium)
- weak = round(weak)
- to_chat(imp_in, "You activate your [name].")
- active = TRUE
- var/turf/boomturf = get_turf(imp_in)
- message_admins("[ADMIN_LOOKUPFLW(imp_in)] has activated their [name] at [ADMIN_VERBOSEJMP(boomturf)], with cause of [cause].")
-//If the delay is short, just blow up already jeez
- if(delay <= 7)
- explosion(src,heavy,medium,weak,weak, flame_range = weak)
- if(imp_in)
- imp_in.gib(1)
- qdel(src)
- return
- timed_explosion()
+ return FALSE
+ addtimer(CALLBACK(src, .proc/timed_explosion, cause), 1)
/obj/item/implant/explosive/implant(mob/living/target)
for(var/X in target.implants)
- if(istype(X, type))
+ if(istype(X, /obj/item/implant/explosive))
var/obj/item/implant/explosive/imp_e = X
imp_e.heavy += heavy
imp_e.medium += medium
@@ -65,22 +52,37 @@
return ..()
-/obj/item/implant/explosive/proc/timed_explosion()
- imp_in.visible_message("[imp_in] starts beeping ominously!")
- playsound(loc, 'sound/items/timer.ogg', 30, 0)
- sleep(delay*0.25)
- if(imp_in && !imp_in.stat)
+/obj/item/implant/explosive/proc/timed_explosion(cause)
+ if(cause == "death" && imp_in.stat != DEAD)
+ return FALSE
+ heavy = round(heavy)
+ medium = round(medium)
+ weak = round(weak)
+ to_chat(imp_in, "You activate your [name].")
+ active = TRUE
+ var/turf/boomturf = get_turf(imp_in)
+ message_admins("[ADMIN_LOOKUPFLW(imp_in)] has activated their [name] at [ADMIN_VERBOSEJMP(boomturf)], with cause of [cause].")
+ if(delay > 7)
+ imp_in?.visible_message("[imp_in] starts beeping ominously!")
+ playsound(get_turf(imp_in ? imp_in : src), 'sound/items/timer.ogg', 30, 0)
+ addtimer(CALLBACK(src, .proc/double_pain, TRUE), delay * 0.25)
+ addtimer(CALLBACK(src, .proc/double_pain), delay * 0.5)
+ addtimer(CALLBACK(src, .proc/double_pain), delay * 0.75)
+ addtimer(CALLBACK(src, .proc/boom_goes_the_weasel), delay)
+ else //If the delay is short, just blow up already jeez
+ boom_goes_the_weasel()
+
+/obj/item/implant/explosive/proc/double_pain(message = FALSE)
+ playsound(get_turf(imp_in ? imp_in : src), 'sound/items/timer.ogg', 30, 0)
+ if(!imp_in)
+ return
+ if(message && imp_in.stat == CONSCIOUS)
imp_in.visible_message("[imp_in] doubles over in pain!")
- imp_in.Knockdown(140)
- playsound(loc, 'sound/items/timer.ogg', 30, 0)
- sleep(delay*0.25)
- playsound(loc, 'sound/items/timer.ogg', 30, 0)
- sleep(delay*0.25)
- playsound(loc, 'sound/items/timer.ogg', 30, 0)
- sleep(delay*0.25)
- explosion(src,heavy,medium,weak,weak, flame_range = weak)
- if(imp_in)
- imp_in.gib(1)
+ imp_in.Knockdown(140)
+
+/obj/item/implant/explosive/proc/boom_goes_the_weasel()
+ explosion(get_turf(imp_in ? imp_in : src), heavy, medium, weak, weak, flame_range = weak)
+ imp_in?.gib(TRUE)
qdel(src)
/obj/item/implant/explosive/macro
@@ -95,17 +97,7 @@
/obj/item/implant/explosive/macro/implant(mob/living/target)
for(var/X in target.implants)
if(istype(X, type))
- return 0
-
- for(var/Y in target.implants)
- if(istype(Y, /obj/item/implant/explosive))
- var/obj/item/implant/explosive/imp_e = Y
- heavy += imp_e.heavy
- medium += imp_e.medium
- weak += imp_e.weak
- delay += imp_e.delay
- qdel(imp_e)
- break
+ return FALSE
return ..()
diff --git a/code/game/objects/items/implants/implant_misc.dm b/code/game/objects/items/implants/implant_misc.dm
index 24ee6d0966..78bdded601 100644
--- a/code/game/objects/items/implants/implant_misc.dm
+++ b/code/game/objects/items/implants/implant_misc.dm
@@ -103,10 +103,22 @@
radio.name = "internal radio"
radio.subspace_transmission = subspace_transmission
radio.canhear_range = 0
+ radio.resistance_flags |= INDESTRUCTIBLE
+ radio.item_flags |= DROPDEL
if(radio_key)
radio.keyslot = new radio_key
radio.recalculateChannels()
+/obj/item/implant/radio/implant(mob/living/target, mob/user, silent = FALSE)
+ . = ..()
+ if(.)
+ radio.forceMove(imp_in)
+
+/obj/item/implant/radio/removed(mob/living/source, silent = FALSE, special = 0)
+ . = ..()
+ if(.)
+ radio.forceMove(src)
+
/obj/item/implant/radio/mining
radio_key = /obj/item/encryptionkey/headset_cargo
diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm
index 1ccc88d892..e9245e233a 100644
--- a/code/game/objects/items/teleportation.dm
+++ b/code/game/objects/items/teleportation.dm
@@ -75,15 +75,14 @@
temp += "Implant Signals:
"
for (var/obj/item/implant/tracking/W in GLOB.tracked_implants)
- if (!W.imp_in || !isliving(W.loc))
+ if (!isliving(W.imp_in))
continue
- else
- var/mob/living/M = W.loc
- if (M.stat == DEAD)
- if (M.timeofdeath + 6000 < world.time)
- continue
+ var/mob/living/M = W.imp_in
+ if (M.stat == DEAD)
+ if (M.timeofdeath + 6000 < world.time)
+ continue
- var/turf/tr = get_turf(W)
+ var/turf/tr = get_turf(W.imp_in)
if (tr.z == sr.z && tr)
var/direct = max(abs(tr.x - sr.x), abs(tr.y - sr.y))
if (direct < 20)