diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm
index 0a04e3135d..14118443f6 100644
--- a/_maps/map_files/BoxStation/BoxStation.dmm
+++ b/_maps/map_files/BoxStation/BoxStation.dmm
@@ -26582,6 +26582,7 @@
layer = 3;
pixel_x = 32
},
+/obj/machinery/aug_manipulator,
/turf/open/floor/plasteel/white,
/area/science/robotics/lab)
"bkp" = (
diff --git a/_maps/map_files/BoxStation/BoxStation.dmm.rej b/_maps/map_files/BoxStation/BoxStation.dmm.rej
new file mode 100644
index 0000000000..f0e788c352
--- /dev/null
+++ b/_maps/map_files/BoxStation/BoxStation.dmm.rej
@@ -0,0 +1,92 @@
+diff a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm (rejected hunks)
+@@ -33644,7 +33645,7 @@
+ /obj/machinery/atmospherics/components/unary/vent_pump/on{
+ dir = 4;
+ external_pressure_bound = 140;
+- pressure_checks = 0
++ pressure_checks = 0;
+ name = "server vent"
+ },
+ /turf/open/floor/circuit{
+@@ -83911,12 +83912,12 @@ aaa
+ aaa
+ aaa
+ cTg
+-cTl
+-cTn
+-cTr
+-cTu
+-cTw
+-cTz
++cTg
++cTi
++cTg
++cTi
++cTg
++cTg
+ aaa
+ bCq
+ bPS
+@@ -84167,13 +84168,13 @@ aaa
+ aaa
+ aaa
+ aaa
+-cTh
++cTg
+ bGg
+ cTo
+ cMl
+ bHx
+ cTx
+-cTA
++cTg
+ aaa
+ bLv
+ bPR
+@@ -84427,7 +84428,7 @@ bDi
+ cTi
+ bGh
+ bHx
+-cTs
++cTo
+ bHx
+ bLt
+ bMF
+@@ -84681,13 +84682,13 @@ bzP
+ bAS
+ bxu
+ aaa
+-cTj
++cTg
+ bGg
+-cTp
+-cTt
++cTo
++cTo
+ bHx
+ bLs
+-cTB
++cTg
+ aaa
+ bLv
+ bPT
+@@ -84938,13 +84939,13 @@ bzR
+ byd
+ bxx
+ aaa
+-cTk
+-cTm
+-cTq
++cTg
++cTg
++cTi
+ bJc
+-cTv
+-cTy
+-cTC
++cTi
++cTg
++cTg
+ aaa
+ bCq
+ bPV
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index 25444b30df..574dcbb095 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -93223,6 +93223,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 4
},
+/obj/machinery/aug_manipulator,
/turf/open/floor/plasteel,
/area/science/robotics/lab)
"dxQ" = (
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm.rej b/_maps/map_files/Deltastation/DeltaStation2.dmm.rej
new file mode 100644
index 0000000000..4b97f76ae0
--- /dev/null
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm.rej
@@ -0,0 +1,37 @@
+diff a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm (rejected hunks)
+@@ -156131,16 +156132,16 @@ cim
+ brN
+ brN
+ bqq
+-coe
++bkT
+ cpL
+-cqZ
++brH
+ csr
+-cub
++bmI
+ cvE
+ cwY
+-cqZ
+-cqZ
+-cqZ
++brH
++brH
++brH
+ brH
+ bkT
+ cFG
+@@ -156166,10 +156167,10 @@ djZ
+ dlM
+ dnc
+ doh
+-dpQ
++dnc
+ drt
+ dsT
+-dpQ
++dnc
+ ego
+ dwO
+ dyc
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 70059179c2..a7db1e0909 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -71201,6 +71201,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 8
},
+/obj/machinery/aug_manipulator,
/turf/open/floor/plasteel,
/area/science/robotics/lab)
"cFe" = (
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm.rej b/_maps/map_files/MetaStation/MetaStation.dmm.rej
new file mode 100644
index 0000000000..553b988622
--- /dev/null
+++ b/_maps/map_files/MetaStation/MetaStation.dmm.rej
@@ -0,0 +1,37 @@
+diff a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm (rejected hunks)
+@@ -45922,7 +45922,7 @@
+ /obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{
+ dir = 8;
+ frequency = 1441;
+- id_tag = "n2o_out"
++ id_tag = "n2o_out";
+ name = "n2o out"
+ },
+ /turf/open/floor/engine/n2o,
+@@ -49223,7 +49223,7 @@
+ /obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{
+ dir = 8;
+ frequency = 1441;
+- id_tag = "tox_out"
++ id_tag = "tox_out";
+ name = "toxin out"
+ },
+ /turf/open/floor/engine/plasma,
+@@ -52023,7 +52023,7 @@
+ /obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{
+ dir = 8;
+ frequency = 1441;
+- id_tag = "co2_out"
++ id_tag = "co2_out";
+ name = "co2 out"
+ },
+ /turf/open/floor/engine/co2,
+@@ -58890,7 +58890,7 @@
+ /obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{
+ dir = 1;
+ frequency = 1441;
+- id_tag = "n2_out"
++ id_tag = "n2_out";
+ name = "n2 out"
+ },
+ /turf/open/floor/engine/n2,
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index 758ff6f496..2b0e8ee74a 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -43,7 +43,7 @@
#define BODYPART_ROBOTIC 2
#define DEFAULT_BODYPART_ICON_ORGANIC 'icons/mob/human_parts_greyscale.dmi'
-#define DEFAULT_BODYPART_ICON_ROBOTIC 'icons/mob/augments.dmi'
+#define DEFAULT_BODYPART_ICON_ROBOTIC 'icons/mob/augmentation/augments.dmi'
#define MONKEY_BODYPART "monkey"
#define ALIEN_BODYPART "alien"
diff --git a/code/game/machinery/aug_manipulator.dm b/code/game/machinery/aug_manipulator.dm
new file mode 100644
index 0000000000..05d6a48064
--- /dev/null
+++ b/code/game/machinery/aug_manipulator.dm
@@ -0,0 +1,135 @@
+/obj/machinery/aug_manipulator
+ name = "\improper augment manipulator"
+ desc = "A machine for custom fitting augmentations, with in-built spraypainter."
+ icon = 'icons/obj/pda.dmi'
+ icon_state = "pdapainter"
+ density = TRUE
+ anchored = TRUE
+ obj_integrity = 200
+ max_integrity = 200
+ var/obj/item/bodypart/storedpart
+ var/initial_icon_state
+ var/static/list/style_list_icons = list("standard" = 'icons/mob/augmentation/augments.dmi', "engineer" = 'icons/mob/augmentation/augments_engineer.dmi', "security" = 'icons/mob/augmentation/augments_security.dmi', "mining" = 'icons/mob/augmentation/augments_mining.dmi')
+
+
+/obj/machinery/aug_manipulator/Initialize()
+ initial_icon_state = initial(icon_state)
+ return ..()
+
+/obj/machinery/aug_manipulator/update_icon()
+ cut_overlays()
+
+ if(stat & BROKEN)
+ icon_state = "[initial_icon_state]-broken"
+ return
+
+ if(storedpart)
+ add_overlay("[initial_icon_state]-closed")
+
+ if(powered())
+ icon_state = initial_icon_state
+ else
+ icon_state = "[initial_icon_state]-off"
+
+/obj/machinery/aug_manipulator/Destroy()
+ QDEL_NULL(storedpart)
+ return ..()
+
+/obj/machinery/aug_manipulator/on_deconstruction()
+ if(storedpart)
+ storedpart.forceMove(loc)
+ storedpart = null
+
+/obj/machinery/aug_manipulator/contents_explosion(severity, target)
+ if(storedpart)
+ storedpart.ex_act(severity, target)
+
+/obj/machinery/aug_manipulator/handle_atom_del(atom/A)
+ if(A == storedpart)
+ storedpart = null
+ update_icon()
+
+/obj/machinery/aug_manipulator/attackby(obj/item/O, mob/user, params)
+ if(default_unfasten_wrench(user, O))
+ power_change()
+ return
+
+ else if(istype(O, /obj/item/bodypart))
+ var/obj/item/bodypart/B = O
+ if(B.status != BODYPART_ROBOTIC)
+ to_chat(user, "The machine only accepts cybernetics!")
+ return
+ if(storedpart)
+ to_chat(user, "There is already something inside!")
+ return
+ else
+ O = user.get_active_held_item()
+ if(!user.transferItemToLoc(O, src))
+ return
+ storedpart = O
+ O.add_fingerprint(user)
+ update_icon()
+
+ else if(istype(O, /obj/item/weapon/weldingtool) && user.a_intent != INTENT_HARM)
+ var/obj/item/weapon/weldingtool/WT = O
+ if(obj_integrity < max_integrity)
+ if(WT.remove_fuel(0,user))
+ user.visible_message("[user] begins repairing [src].", \
+ "You begin repairing [src]...", \
+ "You hear welding.")
+ playsound(src, WT.usesound, 40, 1)
+ if(do_after(user,40*WT.toolspeed, TRUE, target = src))
+ if(!WT.isOn() || !(stat & BROKEN))
+ return
+ to_chat(user, "You repair [src].")
+ playsound(src, 'sound/items/welder2.ogg', 50, 1)
+ stat &= ~BROKEN
+ obj_integrity = max(obj_integrity, max_integrity)
+ update_icon()
+ else
+ to_chat(user, "[src] does not need repairs.")
+ else
+ return ..()
+
+/obj/machinery/aug_manipulator/obj_break(damage_flag)
+ if(!(flags & NODECONSTRUCT))
+ if(!(stat & BROKEN))
+ stat |= BROKEN
+ update_icon()
+
+/obj/machinery/aug_manipulator/attack_hand(mob/user)
+ if(!..())
+ add_fingerprint(user)
+
+ if(storedpart)
+ var/augstyle = input(user, "Select style.", "Augment Custom Fitting") as null|anything in style_list_icons
+ if(!augstyle)
+ return
+ if(!in_range(src, user))
+ return
+ if(!storedpart)
+ return
+ storedpart.icon = style_list_icons[augstyle]
+ eject_part(user)
+
+ else
+ to_chat(user, "\The [src] is empty.")
+
+/obj/machinery/aug_manipulator/proc/eject_part(mob/living/user)
+ if(storedpart)
+ storedpart.forceMove(get_turf(src))
+ storedpart = null
+ update_icon()
+ else
+ to_chat(user, "[src] is empty.")
+
+/obj/machinery/aug_manipulator/AltClick(mob/living/user)
+ ..()
+ if(!user.canUseTopic(src))
+ return
+ else
+ eject_part(user)
+
+/obj/machinery/aug_manipulator/power_change()
+ ..()
+ update_icon()
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 4844a4e804..5d78b9c4e0 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -254,6 +254,10 @@
var/dynamic_hair_suffix = "" //if this is non-null, and hair+suffix matches an iconstate, then we render that hair instead
var/dynamic_fhair_suffix = ""
+ //for augmented heads
+ if(HD.status == BODYPART_ROBOTIC)
+ return
+
//we check if our hat or helmet hides our facial hair.
if(H.head)
var/obj/item/I = H.head
diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm
index d93fc658dd..b239e39576 100644
--- a/code/modules/surgery/bodyparts/bodyparts.dm
+++ b/code/modules/surgery/bodyparts/bodyparts.dm
@@ -306,7 +306,7 @@
else
limb.icon_state = "[animal_origin]_[body_zone]"
else
- limb.icon = 'icons/mob/augments.dmi'
+ limb.icon = 'icons/mob/augmentation/augments.dmi'
limb.icon_state = "[animal_origin]_[body_zone]"
return
diff --git a/code/modules/surgery/bodyparts/robot_bodyparts.dm b/code/modules/surgery/bodyparts/robot_bodyparts.dm
index 00a01e2d2e..c956380d20 100644
--- a/code/modules/surgery/bodyparts/robot_bodyparts.dm
+++ b/code/modules/surgery/bodyparts/robot_bodyparts.dm
@@ -165,27 +165,27 @@
/obj/item/bodypart/l_arm/robot/surplus
name = "surplus prosthetic left arm"
desc = "A skeletal, robotic limb. Outdated and fragile, but it's still better than nothing."
- icon = 'icons/mob/surplus_augments.dmi'
+ icon = 'icons/mob/augmentation/surplus_augments.dmi'
icon_state = "l_arm"
max_damage = 20
/obj/item/bodypart/r_arm/robot/surplus
name = "surplus prosthetic right arm"
desc = "A skeletal, robotic limb. Outdated and fragile, but it's still better than nothing."
- icon = 'icons/mob/surplus_augments.dmi'
+ icon = 'icons/mob/augmentation/surplus_augments.dmi'
icon_state = "r_arm"
max_damage = 20
/obj/item/bodypart/l_leg/robot/surplus
name = "surplus prosthetic left leg"
desc = "A skeletal, robotic limb. Outdated and fragile, but it's still better than nothing."
- icon = 'icons/mob/surplus_augments.dmi'
+ icon = 'icons/mob/augmentation/surplus_augments.dmi'
icon_state = "l_leg"
max_damage = 20
/obj/item/bodypart/r_leg/robot/surplus
name = "surplus prosthetic right leg"
desc = "A skeletal, robotic limb. Outdated and fragile, but it's still better than nothing."
- icon = 'icons/mob/surplus_augments.dmi'
+ icon = 'icons/mob/augmentation/surplus_augments.dmi'
icon_state = "r_leg"
max_damage = 20
diff --git a/code/modules/surgery/limb_augmentation.dm b/code/modules/surgery/limb_augmentation.dm
index aaea6de1d5..caeb966d96 100644
--- a/code/modules/surgery/limb_augmentation.dm
+++ b/code/modules/surgery/limb_augmentation.dm
@@ -57,6 +57,7 @@
qdel(tool)
target.update_body_parts()
target.updatehealth()
+ target.update_hair()
add_logs(user, target, "augmented", addition="by giving him new [parse_zone(target_zone)] INTENT: [uppertext(user.a_intent)]")
else
to_chat(user, "[target] has no organic [parse_zone(target_zone)] there!")
diff --git a/icons/mob/augmentation/augments.dmi b/icons/mob/augmentation/augments.dmi
new file mode 100644
index 0000000000..a532348d6d
Binary files /dev/null and b/icons/mob/augmentation/augments.dmi differ
diff --git a/icons/mob/augmentation/augments_engineer.dmi b/icons/mob/augmentation/augments_engineer.dmi
new file mode 100644
index 0000000000..8aeaaf04e0
Binary files /dev/null and b/icons/mob/augmentation/augments_engineer.dmi differ
diff --git a/icons/mob/augmentation/augments_mining.dmi b/icons/mob/augmentation/augments_mining.dmi
new file mode 100644
index 0000000000..b79c54e9c8
Binary files /dev/null and b/icons/mob/augmentation/augments_mining.dmi differ
diff --git a/icons/mob/augmentation/augments_security.dmi b/icons/mob/augmentation/augments_security.dmi
new file mode 100644
index 0000000000..8f57f77c4b
Binary files /dev/null and b/icons/mob/augmentation/augments_security.dmi differ
diff --git a/icons/mob/augmentation/augments_standard.dmi b/icons/mob/augmentation/augments_standard.dmi
new file mode 100644
index 0000000000..a532348d6d
Binary files /dev/null and b/icons/mob/augmentation/augments_standard.dmi differ
diff --git a/icons/mob/surplus_augments.dmi b/icons/mob/augmentation/surplus_augments.dmi
similarity index 100%
rename from icons/mob/surplus_augments.dmi
rename to icons/mob/augmentation/surplus_augments.dmi
diff --git a/icons/mob/augments.dmi b/icons/mob/augments.dmi
deleted file mode 100644
index 7124c35105..0000000000
Binary files a/icons/mob/augments.dmi and /dev/null differ
diff --git a/tgstation.dme b/tgstation.dme
index 0cda536cdd..c2d9554891 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -553,6 +553,7 @@
#include "code\game\machinery\ai_slipper.dm"
#include "code\game\machinery\airlock_control.dm"
#include "code\game\machinery\announcement_system.dm"
+#include "code\game\machinery\aug_manipulator.dm"
#include "code\game\machinery\autolathe.dm"
#include "code\game\machinery\bank_machine.dm"
#include "code\game\machinery\Beacon.dm"