Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Legcuffs work #5696

Merged
merged 10 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion code/game/machinery/autolathe_datums.dm
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@

/datum/autolathe/recipe/handcuffs
name = "handcuffs"
path = /obj/item/handcuffs
path = /obj/item/restraint/handcuffs
hidden = TRUE
category = AUTOLATHE_CATEGORY_GENERAL

Expand Down
7 changes: 4 additions & 3 deletions code/game/machinery/vending/vending_types.dm
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,9 @@
icon_deny = "sec-deny"
req_access = list(ACCESS_MARINE_BRIG)
products = list(
/obj/item/handcuffs = 8,
/obj/item/handcuffs/zip = 10,
/obj/item/restraint/handcuffs = 8,
/obj/item/restraint/handcuffs/zip = 10,
/obj/item/restraint/legcuffs = 3,
/obj/item/explosive/grenade/flashbang = 4,
/obj/item/weapon/gun/energy/taser = 4,
/obj/item/reagent_container/spray/pepper = 4,
Expand Down Expand Up @@ -263,7 +264,7 @@
hacking_safety = TRUE
wrenchable = FALSE
products = list(
/obj/item/handcuffs/zip = 40,
/obj/item/restraint/handcuffs/zip = 40,
/obj/item/explosive/grenade/flashbang = 20,
/obj/item/explosive/grenade/custom/teargas = 40,
/obj/item/ammo_magazine/smg/m39/rubber = 40,
Expand Down
4 changes: 2 additions & 2 deletions code/game/objects/items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -664,13 +664,13 @@ cases. Override_icon_state should be a list.*/
if(WEAR_HANDCUFFS)
if(human.handcuffed)
return FALSE
if(!istype(src, /obj/item/handcuffs))
if(!istype(src, /obj/item/restraint))
return FALSE
return TRUE
if(WEAR_LEGCUFFS)
if(human.legcuffed)
return FALSE
if(!istype(src, /obj/item/legcuffs))
if(!istype(src, /obj/item/restraint))
return FALSE
return TRUE
if(WEAR_IN_ACCESSORY)
Expand Down
195 changes: 114 additions & 81 deletions code/game/objects/items/handcuffs.dm
Original file line number Diff line number Diff line change
@@ -1,124 +1,162 @@
/obj/item/handcuffs
name = "handcuffs"
desc = "Use this to keep prisoners in line."
gender = PLURAL
icon = 'icons/obj/items/items.dmi'
icon_state = "handcuff"
flags_atom = FPRINT|CONDUCT
flags_equip_slot = SLOT_WAIST
throwforce = 5
w_class = SIZE_SMALL
throw_speed = SPEED_SLOW
throw_range = 5
matter = list("metal" = 500)

var/dispenser = 0
/obj/item/restraint
/// SLOT_HANDS or SLOT_LEGS, for handcuffs or legcuffs
var/target_zone = SLOT_HANDS
/// How long to break out
var/breakouttime = 1 MINUTES
/// determines if handcuffs will be deleted on removal
var/single_use = 0
var/cuff_sound = 'sound/weapons/handcuffs.ogg'
/// how many deciseconds it takes to cuff someone
var/cuff_delay = 4 SECONDS
/// If can be applied to people manually
var/manual = TRUE

/obj/item/handcuffs/attack(mob/living/carbon/C, mob/user)
if(!istype(C))
/obj/item/restraint/attack(mob/living/carbon/attacked_carbon, mob/user)
if(!istype(attacked_carbon) || !manual)
return ..()
if (!istype(user, /mob/living/carbon/human))
if (!ishuman(user))
to_chat(user, SPAN_DANGER("You don't have the dexterity to do this!"))
return
if(!C.handcuffed)
place_handcuffs(C, user)

/obj/item/handcuffs/get_mob_overlay(mob/user_mob, slot)
var/image/ret = ..()

var/image/handcuffs = overlay_image('icons/mob/mob.dmi', "handcuff1", color, RESET_COLOR)
ret.overlays += handcuffs

return ret

/obj/item/handcuffs/proc/place_handcuffs(mob/living/carbon/target, mob/user)
switch(target_zone)
if(SLOT_HANDS)
if(!attacked_carbon.handcuffed)
place_handcuffs(attacked_carbon, user)
if(SLOT_LEGS)
if(!attacked_carbon.legcuffed)
apply_legcuffs(attacked_carbon, user)

/obj/item/restraint/proc/place_handcuffs(mob/living/carbon/target, mob/user)
playsound(src.loc, cuff_sound, 25, 1, 4)

if(user.action_busy)
return

if (ishuman(target))
var/mob/living/carbon/human/H = target
if(ishuman(target))
var/mob/living/carbon/human/human_mob = target

if (!H.has_limb_for_slot(WEAR_HANDCUFFS))
to_chat(user, SPAN_DANGER("\The [H] needs at least two wrists before you can cuff them together!"))
if(!human_mob.has_limb_for_slot(WEAR_HANDCUFFS))
to_chat(user, SPAN_DANGER("\The [human_mob] needs at least two wrists before you can cuff them together!"))
return

H.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been handcuffed (attempt) by [key_name(user)]</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to handcuff [key_name(H)]</font>")
msg_admin_attack("[key_name(user)] attempted to handcuff [key_name(H)] in [get_area(src)] ([src.loc.x],[src.loc.y],[src.loc.z]).", src.loc.x, src.loc.y, src.loc.z)
human_mob.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been handcuffed (attempt) by [key_name(user)]</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to handcuff [key_name(human_mob)]</font>")
msg_admin_attack("[key_name(user)] attempted to handcuff [key_name(human_mob)] in [get_area(src)] ([loc.x],[loc.y],[loc.z]).", loc.x, loc.y, loc.z)

user.visible_message(SPAN_NOTICE("[user] tries to put [src] on [H]."))
if(do_after(user, cuff_delay, INTERRUPT_MOVED, BUSY_ICON_HOSTILE, H, INTERRUPT_MOVED, BUSY_ICON_GENERIC))
if(src == user.get_active_hand() && !H.handcuffed && Adjacent(user))
if(iscarbon(H))
if(istype(H.buckled, /obj/structure/bed/roller))
user.visible_message(SPAN_NOTICE("[user] tries to put [src] on [human_mob]."))
if(do_after(user, cuff_delay, INTERRUPT_MOVED, BUSY_ICON_HOSTILE, human_mob, INTERRUPT_MOVED, BUSY_ICON_GENERIC))
if(src == user.get_active_hand() && !human_mob.handcuffed && Adjacent(user))
if(iscarbon(human_mob))
if(istype(human_mob.buckled, /obj/structure/bed/roller))
to_chat(user, SPAN_DANGER("You cannot handcuff someone who is buckled onto a roller bed."))
return
if(H.has_limb_for_slot(WEAR_HANDCUFFS))
if(human_mob.has_limb_for_slot(WEAR_HANDCUFFS))
user.drop_inv_item_on_ground(src)
H.equip_to_slot_if_possible(src, WEAR_HANDCUFFS, 1, 0, 1, 1)
human_mob.equip_to_slot_if_possible(src, WEAR_HANDCUFFS, 1, 0, 1, 1)
user.count_niche_stat(STATISTICS_NICHE_HANDCUFF)

else if (ismonkey(target))
else if(ismonkey(target))
user.visible_message(SPAN_NOTICE("[user] tries to put [src] on [target]."))
if(do_after(user, 30, INTERRUPT_MOVED, BUSY_ICON_HOSTILE, target, INTERRUPT_MOVED, BUSY_ICON_GENERIC))
if(src == user.get_active_hand() && !target.handcuffed && Adjacent(user))
user.drop_inv_item_on_ground(src)
target.equip_to_slot_if_possible(src, WEAR_HANDCUFFS, 1, 0, 1, 1)

/obj/item/restraint/handcuffs
name = "handcuffs"
desc = "Use this to keep prisoners in line."
gender = PLURAL
icon = 'icons/obj/items/items.dmi'
icon_state = "handcuff"
flags_atom = FPRINT|CONDUCT
flags_equip_slot = SLOT_WAIST
throwforce = 5
w_class = SIZE_SMALL
throw_speed = SPEED_SLOW
throw_range = 5
matter = list("metal" = 500)

/obj/item/restraint/handcuffs/get_mob_overlay(mob/user_mob, slot)
var/image/ret = ..()

var/image/handcuffs = overlay_image('icons/mob/mob.dmi', "handcuff1", color, RESET_COLOR)
ret.overlays += handcuffs

return ret

/obj/item/handcuffs/zip
/obj/item/restraint/handcuffs/zip
name = "zip cuffs"
desc = "Single-use plastic zip tie handcuffs."
w_class = SIZE_TINY
icon_state = "cuff_zip"
breakouttime = 600 //Deciseconds = 60s
breakouttime = 60 SECONDS
cuff_sound = 'sound/weapons/cablecuff.ogg'
cuff_delay = 20

/obj/item/handcuffs/zip/place_handcuffs(mob/living/carbon/target, mob/user)
/obj/item/restraint/handcuffs/zip/place_handcuffs(mob/living/carbon/target, mob/user)
..()
flags_item |= DELONDROP

/obj/item/handcuffs/cable
/obj/item/restraint/adjustable/verb/adjust_restraints()
set category = "Object"
set name = "Adjust Restraints"
set desc = "Adjust the restraint size for wrists or ankles."
set src = usr.contents

if(!ishuman(usr))
return FALSE

if(usr.is_mob_incapacitated())
to_chat(usr, "Not right now.")
return FALSE

switch(target_zone)
if(SLOT_HANDS)
target_zone = SLOT_LEGS
to_chat(usr, SPAN_NOTICE("[src] has been adjusted to tie around a subject's ankles."))
if(SLOT_LEGS)
target_zone = SLOT_HANDS
to_chat(usr, SPAN_NOTICE("[src] has been adjusted to tie around a subject's wrists."))

/obj/item/restraint/adjustable/get_examine_text(mob/user)
. = ..()
switch(target_zone)
if(SLOT_HANDS)
. += SPAN_RED("Sized for human hands.")
if(SLOT_LEGS)
. += SPAN_RED("Sized for human ankles.")

/obj/item/restraint/adjustable/cable
name = "cable restraints"
desc = "Looks like some cables tied together. Could be used to tie something up."
icon_state = "cuff_white"
breakouttime = 300 //Deciseconds = 30s
breakouttime = 30 SECONDS
cuff_sound = 'sound/weapons/cablecuff.ogg'

/obj/item/handcuffs/cable/red
/obj/item/restraint/adjustable/cable/red
color = "#DD0000"

/obj/item/handcuffs/cable/yellow
/obj/item/restraint/adjustable/cable/yellow
color = "#DDDD00"

/obj/item/handcuffs/cable/blue
/obj/item/restraint/adjustable/cable/blue
color = "#0000DD"

/obj/item/handcuffs/cable/green
/obj/item/restraint/adjustable/cable/green
color = "#00DD00"

/obj/item/handcuffs/cable/pink
/obj/item/restraint/adjustable/cable/pink
color = "#DD00DD"

/obj/item/handcuffs/cable/orange
/obj/item/restraint/adjustable/cable/orange
color = "#DD8800"

/obj/item/handcuffs/cable/cyan
/obj/item/restraint/adjustable/cable/cyan
color = "#00DDDD"

/obj/item/handcuffs/cable/white
/obj/item/restraint/adjustable/cable/white
color = "#FFFFFF"

/obj/item/handcuffs/cable/attackby(obj/item/I, mob/user as mob)
/obj/item/restraint/adjustable/cable/attackby(obj/item/I, mob/user as mob)
..()
if(istype(I, /obj/item/stack/rods))
var/obj/item/stack/rods/R = I
Expand All @@ -130,34 +168,30 @@
qdel(src)
update_icon(user)


/obj/item/handcuffs/cyborg
dispenser = 1

/obj/item/handcuffs/cyborg/attack(mob/living/carbon/C as mob, mob/user as mob)
if(!C.handcuffed)
/obj/item/restraint/handcuffs/cyborg/attack(mob/living/carbon/carbon_mob as mob, mob/user as mob)
if(!carbon_mob.handcuffed)
var/turf/p_loc = user.loc
var/turf/p_loc_m = C.loc
playsound(src.loc, cuff_sound, 25, 1, 4)
user.visible_message(SPAN_DANGER("<B>[user] is trying to put handcuffs on [C]!</B>"))

if (ishuman(C))
var/mob/living/carbon/human/H = C
if (!H.has_limb_for_slot(WEAR_HANDCUFFS))
to_chat(user, SPAN_DANGER("\The [H] needs at least two wrists before you can cuff them together!"))
var/turf/p_loc_m = carbon_mob.loc
playsound(loc, cuff_sound, 25, 1, 4)
user.visible_message(SPAN_DANGER("<B>[user] is trying to put handcuffs on [carbon_mob]!</B>"))

if(ishuman(carbon_mob))
var/mob/living/carbon/human/human_mob = carbon_mob
if (!human_mob.has_limb_for_slot(WEAR_HANDCUFFS))
to_chat(user, SPAN_DANGER("\The [human_mob] needs at least two wrists before you can cuff them together!"))
return

spawn(30)
if(!C) return
if(p_loc == user.loc && p_loc_m == C.loc)
C.handcuffed = new /obj/item/handcuffs(C)
C.handcuff_update()
if(!carbon_mob) return
if(p_loc == user.loc && p_loc_m == carbon_mob.loc)
carbon_mob.handcuffed = new /obj/item/restraint/handcuffs(carbon_mob)
carbon_mob.handcuff_update()





/obj/item/restraints
/obj/item/xeno_restraints
name = "xeno restraints"
desc = "Use this to hold xenomorphic creatures safely."
gender = PLURAL
Expand All @@ -171,10 +205,9 @@
throw_range = 5
matter = list("metal" = 500)

var/dispenser = 0
var/breakouttime = 2 MINUTES

/obj/item/restraints/attack(mob/living/carbon/C as mob, mob/user as mob)
/obj/item/xeno_restraints/attack(mob/living/carbon/C as mob, mob/user as mob)
if(!istype(C, /mob/living/carbon/xenomorph))
to_chat(user, SPAN_DANGER("The cuffs do not fit!"))
return
Expand All @@ -187,7 +220,7 @@
spawn(30)
if(!C) return
if(p_loc == user.loc && p_loc_m == C.loc)
C.handcuffed = new /obj/item/restraints(C)
C.handcuffed = new /obj/item/xeno_restraints(C)
C.handcuff_update()
C.visible_message(SPAN_DANGER("[C] has been successfully restrained by [user]!"))
qdel(src)
Expand Down
Loading
Loading