diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index 5e22e9dc238..5ce2c45551f 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -817,6 +817,55 @@
dispenser = 1
+/obj/item/weapon/legcuffs
+ name = "legcuffs"
+ desc = "Use this to keep prisoners in line."
+ gender = PLURAL
+ icon = 'icons/obj/items.dmi'
+ icon_state = "handcuff"
+ flags = FPRINT | TABLEPASS | CONDUCT
+ throwforce = 0
+ w_class = 3.0
+ throw_speed = 2
+ throw_range = 0 //cannot be thrown
+ origin_tech = "materials=1"
+ var/breakouttime = 300 //Deciseconds = 30s = 0.5 minute
+
+/obj/item/weapon/legcuffs/beartrap
+ name = "beartrap"
+ desc = "A trap used to catch bears and other legged creatures."
+ breakouttime = 300 //Deciseconds = 30s = 0.5 minute
+ var/armed = 0
+
+/obj/item/weapon/legcuffs/beartrap/verb/arm()
+ set name = "Arm"
+ set category = "Object"
+
+ if(ishuman(usr) && !usr.stat && !usr.restrained())
+ armed = !armed
+ usr << "\blue \the [src] is now [(armed)?"armed":"disarmed"]"
+
+/obj/item/weapon/legcuffs/beartrap/HasEntered(AM as mob|obj)
+ if(armed)
+ if(ishuman(AM))
+ if(isturf(src.loc))
+ var/mob/living/carbon/H = AM
+ if(H.m_intent == "run")
+ armed = 0
+ usr.legcuffed = src
+ src.loc = usr
+ usr.update_inv_legcuffed()
+ H << "\red You step on \the [src]!"
+ for(var/mob/O in viewers(H, null))
+ if(O == H)
+ continue
+ O.show_message("\red [H] steps on \the [src].", 1)
+ if(isanimal(AM))
+ armed = 0
+ var/mob/living/simple_animal/SA = AM
+ SA.health = 0
+ ..()
+
/obj/item/weapon/locator
name = "locator"
desc = "Used to track those with locater implants."
diff --git a/code/game/magic/cultist/runes.dm b/code/game/magic/cultist/runes.dm
index 717117e038c..893717d067a 100644
--- a/code/game/magic/cultist/runes.dm
+++ b/code/game/magic/cultist/runes.dm
@@ -749,6 +749,10 @@ var/list/sacrificed = list()
cultist.handcuffed.loc = cultist.loc
cultist.handcuffed = null
cultist.update_inv_handcuffed()
+ if (cultist.legcuffed)
+ cultist.legcuffed.loc = cultist.loc
+ cultist.legcuffed = null
+ cultist.update_inv_legcuffed()
if (istype(cultist.wear_mask, /obj/item/clothing/mask/muzzle))
cultist.u_equip(cultist.wear_mask)
if(istype(cultist.loc, /obj/structure/closet)&&cultist.loc:welded)
diff --git a/code/game/objects/items/weapons/implants/implantfreedom.dm b/code/game/objects/items/weapons/implants/implantfreedom.dm
index f95a055eb6d..9b6f41698bd 100644
--- a/code/game/objects/items/weapons/implants/implantfreedom.dm
+++ b/code/game/objects/items/weapons/implants/implantfreedom.dm
@@ -31,6 +31,17 @@
dropped(source)
if (W)
W.layer = initial(W.layer)
+ if (source.legcuffed)
+ var/obj/item/weapon/W = source.legcuffed
+ source.legcuffed = null
+ source.update_inv_legcuffed()
+ if (source.client)
+ source.client.screen -= W
+ if (W)
+ W.loc = source.loc
+ dropped(source)
+ if (W)
+ W.layer = initial(W.layer)
return
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index 099a0f2c3eb..804a969b50b 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -158,6 +158,9 @@
else if (W == handcuffed)
handcuffed = null
update_inv_handcuffed()
+ else if (W == legcuffed)
+ legcuffed = null
+ update_inv_legcuffed()
else if (W == back)
back = null
update_inv_back()
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 6e714773286..925cdb0f123 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -470,6 +470,7 @@
ID: [(wear_id ? wear_id : "Nothing")]
Suit Storage: [(s_store ? s_store : "Nothing")]
[(handcuffed ? text("Handcuffed") : text("Not Handcuffed"))]
+
[(legcuffed ? text("Legcuffed") : text(""))]
[(internal ? text("Remove Internal") : "")]
Empty Pockets
Refresh
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index b46e2116cb3..6353eb59446 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -18,6 +18,7 @@
var/const/slot_r_store = 16
var/const/slot_s_store = 17
var/const/slot_in_backpack = 18
+ var/const/slot_legcuffed = 19
/mob/living/carbon/human/proc/equip_in_one_of_slots(obj/item/W, list/slots, del_on_fail = 1)
for (var/slot in slots)
@@ -175,6 +176,11 @@
src.handcuffed = W
update_inv_handcuffed(0)
equipped = 1
+ if(slot_legcuffed)
+ if(!src.legcuffed)
+ src.legcuffed = W
+ update_inv_legcuffed(0)
+ equipped = 1
if(slot_l_hand)
if(!src.l_hand)
src.l_hand = W
@@ -360,6 +366,9 @@
else if (W == handcuffed)
handcuffed = null
update_inv_handcuffed(0)
+ else if (W == legcuffed)
+ legcuffed = null
+ update_inv_legcuffed(0)
else if (W == r_hand)
r_hand = null
update_inv_r_hand(0)
@@ -502,6 +511,8 @@
message = text("\red [] is trying to take off \a [] from []'s back!", source, target.back, target)
if("handcuff")
message = text("\red [] is trying to unhandcuff []!", source, target)
+ if("legcuff")
+ message = text("\red [] is trying to unlegcuff []!", source, target)
if("uniform")
if(istype(target.w_uniform, /obj/item/clothing)&&!target.w_uniform:canremove)
message = text("\red [] fails to take off \a [] from []'s body!", source, target.w_uniform, target)
@@ -926,6 +937,23 @@ It can still be worn/put on as normal.
target.handcuffed = item
item.loc = target
target.update_inv_handcuffed(0)
+ if("legcuff")
+ if (target.legcuffed)
+ var/obj/item/W = target.legcuffed
+ target.u_equip(W)
+ if (target.client)
+ target.client.screen -= W
+ if (W)
+ W.loc = target.loc
+ W.dropped(target)
+ W.layer = initial(W.layer)
+ W.add_fingerprint(source)
+ else
+ if (istype(item, /obj/item/weapon/legcuffs))
+ source.drop_item()
+ target.legcuffed = item
+ item.loc = target
+ target.update_inv_legcuffed(0)
if("CPR")
if (target.cpr_time >= world.time + 30)
//SN src = null
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 91a75859a08..b668dd0c018 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -113,9 +113,10 @@ Please contact me on #coderbus IRC. ~Carn x
#define FACEMASK_LAYER 15
#define HEAD_LAYER 16
#define HANDCUFF_LAYER 17
-#define L_HAND_LAYER 18
-#define R_HAND_LAYER 19
-#define TOTAL_LAYERS 19
+#define LEGCUFF_LAYER 18
+#define L_HAND_LAYER 19
+#define R_HAND_LAYER 20
+#define TOTAL_LAYERS 20
//////////////////////////////////
/mob/living/carbon/human
@@ -340,6 +341,7 @@ Please contact me on #coderbus IRC. ~Carn x
update_inv_r_hand(0)
update_inv_l_hand(0)
update_inv_handcuffed(0)
+ update_inv_legcuffed(0)
update_inv_pockets(0)
update_icons()
//Hud Stuff
@@ -592,6 +594,20 @@ Please contact me on #coderbus IRC. ~Carn x
overlays_standing[HANDCUFF_LAYER] = null
if(update_icons) update_icons()
+/mob/living/carbon/human/update_inv_legcuffed(var/update_icons=1)
+ if(legcuffed)
+ overlays_lying[LEGCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "legcuff2")
+ overlays_standing[LEGCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "legcuff1")
+ if(src.m_intent != "walk")
+ src.m_intent = "walk"
+ if(src.hud_used && src.hud_used.move_intent)
+ src.hud_used.move_intent.icon_state = "walking"
+
+ else
+ overlays_lying[LEGCUFF_LAYER] = null
+ overlays_standing[LEGCUFF_LAYER] = null
+ if(update_icons) update_icons()
+
/mob/living/carbon/human/update_inv_r_hand(var/update_icons=1)
if(r_hand)
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index dc9d14e1374..e06d6a3fa2d 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -111,7 +111,8 @@
var/lastDblClick = 0
var/lastKnownIP = null
var/obj/structure/stool/bed/buckled = null//Living
- var/obj/item/weapon/handcuffs/handcuffed = null//Living
+ var/obj/item/handcuffed = null//Living
+ var/obj/item/legcuffed = null//Living
var/obj/item/l_hand = null//Living
var/obj/item/r_hand = null//Living
var/obj/item/weapon/back = null//Human/Monkey
diff --git a/code/modules/mob/screen.dm b/code/modules/mob/screen.dm
index 8c30f773321..e3578dc9652 100644
--- a/code/modules/mob/screen.dm
+++ b/code/modules/mob/screen.dm
@@ -318,6 +318,11 @@
usr.hud_used.action_intent.icon_state = "help"
if("mov_intent")
+ if(usr.legcuffed)
+ usr << "\red You are legcuffed! You cannot run until you get your cuffs removed!"
+ usr.m_intent = "walk" //Just incase
+ usr.hud_used.move_intent.icon_state = "walking"
+ return
switch(usr.m_intent)
if("run")
usr.m_intent = "walk"
@@ -702,4 +707,41 @@
CM << "\blue You successfully remove \the [CM.handcuffed]."
CM.handcuffed.loc = usr.loc
CM.handcuffed = null
- CM.update_inv_handcuffed()
\ No newline at end of file
+ CM.update_inv_handcuffed()
+ else if(CM.legcuffed && CM.canmove && (CM.last_special <= world.time))
+ CM.next_move = world.time + 100
+ CM.last_special = world.time + 100
+ if(isalienadult(CM) || (HULK in usr.mutations) || (SUPRSTR in CM.augmentations))//Don't want to do a lot of logic gating here.
+ usr << "\green You attempt to break your legcuffs. (This will take around 5 seconds and you need to stand still)"
+ for(var/mob/O in viewers(CM))
+ O.show_message(text("\red [] is trying to break the legcuffs!", CM), 1)
+ spawn(0)
+ if(do_after(CM, 50))
+ if(!CM.legcuffed || CM.buckled)
+ return
+ for(var/mob/O in viewers(CM))
+ O.show_message(text("\red [] manages to break the legcuffs!", CM), 1)
+ CM << "\green You successfully break your legcuffs."
+ del(CM.legcuffed)
+ CM.legcuffed = null
+ CM.update_inv_legcuffed()
+ else
+ var/obj/item/weapon/legcuffs/HC = CM.legcuffed
+ var/breakouttime = 1200 //A default in case you are somehow legcuffed with something that isn't an obj/item/weapon/legcuffs type
+ var/displaytime = 2 //Minutes to display in the "this will take X minutes."
+ if(istype(HC)) //If you are legcuffed with actual legcuffs... Well what do I know, maybe someone will want to legcuff you with toilet paper in the future...
+ breakouttime = HC.breakouttime
+ displaytime = breakouttime / 600 //Minutes
+ CM << "\red You attempt to remove \the [HC]. (This will take around [displaytime] minutes and you need to stand still)"
+ for(var/mob/O in viewers(CM))
+ O.show_message( "\red [usr] attempts to remove \the [HC]!", 1)
+ spawn(0)
+ if(do_after(CM, breakouttime))
+ if(!CM.legcuffed || CM.buckled)
+ return // time leniency for lag which also might make this whole thing pointless but the server
+ for(var/mob/O in viewers(CM))// lags so hard that 40s isn't lenient enough - Quarxink
+ O.show_message("\red [CM] manages to remove the legcuffs!", 1)
+ CM << "\blue You successfully remove \the [CM.legcuffed]."
+ CM.legcuffed.loc = usr.loc
+ CM.legcuffed = null
+ CM.update_inv_legcuffed()
\ No newline at end of file
diff --git a/code/modules/mob/update_icons.dm b/code/modules/mob/update_icons.dm
index 64f2a2fdf71..252439277c5 100644
--- a/code/modules/mob/update_icons.dm
+++ b/code/modules/mob/update_icons.dm
@@ -13,6 +13,9 @@
/mob/proc/update_inv_handcuffed()
return
+/mob/proc/update_inv_legcuffed()
+ return
+
/mob/proc/update_inv_back()
return
diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi
index f4222078300..32128cf1951 100644
Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ