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)