diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index 8bfe71121d..c40c5db48c 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -173,19 +173,6 @@
item_state = "gift"
w_class = ITEMSIZE_LARGE
-/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 = CONDUCT
- throwforce = 0
- w_class = ITEMSIZE_NORMAL
- origin_tech = list(TECH_MATERIAL = 1)
- var/breakouttime = 300 //Deciseconds = 30s = 0.5 minute
- sprite_sheets = list("Teshari" = 'icons/mob/species/seromi/handcuffs.dmi')
-
/obj/item/weapon/caution
desc = "Caution! Wet Floor!"
name = "wet floor sign"
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 4ca9703301..6b4a09c6a5 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -343,12 +343,12 @@ var/list/global/slot_flags_enumeration = list(
return 0
if( !(istype(src, /obj/item/device/pda) || istype(src, /obj/item/weapon/pen) || is_type_in_list(src, H.wear_suit.allowed)) )
return 0
+ if(slot_legcuffed) //Going to put this check above the handcuff check because the survival of the universe depends on it.
+ if(!istype(src, /obj/item/weapon/handcuffs/legcuffs)) //Putting it here might actually do nothing.
+ return 0
if(slot_handcuffed)
- if(!istype(src, /obj/item/weapon/handcuffs))
- return 0
- if(slot_legcuffed)
- if(!istype(src, /obj/item/weapon/legcuffs))
- return 0
+ if(!istype(src, /obj/item/weapon/handcuffs) || istype(src, /obj/item/weapon/handcuffs/legcuffs)) //Legcuffs are a child of handcuffs, but we don't want to use legcuffs as handcuffs...
+ return 0 //In theory, this would never happen, but let's just do the legcuff check anyways.
if(slot_in_backpack) //used entirely for equipping spawned mobs or at round start
var/allow = 0
if(H.back && istype(H.back, /obj/item/weapon/storage/backpack))
diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm
index 62941c24f0..d86b534243 100644
--- a/code/game/objects/items/weapons/handcuffs.dm
+++ b/code/game/objects/items/weapons/handcuffs.dm
@@ -181,3 +181,84 @@ var/last_chew = 0
icon = 'icons/obj/bureaucracy.dmi'
breakouttime = 200
cuff_type = "duct tape"
+
+//Legcuffs. Not /really/ handcuffs, but its close enough.
+/obj/item/weapon/handcuffs/legcuffs
+ name = "legcuffs"
+ desc = "Use this to keep prisoners in line."
+ gender = PLURAL
+ icon = 'icons/obj/items.dmi'
+ icon_state = "handcuff"
+ flags = CONDUCT
+ throwforce = 0
+ w_class = ITEMSIZE_NORMAL
+ origin_tech = list(TECH_MATERIAL = 1)
+ breakouttime = 300 //Deciseconds = 30s = 0.5 minute
+ cuff_type = "legcuffs"
+ sprite_sheets = list("Teshari" = 'icons/mob/species/seromi/handcuffs.dmi')
+ elastic = 0
+ cuff_sound = 'sound/weapons/handcuffs.ogg' //This shold work for now.
+
+/obj/item/weapon/handcuffs/legcuffs/attack(var/mob/living/carbon/C, var/mob/living/user)
+ if(!user.IsAdvancedToolUser())
+ return
+
+ if ((CLUMSY in user.mutations) && prob(50))
+ user << "Uh ... how do those things work?!"
+ place_legcuffs(user, user)
+ return
+
+ if(!C.handcuffed)
+ if (C == user)
+ place_legcuffs(user, user)
+ return
+
+ //check for an aggressive grab (or robutts)
+ if(can_place(C, user))
+ place_legcuffs(C, user)
+ else
+ user << "You need to have a firm grip on [C] before you can put \the [src] on!"
+
+/obj/item/weapon/handcuffs/legcuffs/proc/place_legcuffs(var/mob/living/carbon/target, var/mob/user)
+ playsound(src.loc, cuff_sound, 30, 1, -2)
+
+ var/mob/living/carbon/human/H = target
+ if(!istype(H))
+ return 0
+
+ if (!H.has_organ_for_slot(slot_legcuffed))
+ user << "\The [H] needs at least two ankles before you can cuff them together!"
+ return 0
+
+ if(istype(H.shoes,/obj/item/clothing/shoes/magboots/rig) && !elastic) // Can't cuff someone who's in a deployed hardsuit.
+ user << "\The [src] won't fit around \the [H.gloves]!"
+ return 0
+
+ user.visible_message("\The [user] is attempting to put [cuff_type] on \the [H]!")
+
+ if(!do_after(user,30))
+ return 0
+
+ if(!can_place(target, user)) //victim may have resisted out of the grab in the meantime
+ return 0
+
+ H.attack_log += text("\[[time_stamp()]\] Has been legcuffed (attempt) by [user.name] ([user.ckey])")
+ user.attack_log += text("\[[time_stamp()]\] Attempted to legcuff [H.name] ([H.ckey])")
+ msg_admin_attack("[key_name(user)] attempted to legcuff [key_name(H)]")
+ feedback_add_details("legcuffs","H")
+
+ user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
+ user.do_attack_animation(H)
+
+ user.visible_message("\The [user] has put [cuff_type] on \the [H]!")
+
+ // Apply cuffs.
+ var/obj/item/weapon/handcuffs/legcuffs/lcuffs = src
+ if(dispenser)
+ lcuffs = new(get_turf(user))
+ else
+ user.drop_from_inventory(lcuffs)
+ lcuffs.loc = target
+ target.legcuffed = lcuffs
+ target.update_inv_legcuffed()
+ return 1
\ No newline at end of file
diff --git a/code/game/objects/random/random.dm b/code/game/objects/random/random.dm
index 4da7cc6aeb..f79b6be0ae 100644
--- a/code/game/objects/random/random.dm
+++ b/code/game/objects/random/random.dm
@@ -208,7 +208,7 @@
prob(1);/obj/item/clothing/suit/storage/vest/heavy/merc,
prob(1);/obj/item/weapon/beartrap,
prob(1);/obj/item/weapon/handcuffs,
- prob(1);/obj/item/weapon/legcuffs,
+ prob(1);/obj/item/weapon/handcuffs/legcuffs,
prob(2);/obj/item/weapon/reagent_containers/syringe/drugs,
prob(1);/obj/item/weapon/reagent_containers/syringe/steroid)
diff --git a/code/modules/mob/living/carbon/resist.dm b/code/modules/mob/living/carbon/resist.dm
index ebb16683a8..c82c39732b 100644
--- a/code/modules/mob/living/carbon/resist.dm
+++ b/code/modules/mob/living/carbon/resist.dm
@@ -66,38 +66,43 @@
drop_from_inventory(handcuffed)
/mob/living/carbon/proc/escape_legcuffs()
- if(!canClick())
- return
+ //if(!(last_special <= world.time)) return
+ //This line represent a significant buff to grabs...
+ // We don't have to check the click cooldown because /mob/living/verb/resist() has done it for us, we can simply set the delay
setClickCooldown(100)
if(can_break_cuffs()) //Don't want to do a lot of logic gating here.
break_legcuffs()
return
- var/obj/item/weapon/legcuffs/HC = legcuffed
+ var/obj/item/weapon/handcuffs/legcuffs/LC = legcuffed
- //A default in case you are somehow legcuffed with something that isn't an obj/item/weapon/legcuffs type
+ //A default in case you are somehow handcuffed with something that isn't an obj/item/weapon/handcuffs type
var/breakouttime = 1200
var/displaytime = 2 //Minutes to display in the "this will take X minutes."
- //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...
- if(istype(HC))
- breakouttime = HC.breakouttime
+ //If you are handcuffed with actual handcuffs... Well what do I know, maybe someone will want to handcuff you with toilet paper in the future...
+ if(istype(LC))
+ breakouttime = LC.breakouttime
displaytime = breakouttime / 600 //Minutes
+ var/mob/living/carbon/human/H = src
+ if(istype(H) && H.shoes && istype(H.shoes,/obj/item/clothing/shoes/magboots/rig))
+ breakouttime /= 2
+ displaytime /= 2
+
visible_message(
- "[usr] attempts to remove \the [HC]!",
- "You attempt to remove \the [HC]. (This will take around [displaytime] minutes and you need to stand still)"
+ "\The [src] attempts to remove \the [LC]!",
+ "You attempt to remove \the [LC]. (This will take around [displaytime] minutes and you need to stand still)"
)
- if(do_after(src, breakouttime, incapacitation_flags = INCAPACITATION_DEFAULT & ~INCAPACITATION_RESTRAINED))
- if(!legcuffed || buckled)
+ if(do_after(src, breakouttime, incapacitation_flags = INCAPACITATION_DISABLED & INCAPACITATION_KNOCKDOWN))
+ if(!legcuffed)
return
visible_message(
- "[src] manages to remove \the [legcuffed]!",
+ "\The [src] manages to remove \the [legcuffed]!",
"You successfully remove \the [legcuffed]."
)
-
drop_from_inventory(legcuffed)
legcuffed = null
update_inv_legcuffed()
diff --git a/maps/northern_star/polaris-2.dmm b/maps/northern_star/polaris-2.dmm
index c555be4d81..f35959257b 100644
--- a/maps/northern_star/polaris-2.dmm
+++ b/maps/northern_star/polaris-2.dmm
@@ -2337,7 +2337,7 @@
"SW" = (/obj/structure/table/steel_reinforced,/obj/item/organ/internal/stack,/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station)
"SX" = (/obj/machinery/floodlight,/turf/unsimulated/floor{icon_state = "plating"; name = "plating"},/area/wizard_station)
"SY" = (/turf/space,/obj/structure/shuttle/engine/propulsion,/turf/simulated/shuttle/plating/airless/carry,/area/skipjack_station/start)
-"SZ" = (/obj/structure/table/standard,/obj/item/weapon/legcuffs,/turf/simulated/shuttle/floor/red,/area/skipjack_station/start)
+"SZ" = (/obj/structure/table/standard,/obj/item/weapon/handcuffs/legcuffs,/turf/simulated/shuttle/floor/red,/area/skipjack_station/start)
"Ta" = (/obj/structure/table/standard,/obj/item/weapon/deck/cards,/turf/simulated/shuttle/floor/red,/area/skipjack_station/start)
"Tb" = (/obj/machinery/light/small,/turf/simulated/shuttle/floor/red,/area/skipjack_station/start)
"Tc" = (/obj/structure/table/standard,/obj/item/weapon/surgical/circular_saw{pixel_y = 8},/obj/item/weapon/surgical/hemostat,/obj/item/weapon/surgical/scalpel,/obj/item/stack/medical/advanced/bruise_pack,/turf/simulated/shuttle/floor/red,/area/skipjack_station/start)