diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm
index e6fb2c03322..535e4cbd826 100644
--- a/code/game/machinery/embedded_controller/embedded_controller_base.dm
+++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm
@@ -30,6 +30,8 @@
src.ui_interact(user)
/obj/machinery/embedded_controller/attack_hand(mob/user as mob)
+ if(!user.IsAdvancedToolUser())
+ return 0
src.ui_interact(user)
/obj/machinery/embedded_controller/ui_interact()
diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm
index 82328073b4b..8ce8273a526 100644
--- a/code/game/machinery/navbeacon.dm
+++ b/code/game/machinery/navbeacon.dm
@@ -130,6 +130,8 @@
/obj/machinery/navbeacon/attack_hand(var/mob/user)
+ if(!user.IsAdvancedToolUser())
+ return 0
interact(user, 0)
/obj/machinery/navbeacon/interact(var/mob/user, var/ai = 0)
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index 282ea222d8f..9aa87881287 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/game/machinery/newscaster.dm
@@ -180,6 +180,10 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co
/obj/machinery/newscaster/attack_hand(mob/user as mob) //########### THE MAIN BEEF IS HERE! And in the proc below this...############
if(!src.ispowered || src.isbroken)
return
+
+ if(!user.IsAdvancedToolUser())
+ return 0
+
if(istype(user, /mob/living/carbon/human) || istype(user,/mob/living/silicon) )
var/mob/living/human_or_robot_user = user
var/dat
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index 3aea4a33a6d..4017d1f3be1 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -96,6 +96,8 @@
return
if(stat & NOPOWER)
return
+ if(!user.IsAdvancedToolUser())
+ return 0
if(src.panelopen) //The maintenance panel is open. Time for some shady stuff
dat+= "
Suit storage unit: Maintenance panel"
dat+= "Maintenance panel controls
"
@@ -743,6 +745,9 @@
if(..() || stat & (BROKEN|NOPOWER))
return
+ if(!user.IsAdvancedToolUser())
+ return 0
+
if(electrified != 0)
if(src.shock(user, 100))
return
diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm
index e0946240530..7c92cdc2249 100644
--- a/code/game/objects/items/weapons/dna_injector.dm
+++ b/code/game/objects/items/weapons/dna_injector.dm
@@ -99,8 +99,7 @@
var/mob/living/carbon/human/H = M
if(H.species.flags & IS_SYNTHETIC)
return
- if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
- user << "\red You don't have the dexterity to do this!"
+ if (!usr.IsAdvancedToolUser())
return
M.attack_log += text("\[[time_stamp()]\] Has been injected with [name] by [user.name] ([user.ckey])")
diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm
index b0abf1bb4f8..b44235a3c4f 100644
--- a/code/game/objects/items/weapons/handcuffs.dm
+++ b/code/game/objects/items/weapons/handcuffs.dm
@@ -17,6 +17,9 @@
var/trashtype = null //For disposable cuffs
/obj/item/weapon/restraints/handcuffs/attack(mob/living/carbon/C, mob/user)
+ if(!user.IsAdvancedToolUser())
+ return
+
if(CLUMSY in user.mutations && prob(50))
user << "Uh... how do those things work?!"
apply_cuffs(user,user)
diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm
index 72fcc6d4f53..49da421a9ca 100644
--- a/code/modules/clothing/masks/miscellaneous.dm
+++ b/code/modules/clothing/masks/miscellaneous.dm
@@ -10,6 +10,13 @@
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/mask.dmi'
)
+
+// Clumsy folks can't take the mask off themselves.
+/obj/item/clothing/mask/muzzle/attack_hand(mob/user as mob)
+ if(user.wear_mask == src && !user.IsAdvancedToolUser())
+ return 0
+ ..()
+
/obj/item/clothing/mask/muzzle/gag
name = "gag"
desc = "Stick this in their mouth to stop the noise."
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index c60fce02d31..6b5d5ef8263 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1091,9 +1091,6 @@
tinted += MT.tint
return tinted
-/mob/living/carbon/human/IsAdvancedToolUser()
- return 1//Humans can use guns and such
-
/mob/living/carbon/human/abiotic(var/full_body = 0)
if(full_body && ((src.l_hand && !(src.l_hand.flags & ABSTRACT)) || (src.r_hand && !(src.r_hand.flags & ABSTRACT)) || (src.back || src.wear_mask || src.head || src.shoes || src.w_uniform || src.wear_suit || src.glasses || src.l_ear || src.r_ear || src.gloves)))
@@ -1690,4 +1687,12 @@
return 1
/mob/living/carbon/human/InCritical()
- return (health <= config.health_threshold_crit && stat == UNCONSCIOUS)
\ No newline at end of file
+ return (health <= config.health_threshold_crit && stat == UNCONSCIOUS)
+
+
+/mob/living/carbon/human/IsAdvancedToolUser(var/silent)
+ if(species.has_fine_manipulation)
+ return 1
+ if(!silent)
+ src << "You don't have the dexterity to use that!"
+ return 0
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/species/monkey.dm b/code/modules/mob/living/carbon/human/species/monkey.dm
index 97c57a1af47..05611d7ffa4 100644
--- a/code/modules/mob/living/carbon/human/species/monkey.dm
+++ b/code/modules/mob/living/carbon/human/species/monkey.dm
@@ -11,7 +11,8 @@
default_language = "Chimpanzee"
greater_form = "Human"
is_small = 1
- //has_fine_manipulation = 0
+ has_fine_manipulation = 0
+ ventcrawler = 1
show_ssd = 0
eyes = "blank_eyes"
diff --git a/code/modules/mob/living/carbon/species.dm b/code/modules/mob/living/carbon/species.dm
index 3b2f9d0edf7..793bf21f290 100644
--- a/code/modules/mob/living/carbon/species.dm
+++ b/code/modules/mob/living/carbon/species.dm
@@ -56,6 +56,7 @@
var/list/default_genes = list()
var/ventcrawler = 0 //Determines if the mob can go through the vents.
+ var/has_fine_manipulation = 1 // Can use small items.
var/flags = 0 // Various specific features.
var/bloodflags=0
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 6d0b1768f03..095d7af1436 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -321,3 +321,6 @@
if ("Disable")
sensor_mode = 0
src << "Sensor augmentations disabled."
+
+/mob/living/silicon/IsAdvancedToolUser()
+ return 1
\ No newline at end of file
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index ff73ff13259..0d766fa162b 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -1492,4 +1492,4 @@ mob/proc/yank_out_object()
return
/mob/proc/handle_ventcrawl()
- return // Only living mobs can ventcrawl
\ No newline at end of file
+ return // Only living mobs can ventcrawl
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index 889d2f47f62..a6553a6f4fc 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -811,6 +811,8 @@
return 0
if(!user.client)
return 0
+ if(!user.IsAdvancedToolUser())
+ return 0
if ( ! (istype(user, /mob/living/carbon/human) || \
istype(user, /mob/living/silicon)))
user << "\red You don't have the dexterity to use this [src]!"
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 9d9fef8e0bc..87cf5df27df 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -56,6 +56,8 @@
proc/special_check(var/mob/M) //Placeholder for any special checks, like detective's revolver.
+ if(!usr.IsAdvancedToolUser())
+ return 0
return 1
diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm
index 0eb8dbafd3f..4bb71244045 100644
--- a/code/modules/recycling/disposal.dm
+++ b/code/modules/recycling/disposal.dm
@@ -212,22 +212,19 @@
// human interact with machine
attack_hand(mob/user as mob)
+ if(stat & BROKEN)
+ return
+
if(user && user.loc == src)
usr << "\red You cannot reach the controls from inside."
return
- /*
- if(mode==-1)
- usr << "\red The disposal units power is disabled."
- return
- */
- interact(user, 0)
- // hostile mob escape from disposals
- attack_animal(var/mob/living/simple_animal/M)
- if(M.environment_smash)
- M.do_attack_animation(src)
- visible_message("[M.name] smashes \the [src] apart!")
- qdel(src)
+ // Clumsy folks can only flush it.
+ if(user.IsAdvancedToolUser(1))
+ interact(user, 0)
+ else
+ flush = !flush
+ update()
return
// user interaction
diff --git a/code/modules/security levels/keycard authentication.dm b/code/modules/security levels/keycard authentication.dm
index b2cf9c268ed..97bca316a2d 100644
--- a/code/modules/security levels/keycard authentication.dm
+++ b/code/modules/security levels/keycard authentication.dm
@@ -52,6 +52,8 @@
stat |= NOPOWER
/obj/machinery/keycard_auth/attack_hand(mob/user as mob)
+ if(!user.IsAdvancedToolUser())
+ return 0
ui_interact(user)
/obj/machinery/keycard_auth/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)