diff --git a/code/__defines/items_clothing.dm b/code/__defines/items_clothing.dm
index 85837062365..a6d4648e618 100644
--- a/code/__defines/items_clothing.dm
+++ b/code/__defines/items_clothing.dm
@@ -31,6 +31,7 @@
#define NOREACT 0x40 // Reagents don't react inside this container.
#define PROXMOVE 0x80 // Does this object require proximity checking in Enter()?
#define HELDMAPTEXT 0x100 // Uses the special held maptext system, which sets a specific maptext if the item is in possession of a mob.
+#define NOMOVE 0x200 // Cannot be moved from its current inventory slot. Mostly for augments, modules, and other "attached" items.
//Flags for items (equipment)
#define THICKMATERIAL BITFLAG(0) // Prevents syringes, parapens and hyposprays if equiped to slot_suit or slot_head.
diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm
index abd48a89dd5..579cbbb7a40 100644
--- a/code/_helpers/mobs.dm
+++ b/code/_helpers/mobs.dm
@@ -158,14 +158,15 @@ Proc for attack log creation, because really why not
if(admin)
log_attack("[user ? "[user.name][(ismob(user) && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"] [what_done] [target ? "[target.name][(ismob(target) && target.ckey)? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition]",ckey=key_name(user),ckey_target=key_name(target))
-//checks whether this item is a module of the robot it is located in.
+//checks whether this item is a module of the robot or exosuit it is located in. This is mainly to ensure that things do not get embedded or fed into autolathes if attached to a bot or exosuit
/proc/is_robot_module(var/obj/item/thing)
if(!thing)
return FALSE
if(istype(thing.loc, /mob/living/heavy_vehicle))
- return FALSE
- if(!istype(thing.loc, /mob/living/silicon/robot))
- return FALSE
+ return TRUE
+ if(istype(thing.loc, /mob/living/silicon/robot))
+ var/mob/living/silicon/robot/R = thing.loc
+ return (thing in R.module.modules)
/proc/get_exposed_defense_zone(var/atom/movable/target)
var/obj/item/grab/G = locate() in target
diff --git a/code/game/gamemodes/changeling/implements/items.dm b/code/game/gamemodes/changeling/implements/items.dm
index a6ddf5d21d9..82d312b9271 100644
--- a/code/game/gamemodes/changeling/implements/items.dm
+++ b/code/game/gamemodes/changeling/implements/items.dm
@@ -10,6 +10,7 @@
sharp = TRUE
edge = TRUE
anchored = TRUE
+ item_flags = NOMOVE //It deploys from your arm and stays there
throwforce = 0 //Just to be on the safe side
throw_range = 0
throw_speed = 0
@@ -68,6 +69,7 @@
contained_sprite = TRUE
force = 15 //Bash the crap out of people
slot_flags = null
+ item_flags = NOMOVE //It deploys from your arm and stays there
anchored = TRUE
throwforce = 0 //Just to be on the safe side
throw_range = 0
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index 5053c88cf04..ecfa3766693 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -22,7 +22,10 @@
//set disable_warning to disable the 'you are unable to equip that' warning.
//unset redraw_mob to prevent the mob from being redrawn at the end.
/mob/proc/equip_to_slot_if_possible(obj/item/W as obj, slot, del_on_fail = FALSE, disable_warning = FALSE, redraw_mob = TRUE, ignore_blocked = FALSE, assisted_equip = FALSE)
- if(!istype(W)) return 0
+ if(!istype(W))
+ return FALSE
+ if(W.item_flags & NOMOVE) //Cannot move NOMOVE items from one inventory slot to another. Cannot do canremove here because then BSTs spawn naked.
+ return FALSE
if(!W.mob_can_equip(src, slot, disable_warning, ignore_blocked))
if(del_on_fail)
@@ -393,12 +396,13 @@ var/list/slot_equipment_priority = list( \
continue
return TRUE //Something is stopping us. Takes off throw mode.
- remove_from_mob(I)
- make_item_drop_sound(I)
- I.forceMove(T)
- return TRUE
+ if(unEquip(I))
+ make_item_drop_sound(I)
+ I.forceMove(T)
+ return TRUE
- remove_from_mob(item)
+ if(!unEquip(item))
+ return TRUE
if(is_pacified())
to_chat(src, "You set [item] down gently on the ground.")
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index 76462c6d862..a6beeac3f38 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -102,11 +102,11 @@
apply_damage(effective_force, I.damtype, hit_zone, I, damage_flags, I.armor_penetration)
//Melee weapon embedded object code.
- if (I && I.damtype == BRUTE && !I.anchored && !is_robot_module(I))
+ if (I && I.damtype == BRUTE && !I.anchored && !is_robot_module(I) && I.canremove)
var/damage = effective_force //just the effective damage used for sorting out embedding, no further damage is applied here
damage *= 1 - get_blocked_ratio(hit_zone, I.damtype, I.damage_flags(), I.armor_penetration, I.force)
- if(I.can_embed)//If this weapon is allowed to embed in people
+ if(I.can_embed) //If this weapon is allowed to embed in people.
//blunt objects should really not be embedding in things unless a huge amount of force is involved
var/sharp = damage_flags & DAM_SHARP
var/edge = damage_flags & DAM_EDGE
diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm
index 733e69fe803..9e63bc90222 100644
--- a/code/modules/mob/living/carbon/human/human_attackhand.dm
+++ b/code/modules/mob/living/carbon/human/human_attackhand.dm
@@ -443,12 +443,15 @@
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
return
- //Actually disarm them
+ //Actually disarm them, if possible
for(var/obj/item/I in holding)
- drop_from_inventory(I)
- visible_message("[M] has disarmed [src]!")
- playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
- return
+ if(unEquip(I))
+ visible_message(SPAN_DANGER("\The [M] has disarmed \the [src]!"))
+ playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
+ return
+ else
+ to_chat(M, SPAN_WARNING("You cannot disarm \the [I] from \the [src], as it's attached to them!"))
+ //No return here is intentional, as it will then try to disarm other items, and/or play a failed disarm message
playsound(loc, /decl/sound_category/punchmiss_sound, 25, 1, -1)
visible_message("[M] attempted to disarm [src]!")
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index 96732844a66..cfcad760f6f 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -1208,6 +1208,8 @@ Note that amputating the affected organ does in fact remove the infection from t
/obj/item/organ/external/proc/embed(var/obj/item/W, var/silent = 0, var/supplied_message)
if(!owner || loc != owner)
return
+ if(!W.canremove || is_robot_module(W)) //Modules and augments cannot embed
+ return
if(species.flags & NO_EMBED)
return
if(!silent)
diff --git a/code/modules/organs/subtypes/augment.dm b/code/modules/organs/subtypes/augment.dm
index 3949bc3c2a4..b57d128467e 100644
--- a/code/modules/organs/subtypes/augment.dm
+++ b/code/modules/organs/subtypes/augment.dm
@@ -116,6 +116,8 @@
return
var/obj/item/M = new augment_type(owner)
+ M.canremove = FALSE
+ M.item_flags |= NOMOVE
owner.equip_to_slot(M, aug_slot)
owner.visible_message(SPAN_NOTICE("\The [M] slides out of \the [owner]'s [owner.organs_by_name[parent_organ]]."), SPAN_NOTICE("You deploy \the [M]!"))
diff --git a/code/modules/organs/subtypes/autakh.dm b/code/modules/organs/subtypes/autakh.dm
index 5cf4f5845e1..0b375445ebd 100644
--- a/code/modules/organs/subtypes/autakh.dm
+++ b/code/modules/organs/subtypes/autakh.dm
@@ -283,6 +283,8 @@
owner.last_special = world.time + 100
var/obj/item/M = new augment_type(owner)
+ M.canremove = FALSE
+ M.item_flags |= NOMOVE
owner.put_in_active_hand(M)
owner.visible_message("\The [M] slides out of \the [owner]'s [src].","You deploy \the [M]!")
diff --git a/html/changelogs/doxxmedearly-augments_modules_fixes.yml b/html/changelogs/doxxmedearly-augments_modules_fixes.yml
new file mode 100644
index 00000000000..2e9c6b7aeb2
--- /dev/null
+++ b/html/changelogs/doxxmedearly-augments_modules_fixes.yml
@@ -0,0 +1,7 @@
+author: Doxxmedearly
+delete-after: True
+changes:
+ - bugfix: "Deployed augment items (Combitools, lighters, and the like) can no longer be removed from their hand slot, placed or thrown on the ground, put in bags or pockets, etc."
+ - bugfix: "Attached items (Augments, robot modules, exosuit equipment) will no longer embed in mobs if used to attack."
+ - bugfix: "Attached items can no longer be removed via disarming. This applies to the above, as well as some special equipment, like changeling armblades."
+ - bugfix: "The autolathe will (once again) no longer eat robot modules."