mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-20 19:43:13 +01:00
Ports screen alerts from CM13. This enables an immediate reference to whether you are cuffed or buckled. It also provides an easy way to get out of said situation by simply clicking on the alert. <img width="430" height="454" alt="image" src="https://github.com/user-attachments/assets/0c20abf2-0901-49e0-ac29-492ba7c6dbe5" /> ### Asset Licenses The following assets that **have not** been created by myself are included in this PR: | Path | Original Author | License | | --- | --- | --- | | icons/mob/screen_alert.dmi (buckle, succumb) | CM13Devs (CM-13) | CC-BY-SA 3.0 |
254 lines
7.8 KiB
Plaintext
254 lines
7.8 KiB
Plaintext
/obj/item/handcuffs
|
|
name = "handcuffs"
|
|
desc = "Use this to keep prisoners in line."
|
|
gender = PLURAL
|
|
icon = 'icons/obj/handcuffs.dmi'
|
|
icon_state = "handcuff"
|
|
sprite_sheets = list(
|
|
BODYTYPE_VAURCA_BULWARK = 'icons/mob/species/bulwark/cuff.dmi'
|
|
)
|
|
obj_flags = OBJ_FLAG_CONDUCTABLE
|
|
slot_flags = SLOT_BELT
|
|
throwforce = 5
|
|
w_class = WEIGHT_CLASS_SMALL
|
|
throw_speed = 2
|
|
throw_range = 5
|
|
origin_tech = list(TECH_MATERIAL = 1)
|
|
matter = list(DEFAULT_WALL_MATERIAL = 500)
|
|
recyclable = TRUE
|
|
var/legcuff = FALSE
|
|
var/elastic = FALSE
|
|
var/dispenser = 0
|
|
var/breakouttime = 2 MINUTES
|
|
var/cuff_sound = 'sound/weapons/handcuffs.ogg'
|
|
var/cuff_type = "handcuffs"
|
|
drop_sound = 'sound/items/drop/accessory.ogg'
|
|
pickup_sound = 'sound/items/pickup/accessory.ogg'
|
|
|
|
/obj/item/handcuffs/attack(mob/living/target_mob, mob/living/user, target_zone)
|
|
var/mob/living/carbon/C = target_mob
|
|
if(!istype(C))
|
|
return
|
|
|
|
if(!user.IsAdvancedToolUser())
|
|
return
|
|
|
|
if ((user.is_clumsy()) && prob(50))
|
|
to_chat(user, SPAN_WARNING("Uh ... how do those things work?!"))
|
|
place_handcuffs(user, user)
|
|
return
|
|
|
|
if((!legcuff && !C.handcuffed) || (legcuff && !C.legcuffed))
|
|
if (C == user)
|
|
place_handcuffs(user, user)
|
|
return
|
|
|
|
var/can_place
|
|
if(istype(user, /mob/living/silicon/robot))
|
|
can_place = TRUE
|
|
else
|
|
for (var/obj/item/grab/G in C.grabbed_by)
|
|
if (G.state >= GRAB_AGGRESSIVE)
|
|
can_place = TRUE
|
|
break
|
|
|
|
if(can_place)
|
|
place_handcuffs(C, user)
|
|
else
|
|
to_chat(user, SPAN_DANGER("You need to have a firm grip on [C] before you can put \the [src] on!"))
|
|
|
|
/obj/item/handcuffs/proc/place_handcuffs(var/mob/living/carbon/target, var/mob/user, var/instant)
|
|
playsound(src.loc, cuff_sound, 30, 1, -2)
|
|
|
|
var/mob/living/carbon/human/H = target
|
|
if(!istype(H))
|
|
return FALSE
|
|
|
|
if((!legcuff && !H.has_organ_for_slot(slot_handcuffed)) || (legcuff && !H.has_organ_for_slot(slot_legcuffed)))
|
|
if(user)
|
|
to_chat(user, SPAN_DANGER("\The [H] needs at least two [legcuff ? "ankles" : "wrists"] before you can cuff them together!"))
|
|
return FALSE
|
|
|
|
if(!elastic) // Can't cuff someone who's in a deployed hardsuit.
|
|
if(!legcuff && istype(H.gloves, /obj/item/clothing/gloves/rig))
|
|
if(user)
|
|
to_chat(user, SPAN_DANGER("\The [src] won't fit around \the [H.gloves]!"))
|
|
return FALSE
|
|
if(legcuff && istype(H.shoes, /obj/item/clothing/shoes/magboots/rig))
|
|
if(user)
|
|
to_chat(user, SPAN_DANGER("\The [src] won't fit around \the [H.shoes]!"))
|
|
return FALSE
|
|
|
|
if(user)
|
|
user.visible_message(SPAN_DANGER("\The [user] is attempting to put [cuff_type] on \the [H]!"))
|
|
|
|
if(!instant)
|
|
if(!do_mob(user, target, 30))
|
|
return
|
|
|
|
if(user)
|
|
H.attack_log += "\[[time_stamp()]\] <font color='orange'>Has been handcuffed (attempt) by [user.name] ([user.ckey])</font>"
|
|
user.attack_log += "\[[time_stamp()]\] <span class='warning'>Attempted to handcuff [H.name] ([H.ckey])</span>"
|
|
msg_admin_attack("[key_name_admin(user)] attempted to handcuff [key_name_admin(H)] (<A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)",ckey=key_name(user),ckey_target=key_name(H))
|
|
feedback_add_details("handcuffs","H")
|
|
|
|
if(user)
|
|
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
|
user.do_attack_animation(H)
|
|
user.visible_message(SPAN_DANGER("\The [user] has put [cuff_type] on \the [H]!"))
|
|
|
|
// Apply cuffs.
|
|
var/obj/item/handcuffs/cuffs = src
|
|
if(dispenser)
|
|
cuffs = new(target)
|
|
else if(user)
|
|
user.drop_from_inventory(cuffs,target)
|
|
else
|
|
cuffs.forceMove(target)
|
|
|
|
if(!legcuff)
|
|
target.handcuffed = cuffs
|
|
target.handcuff_update()
|
|
else
|
|
target.legcuffed = cuffs
|
|
target.legcuff_update()
|
|
return TRUE
|
|
|
|
/mob/living/carbon/human/RestrainedClickOn(var/atom/A)
|
|
if (A != src) return ..()
|
|
|
|
|
|
var/mob/living/carbon/human/H = A
|
|
if (H.last_chew + 26 > world.time) return
|
|
if (!H.handcuffed) return
|
|
if (H.a_intent != I_HURT) return
|
|
if (H.zone_sel.selecting != BP_MOUTH) return
|
|
if (!H.check_has_mouth()) return
|
|
if (H.wear_mask) return
|
|
if (istype(H.wear_suit, /obj/item/clothing/suit/straight_jacket)) return
|
|
|
|
var/obj/item/organ/external/O = H.organs_by_name[H.hand?BP_L_HAND:BP_R_HAND]
|
|
if (!O) return
|
|
|
|
var/s = SPAN_WARNING("[H] chews on [H.get_pronoun("his")] [O.name]!")
|
|
H.visible_message(s, SPAN_WARNING("You chew on your [O.name]!"))
|
|
message_admins("[key_name_admin(H)] is chewing on [H.get_pronoun("his")] restrained hand - (<A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[H.x];Y=[H.y];Z=[H.z]'>JMP</a>)")
|
|
H.attack_log += "\[[time_stamp()]\] <span class='warning'>[s] ([H.ckey])</span>"
|
|
log_attack("[s] ([H.ckey])")
|
|
|
|
if(O.take_damage(3, 0, damage_flags = DAMAGE_FLAG_SHARP|DAMAGE_FLAG_EDGE, used_weapon = "teeth marks"))
|
|
H.UpdateDamageIcon()
|
|
|
|
last_chew = world.time
|
|
|
|
/obj/item/handcuffs/cable
|
|
name = "cable restraints"
|
|
desc = "Looks like some cables tied together. Could be used to tie something up."
|
|
icon_state = "cablecuff"
|
|
item_state = "coil"
|
|
color = COLOR_RED
|
|
breakouttime = 30 SECONDS
|
|
cuff_sound = 'sound/weapons/cablecuff.ogg'
|
|
cuff_type = "cable restraint handcuffs"
|
|
var/can_be_cut = TRUE
|
|
elastic = TRUE
|
|
contained_sprite = TRUE
|
|
build_from_parts = TRUE
|
|
worn_overlay = "end"
|
|
|
|
/obj/item/handcuffs/cable/Initialize(mapload, new_color)
|
|
. = ..()
|
|
if(new_color)
|
|
color = new_color
|
|
|
|
if(build_from_parts) //random colors!
|
|
if(!color)
|
|
color = pick(COLOR_RED, COLOR_BLUE, COLOR_LIME, COLOR_ORANGE, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN)
|
|
AddOverlays(overlay_image(icon, "[initial(icon_state)]_end", flags=RESET_COLOR))
|
|
|
|
/obj/item/handcuffs/cable/attack_self(mob/user)
|
|
legcuff = !legcuff
|
|
cuff_type = "cable restraint [legcuff ? "leg" : "hand"]cuffs"
|
|
to_chat(user, SPAN_NOTICE("You twist the cable into [cuff_type]."))
|
|
icon_state = "cable[legcuff ? "leg" : ""]cuff"
|
|
breakouttime = legcuff ? 10 SECONDS : 30 SECONDS
|
|
|
|
/obj/item/handcuffs/cable/yellow
|
|
color = COLOR_YELLOW
|
|
|
|
/obj/item/handcuffs/cable/blue
|
|
color = COLOR_BLUE
|
|
|
|
/obj/item/handcuffs/cable/green
|
|
color = COLOR_GREEN
|
|
|
|
/obj/item/handcuffs/cable/green/vines
|
|
name = "vine bindings"
|
|
desc = "A set of handcuffs made out of vines. How devilish!"
|
|
can_be_cut = FALSE
|
|
|
|
/obj/item/handcuffs/cable/green/vines/attack_self(mob/user)
|
|
return
|
|
|
|
/obj/item/handcuffs/cable/pink
|
|
color = COLOR_PINK
|
|
|
|
/obj/item/handcuffs/cable/orange
|
|
color = COLOR_ORANGE
|
|
|
|
/obj/item/handcuffs/cable/cyan
|
|
color = COLOR_CYAN
|
|
|
|
/obj/item/handcuffs/cable/white
|
|
color = COLOR_WHITE
|
|
|
|
/obj/item/handcuffs/cable/random/Initialize()
|
|
color = pick(COLOR_RED, COLOR_BLUE, COLOR_LIME, COLOR_ORANGE, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN)
|
|
. = ..()
|
|
|
|
/obj/item/handcuffs/cable/attackby(obj/item/attacking_item, mob/user)
|
|
..()
|
|
if(istype(attacking_item, /obj/item/stack/rods))
|
|
var/obj/item/stack/rods/R = attacking_item
|
|
if (R.use(1))
|
|
var/obj/item/material/wirerod/W = new(get_turf(user), MATERIAL_STEEL, color)
|
|
user.put_in_hands(W)
|
|
to_chat(user, SPAN_NOTICE("You wrap \the [src] around the top of the rod."))
|
|
qdel(src)
|
|
update_icon(user)
|
|
else if(can_be_cut && attacking_item.tool_behaviour == TOOL_WIRECUTTER)
|
|
user.visible_message("[user] cuts the [src].", SPAN_NOTICE("You cut the [src]."))
|
|
playsound(src.loc, 'sound/items/Wirecutter.ogg', 50, 1)
|
|
new/obj/item/stack/cable_coil(get_turf(src), 15, color)
|
|
qdel(src)
|
|
update_icon(user)
|
|
|
|
/obj/item/handcuffs/cyborg
|
|
dispenser = TRUE
|
|
|
|
/obj/item/handcuffs/cable/tape
|
|
name = "tape restraints"
|
|
desc = "DIY!"
|
|
icon_state = "tape_cross"
|
|
item_state = null
|
|
icon = 'icons/obj/bureaucracy.dmi'
|
|
breakouttime = 20 SECONDS
|
|
cuff_type = "duct tape"
|
|
|
|
/obj/item/handcuffs/ziptie
|
|
name = "ziptie"
|
|
desc = " A sturdy and reliable plastic ziptie for binding the wrists."
|
|
icon_state = "ziptie"
|
|
breakouttime = 1 MINUTE
|
|
cuff_sound = 'sound/weapons/cablecuff.ogg'
|
|
cuff_type = "zipties"
|
|
elastic = TRUE
|
|
|
|
/obj/item/handcuffs/legcuffs
|
|
name = "legcuffs"
|
|
desc = "Use this to keep prisoners in line."
|
|
icon_state = "legcuff"
|
|
legcuff = TRUE
|
|
breakouttime = 30 SECONDS
|
|
cuff_type = "legcuffs"
|