diff --git a/aurorastation.dme b/aurorastation.dme
index 860cea55748..abad77eb6eb 100644
--- a/aurorastation.dme
+++ b/aurorastation.dme
@@ -763,6 +763,7 @@
#include "code\game\objects\items\devices\multitool.dm"
#include "code\game\objects\items\devices\oxycandle.dm"
#include "code\game\objects\items\devices\paicard.dm"
+#include "code\game\objects\items\devices\pin_extractor.dm"
#include "code\game\objects\items\devices\pipe_painter.dm"
#include "code\game\objects\items\devices\powersink.dm"
#include "code\game\objects\items\devices\radio_jammer.dm"
diff --git a/code/game/objects/items/devices/pin_extractor.dm b/code/game/objects/items/devices/pin_extractor.dm
new file mode 100644
index 00000000000..cc010bedf4a
--- /dev/null
+++ b/code/game/objects/items/devices/pin_extractor.dm
@@ -0,0 +1,51 @@
+/obj/item/device/pin_extractor
+ name = "firing pin extractor"
+ desc = "A device that is capable of removing firing pin without damaging it."
+ icon = 'icons/obj/device.dmi'
+ icon_state = "pin_extractor"
+ item_state = "pin_extractor"
+ w_class = 2
+ flags = CONDUCT
+ action_button_name = "Toggle extractor"
+ var/on = 0
+ var/activation_sound = 'sound/effects/lighton.ogg'
+ origin_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 3, TECH_MAGNET = 4)
+
+
+/obj/item/device/pin_extractor/update_icon()
+ if(on)
+ icon_state = "[initial(icon_state)]-on"
+ else
+ icon_state = "[initial(icon_state)]"
+
+/obj/item/device/pin_extractor/attack_self(mob/user)
+ on = !on
+ if(on && activation_sound)
+ playsound(src.loc, activation_sound, 75, 1)
+ update_icon()
+ user.update_action_buttons()
+ return 1
+
+/obj/item/device/pin_extractor/afterattack(atom/target, mob/user, proximity_flag)
+ if(proximity_flag)
+ if(istype(target, /obj/item/weapon/gun))
+ if(!on)
+ to_chat(user, "\The [src.name] is not turned on.")
+ ..()
+ return
+ var/obj/item/weapon/gun/G = target
+ if(G.pin)
+ to_chat(user, "You begin removing [G.name]'s [G.pin.name] using \the [src.name], it will take 15 seconds.")
+
+ if(!do_after(user, 15 SECONDS, act_target = target))
+ return
+
+ to_chat(user, "You remove [G.name]'s [G.pin.name].")
+ G.pin.forceMove(get_turf(G))
+ G.pin.gun = null
+ G.pin = null
+
+ else
+ to_chat(user, "\The [G.name] doesn't have a firing pin installed.")
+ else
+ ..()
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm
index 03c27ce148d..7d5c3845f95 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm
@@ -45,6 +45,7 @@
new /obj/item/clothing/mask/gas(src)
new /obj/item/device/flash(src)
new /obj/item/weapon/storage/box/firingpinsRD(src)
+ new /obj/item/device/pin_extractor(src)
/obj/structure/closet/secure_closet/RD2
name = "research director's attire"
diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm
index 9b9647177d8..f26d4b687fc 100644
--- a/code/modules/research/designs.dm
+++ b/code/modules/research/designs.dm
@@ -177,7 +177,7 @@ other types of metals and chemistry for reagents).
req_tech = list(TECH_ENGINEERING = 4, TECH_MATERIAL = 4)
materials = list(DEFAULT_WALL_MATERIAL = 500)
build_path =/obj/item/weapon/weldingtool/experimental
- sort_string = "VABAJ"
+ sort_string = "VABAJ"
/datum/design/item/posibrain
name = "Positronic brain"
@@ -434,3 +434,11 @@ other types of metals and chemistry for reagents).
materials = list(DEFAULT_WALL_MATERIAL = 2000)
build_path = /obj/item/weapon/disk/integrated_circuit/upgrade/advanced
sort_string = "VCAAH"
+
+/datum/design/item/pin_extractor
+ name = "Pin extraction device"
+ id = "pin_extractor"
+ req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 3, TECH_MAGNET = 4, TECH_ILLEGAL = 4)
+ materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 2500)
+ build_path = /obj/item/device/pin_extractor
+ sort_string = "VCBAA"
\ No newline at end of file
diff --git a/html/changelogs/Sindorman-pinextractor.yml b/html/changelogs/Sindorman-pinextractor.yml
new file mode 100644
index 00000000000..2baff2372cc
--- /dev/null
+++ b/html/changelogs/Sindorman-pinextractor.yml
@@ -0,0 +1,37 @@
+################################
+# 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
+#################################
+
+# Your name.
+author: PoZe
+
+# 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:
+ - rscadd: "Added firing pin extraction device that can extract pins safely. The device will spawn inside the RD's locker. It can be printed in Protholate, but it is illegal to make these devices without head of staff approval."
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index 35f6455dc3c..bf43be741bc 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ