diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 24a984c73d4..8ef16dbe482 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -79,6 +79,10 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_KNOCKEDOUT "knockedout" //Forces the user to stay unconscious.
#define TRAIT_IMMOBILIZED "immobilized" //Prevents voluntary movement.
#define TRAIT_FLOORED "floored" //Prevents standing or staying up on its own.
+/// Prevents usage of manipulation appendages (picking, holding or using items, manipulating storage).
+#define TRAIT_HANDS_BLOCKED "handsblocked"
+/// Abstract condition that prevents movement if being pulled and might be resisted against. Handcuffs and straight jackets, basically.
+#define TRAIT_RESTRAINED "restrained"
#define TRAIT_INCAPACITATED "incapacitated"
#define TRAIT_CRITICAL_CONDITION "critical-condition" //In some kind of critical condition. Is able to succumb.
#define TRAIT_BLIND "blind"
@@ -286,6 +290,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define RESTING_TRAIT "resting" //trait associated to resting
#define STAT_TRAIT "stat" //trait associated to a stat value or range of
#define MAPPING_HELPER_TRAIT "mapping-helper" //obtained from mapping helper
+/// Trait associated to wearing a suit
+#define SUIT_TRAIT "suit"
// unique trait sources, still defines
#define CLONING_POD_TRAIT "cloning-pod"
@@ -331,3 +337,5 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define PULLED_WHILE_SOFTCRIT_TRAIT "pulled-while-softcrit"
#define LOCKED_BORG_TRAIT "locked-borg"
#define LACKING_LOCOMOTION_APPENDAGES_TRAIT "lacking-locomotion-appengades" //trait associated to not having locomotion appendages nor the ability to fly or float
+#define LACKING_MANIPULATION_APPENDAGES_TRAIT "lacking-manipulation-appengades" //trait associated to not having fine manipulation appendages such as hands
+#define HANDCUFFED_TRAIT "handcuffed"
diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm
index f196a136317..8d803f1cfbf 100644
--- a/code/_globalvars/traits.dm
+++ b/code/_globalvars/traits.dm
@@ -8,6 +8,8 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_KNOCKEDOUT" = TRAIT_KNOCKEDOUT,
"TRAIT_IMMOBILIZED" = TRAIT_IMMOBILIZED,
"TRAIT_FLOORED" = TRAIT_FLOORED,
+ "TRAIT_HANDS_BLOCKED" = TRAIT_HANDS_BLOCKED,
+ "TRAIT_RESTRAINED" = TRAIT_RESTRAINED,
"TRAIT_INCAPACITATED" = TRAIT_INCAPACITATED,
"TRAIT_CRITICAL_CONDITION" = TRAIT_CRITICAL_CONDITION,
"TRAIT_BLIND" = TRAIT_BLIND,
diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm
index 14733e1881c..3ed75494289 100644
--- a/code/_onclick/ai.dm
+++ b/code/_onclick/ai.dm
@@ -1,9 +1,6 @@
/*
AI ClickOn()
- Note currently ai restrained() returns 0 in all cases,
- therefore restrained code has been removed
-
The AI can double click to move the camera (this was already true but is cleaner),
or double click a mob to track them.
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index 337399c8dde..14e94a9f2c0 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -113,9 +113,9 @@
if(!modifiers["catcher"] && A.IsObscured())
return
- if(restrained())
+ if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
changeNext_move(CLICK_CD_HANDCUFFED) //Doing shit in cuffs shall be vey slow
- RestrainedClickOn(A)
+ UnarmedAttack(A)
return
if(in_throw_mode)
@@ -277,14 +277,7 @@
*/
/mob/proc/RangedAttack(atom/A, params)
SEND_SIGNAL(src, COMSIG_MOB_ATTACK_RANGED, A, params)
-/**
- * Restrained ClickOn
- *
- * Used when you are handcuffed and click things.
- * Not currently used by anything but could easily be.
- */
-/mob/proc/RestrainedClickOn(atom/A)
- return
+
/**
* Middle click
diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm
index dd10d5d2791..ba02c8dd3b3 100644
--- a/code/_onclick/cyborg.dm
+++ b/code/_onclick/cyborg.dm
@@ -42,12 +42,6 @@
face_atom(A) // change direction to face what you clicked on
- /*
- cyborg restrained() currently does nothing
- if(restrained())
- RestrainedClickOn(A)
- return
- */
if(aicamera.in_camera_mode) //Cyborg picture taking
aicamera.camera_mode_off()
aicamera.captureimage(A, usr)
diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm
index d3e8f3d39ad..35db4a23252 100644
--- a/code/_onclick/other_mobs.dm
+++ b/code/_onclick/other_mobs.dm
@@ -5,6 +5,10 @@
Otherwise pretty standard.
*/
/mob/living/carbon/human/UnarmedAttack(atom/A, proximity)
+ if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
+ if(src == A)
+ check_self_for_injuries()
+ return
if(!has_active_hand()) //can't attack without a hand.
var/obj/item/bodypart/check_arm = get_active_hand()
if(check_arm?.bodypart_disabled)
@@ -75,13 +79,6 @@
return ui_interact(user)
return FALSE
-/*
-/mob/living/carbon/human/RestrainedClickOn(atom/A) ---carbons will handle this
- return
-*/
-
-/mob/living/carbon/RestrainedClickOn(atom/A)
- return
/mob/living/carbon/human/RangedAttack(atom/A, mouseparams)
. = ..()
@@ -103,74 +100,64 @@
/atom/proc/attack_animal(mob/user)
SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_ANIMAL, user)
-/mob/living/RestrainedClickOn(atom/A)
- return
/*
Monkeys
*/
/mob/living/carbon/monkey/UnarmedAttack(atom/A)
+ if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
+ if(a_intent != INTENT_HARM || is_muzzled())
+ return
+ if(!iscarbon(A))
+ return
+ var/mob/living/carbon/victim = A
+ var/obj/item/bodypart/affecting = null
+ if(ishuman(victim))
+ var/mob/living/carbon/human/human_victim = victim
+ affecting = human_victim.get_bodypart(pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
+ var/armor = victim.run_armor_check(affecting, MELEE)
+ if(prob(25))
+ victim.visible_message("[src]'s bite misses [victim]!",
+ "You avoid [src]'s bite!", "You hear jaws snapping shut!", COMBAT_MESSAGE_RANGE, src)
+ to_chat(src, "Your bite misses [victim]!")
+ return
+ victim.apply_damage(rand(1, 3), BRUTE, affecting, armor)
+ victim.visible_message("[name] bites [victim]!",
+ "[name] bites you!", "You hear a chomp!", COMBAT_MESSAGE_RANGE, name)
+ to_chat(name, "You bite [victim]!")
+ if(armor >= 2)
+ return
+ for(var/d in diseases)
+ var/datum/disease/bite_infection = d
+ victim.ForceContractDisease(bite_infection)
+ return
A.attack_paw(src)
+
/atom/proc/attack_paw(mob/user)
if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_PAW, user) & COMPONENT_NO_ATTACK_HAND)
return TRUE
return FALSE
-/*
- Monkey RestrainedClickOn() was apparently the
- one and only use of all of the restrained click code
- (except to stop you from doing things while handcuffed);
- moving it here instead of various hand_p's has simplified
- things considerably
-*/
-/mob/living/carbon/monkey/RestrainedClickOn(atom/A)
- if(..())
- return
- if(a_intent != INTENT_HARM || !ismob(A))
- return
- if(is_muzzled())
- return
- var/mob/living/carbon/ML = A
- if(istype(ML))
- var/dam_zone = pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
- var/obj/item/bodypart/affecting = null
- if(ishuman(ML))
- var/mob/living/carbon/human/H = ML
- affecting = H.get_bodypart(ran_zone(dam_zone))
- var/armor = ML.run_armor_check(affecting, MELEE)
- if(prob(75))
- ML.apply_damage(rand(1,3), BRUTE, affecting, armor)
- ML.visible_message("[name] bites [ML]!", \
- "[name] bites you!", "You hear a chomp!", COMBAT_MESSAGE_RANGE, name)
- to_chat(name, "You bite [ML]!")
- if(armor >= 2)
- return
- for(var/thing in diseases)
- var/datum/disease/D = thing
- ML.ForceContractDisease(D)
- else
- ML.visible_message("[src]'s bite misses [ML]!", \
- "You avoid [src]'s bite!", "You hear jaws snapping shut!", COMBAT_MESSAGE_RANGE, src)
- to_chat(src, "Your bite misses [ML]!")
/*
Aliens
Defaults to same as monkey in most places
*/
/mob/living/carbon/alien/UnarmedAttack(atom/A)
+ if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
+ return
A.attack_alien(src)
/atom/proc/attack_alien(mob/living/carbon/alien/user)
attack_paw(user)
return
-/mob/living/carbon/alien/RestrainedClickOn(atom/A)
- return
// Babby aliens
/mob/living/carbon/alien/larva/UnarmedAttack(atom/A)
A.attack_larva(src)
+
/atom/proc/attack_larva(mob/user)
return
@@ -187,9 +174,6 @@
/atom/proc/attack_slime(mob/user)
return
-/mob/living/simple_animal/slime/RestrainedClickOn(atom/A)
- return
-
/*
Drones
@@ -200,9 +184,6 @@
/atom/proc/attack_drone(mob/living/simple_animal/drone/user)
attack_hand(user) //defaults to attack_hand. Override it when you don't want drones to do same stuff as humans.
-/mob/living/simple_animal/slime/RestrainedClickOn(atom/A)
- return
-
/*
Brain
diff --git a/code/datums/action.dm b/code/datums/action.dm
index 152aac1065c..57e41babc78 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -1,7 +1,7 @@
-#define AB_CHECK_RESTRAINED 1
-#define AB_CHECK_STUN 2
-#define AB_CHECK_LYING 4
-#define AB_CHECK_CONSCIOUS 8
+#define AB_CHECK_HANDS_BLOCKED (1<<0)
+#define AB_CHECK_IMMOBILE (1<<1)
+#define AB_CHECK_LYING (1<<2)
+#define AB_CHECK_CONSCIOUS (1<<3)
/datum/action
var/name = "Generic Action"
@@ -91,27 +91,23 @@
return FALSE
return TRUE
+
/datum/action/proc/IsAvailable()
if(!owner)
return FALSE
- if(check_flags & AB_CHECK_RESTRAINED)
- if(owner.restrained())
- return FALSE
- if(check_flags & AB_CHECK_STUN)
- if(isliving(owner))
- var/mob/living/L = owner
- if(L.IsParalyzed() || L.IsStun())
- return FALSE
- if(check_flags & AB_CHECK_LYING)
- if(isliving(owner))
- var/mob/living/L = owner
- if(!(L.mobility_flags & MOBILITY_STAND))
- return FALSE
- if(check_flags & AB_CHECK_CONSCIOUS)
- if(owner.stat)
+ if((check_flags & AB_CHECK_HANDS_BLOCKED) && HAS_TRAIT(owner, TRAIT_HANDS_BLOCKED))
+ return FALSE
+ if((check_flags & AB_CHECK_IMMOBILE) && HAS_TRAIT(owner, TRAIT_IMMOBILIZED))
+ return FALSE
+ if((check_flags & AB_CHECK_LYING) && isliving(owner))
+ var/mob/living/action_user = owner
+ if(!(action_user.mobility_flags & MOBILITY_STAND))
return FALSE
+ if((check_flags & AB_CHECK_CONSCIOUS) && owner.stat != CONSCIOUS)
+ return FALSE
return TRUE
+
/datum/action/proc/UpdateButtonIcon(status_only = FALSE, force = FALSE)
if(button)
if(!status_only)
@@ -150,7 +146,7 @@
//Presets for item actions
/datum/action/item_action
- check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_LYING|AB_CHECK_CONSCIOUS
+ check_flags = AB_CHECK_HANDS_BLOCKED|AB_CHECK_IMMOBILE|AB_CHECK_LYING|AB_CHECK_CONSCIOUS
button_icon_state = null
// If you want to override the normal icon being the item
// then change this to an icon state
@@ -499,7 +495,7 @@
/datum/action/item_action/agent_box
name = "Deploy Box"
desc = "Find inner peace, here, in the box."
- check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_CONSCIOUS
+ check_flags = AB_CHECK_HANDS_BLOCKED|AB_CHECK_IMMOBILE|AB_CHECK_CONSCIOUS
background_icon_state = "bg_agent"
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "deploy_box"
diff --git a/code/datums/components/riding.dm b/code/datums/components/riding.dm
index d53b456822b..e8944d1b89b 100644
--- a/code/datums/components/riding.dm
+++ b/code/datums/components/riding.dm
@@ -117,9 +117,9 @@
var/atom/movable/AM = parent
var/mob/AMM = AM
var/kick_us_off
- if((ride_check_rider_restrained && M.restrained(TRUE)) || (ride_check_rider_incapacitated && M.incapacitated(TRUE, TRUE)))
+ if((ride_check_rider_restrained && HAS_TRAIT(M, TRAIT_RESTRAINED)) || (ride_check_rider_incapacitated && M.incapacitated(TRUE, TRUE)))
kick_us_off = TRUE
- if(kick_us_off || (istype(AMM) && ((ride_check_ridden_restrained && AMM.restrained(TRUE)) || (ride_check_ridden_incapacitated && AMM.incapacitated(TRUE, TRUE)))))
+ if(kick_us_off || (istype(AMM) && ((ride_check_ridden_restrained && HAS_TRAIT(AMM, TRAIT_RESTRAINED)) || (ride_check_ridden_incapacitated && AMM.incapacitated(TRUE, TRUE)))))
M.visible_message("[M] falls off of [AM]!", \
"You fall off of [AM]!")
AM.unbuckle_mob(M)
diff --git a/code/datums/components/tackle.dm b/code/datums/components/tackle.dm
index 2c3d60d24bb..5f2acde6955 100644
--- a/code/datums/components/tackle.dm
+++ b/code/datums/components/tackle.dm
@@ -81,7 +81,7 @@
to_chat(user, "You're too angry to remember how to tackle!")
return
- if(user.restrained())
+ if(HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
to_chat(user, "You need free use of your hands to tackle!")
return
diff --git a/code/datums/emotes.dm b/code/datums/emotes.dm
index 9d8090913fe..d343ac51f98 100644
--- a/code/datums/emotes.dm
+++ b/code/datums/emotes.dm
@@ -14,7 +14,8 @@
var/message_simple = "" //Message to display if the user is a simple_animal
var/message_param = "" //Message to display if a param was given
var/emote_type = EMOTE_VISIBLE //Whether the emote is visible or audible
- var/restraint_check = FALSE //Checks if the mob is restrained before performing the emote
+ /// Checks if the mob can use its hands before performing the emote.
+ var/hands_use_check = FALSE
var/muzzle_ignore = FALSE //Will only work if the emote is EMOTE_AUDIBLE
var/list/mob_type_allowed_typecache = /mob //Types that are allowed to use that emote
var/list/mob_type_blacklist_typecache //Types that are NOT allowed to use that emote
@@ -139,18 +140,10 @@
if(DEAD)
to_chat(user, "You cannot [key] while dead!")
return FALSE
- if(restraint_check)
- if(isliving(user))
- var/mob/living/L = user
- if(L.IsParalyzed() || L.IsStun())
- if(!intentional)
- return FALSE
- to_chat(user, "You cannot [key] while stunned!")
- return FALSE
- if(restraint_check && user.restrained())
+ if(hands_use_check && HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
if(!intentional)
return FALSE
- to_chat(user, "You cannot [key] while restrained!")
+ to_chat(user, "You cannot use your hands to [key] right now!")
return FALSE
if(isliving(user))
diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm
index 1991bd8bcf2..ded403262ef 100644
--- a/code/datums/status_effects/debuffs.dm
+++ b/code/datums/status_effects/debuffs.dm
@@ -35,10 +35,12 @@
return
ADD_TRAIT(owner, TRAIT_INCAPACITATED, TRAIT_STATUS_EFFECT(id))
ADD_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
+ ADD_TRAIT(owner, TRAIT_HANDS_BLOCKED, TRAIT_STATUS_EFFECT(id))
/datum/status_effect/incapacitating/stun/on_remove()
REMOVE_TRAIT(owner, TRAIT_INCAPACITATED, TRAIT_STATUS_EFFECT(id))
REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
+ REMOVE_TRAIT(owner, TRAIT_HANDS_BLOCKED, TRAIT_STATUS_EFFECT(id))
return ..()
@@ -83,11 +85,13 @@
ADD_TRAIT(owner, TRAIT_INCAPACITATED, TRAIT_STATUS_EFFECT(id))
ADD_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
ADD_TRAIT(owner, TRAIT_FLOORED, TRAIT_STATUS_EFFECT(id))
+ ADD_TRAIT(owner, TRAIT_HANDS_BLOCKED, TRAIT_STATUS_EFFECT(id))
/datum/status_effect/incapacitating/paralyzed/on_remove()
REMOVE_TRAIT(owner, TRAIT_INCAPACITATED, TRAIT_STATUS_EFFECT(id))
REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
REMOVE_TRAIT(owner, TRAIT_FLOORED, TRAIT_STATUS_EFFECT(id))
+ REMOVE_TRAIT(owner, TRAIT_HANDS_BLOCKED, TRAIT_STATUS_EFFECT(id))
return ..()
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index e3681201cb3..f09166b4172 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -1021,11 +1021,13 @@
if(grab_state >= GRAB_NECK)
ADD_TRAIT(pulling, TRAIT_IMMOBILIZED, CHOKEHOLD_TRAIT)
ADD_TRAIT(pulling, TRAIT_FLOORED, CHOKEHOLD_TRAIT)
+ ADD_TRAIT(pulling, TRAIT_HANDS_BLOCKED, CHOKEHOLD_TRAIT)
switch(grab_state) //Current state.
if(GRAB_PASSIVE, GRAB_AGGRESSIVE)
if(. >= GRAB_NECK)
REMOVE_TRAIT(pulling, TRAIT_IMMOBILIZED, CHOKEHOLD_TRAIT)
REMOVE_TRAIT(pulling, TRAIT_FLOORED, CHOKEHOLD_TRAIT)
+ REMOVE_TRAIT(pulling, TRAIT_HANDS_BLOCKED, CHOKEHOLD_TRAIT)
/obj/item/proc/do_pickup_animation(atom/target)
diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm
index 1234d20c55c..70cb4f06596 100644
--- a/code/game/machinery/PDApainter.dm
+++ b/code/game/machinery/PDApainter.dm
@@ -134,7 +134,7 @@
set category = "Object"
set src in oview(1)
- if(usr.stat || usr.restrained())
+ if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(storedpda)
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index fe92c587e52..3293901299c 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -122,7 +122,7 @@
if(world.time - M.last_bumped <= 10)
return //Can bump-open one airlock per second. This is to prevent shock spam.
M.last_bumped = world.time
- if(M.restrained() && !check_access(null))
+ if(HAS_TRAIT(M, TRAIT_HANDS_BLOCKED) && !check_access(null))
return
if(try_safety_unlock(M))
return
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index 013b43be237..a0165290fd7 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -82,7 +82,7 @@
if(!SSticker)
return
var/mob/M = AM
- if(M.restrained() || ((isdrone(M) || iscyborg(M)) && M.stat))
+ if(HAS_TRAIT(M, TRAIT_HANDS_BLOCKED) || ((isdrone(M) || iscyborg(M)) && M.stat != CONSCIOUS))
return
bumpopen(M)
diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm
index 93a0f7869b6..6db4e547242 100644
--- a/code/game/machinery/pipe/pipe_dispenser.dm
+++ b/code/game/machinery/pipe/pipe_dispenser.dm
@@ -35,7 +35,7 @@
if(..())
return 1
var/mob/living/L = usr
- if(!anchored || (istype(L) && !(L.mobility_flags & MOBILITY_UI)) || usr.stat || usr.restrained() || !in_range(loc, usr))
+ if(!anchored || (istype(L) && !(L.mobility_flags & MOBILITY_UI)) || usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || !in_range(loc, usr))
usr << browse(null, "window=pipedispenser")
return 1
usr.set_machine(src)
diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm
index c3c6ac8e274..28d807459a9 100644
--- a/code/game/objects/buckling.dm
+++ b/code/game/objects/buckling.dm
@@ -167,8 +167,8 @@
if(LAZYLEN(buckled_mobs) >= max_buckled_mobs)
return FALSE
- // If the buckle requires restraints, make sure the target is actually restrained while ignoring grab restraint.
- if(buckle_requires_restraints && !target.restrained(TRUE))
+ // If the buckle requires restraints, make sure the target is actually restrained.
+ if(buckle_requires_restraints && !HAS_TRAIT(target, TRAIT_RESTRAINED))
return FALSE
return TRUE
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 05c1f9a114e..7d59ec8b6c3 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -261,7 +261,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
set category = "Object"
set src in oview(1)
- if(!isturf(loc) || usr.stat || usr.restrained())
+ if(!isturf(loc) || usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(isliving(usr))
diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm
index 7eaa638fc14..2ae89187c5e 100644
--- a/code/game/objects/items/handcuffs.dm
+++ b/code/game/objects/items/handcuffs.dm
@@ -9,7 +9,7 @@
if(iscarbon(loc))
var/mob/living/carbon/M = loc
if(M.handcuffed == src)
- M.handcuffed = null
+ M.set_handcuffed(null)
M.update_handcuffed()
if(M.buckled && M.buckled.buckle_requires_restraints)
M.buckled.unbuckle_mob(M)
@@ -91,7 +91,7 @@
cuffs = new type()
cuffs.forceMove(target)
- target.handcuffed = cuffs
+ target.set_handcuffed(cuffs)
target.update_handcuffed()
if(trashtype && !dispense)
@@ -238,11 +238,12 @@
return (BRUTELOSS)
/obj/item/restraints/legcuffs/beartrap/attack_self(mob/user)
- ..()
- if(ishuman(user) && !user.stat && !user.restrained())
- armed = !armed
- update_icon()
- to_chat(user, "[src] is now [armed ? "armed" : "disarmed"]")
+ . = ..()
+ if(!ishuman(user) || user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ return
+ armed = !armed
+ update_icon()
+ to_chat(user, "[src] is now [armed ? "armed" : "disarmed"]")
/obj/item/restraints/legcuffs/beartrap/proc/close_trap()
armed = FALSE
diff --git a/code/game/objects/items/paint.dm b/code/game/objects/items/paint.dm
index 2ef7da91cb9..cd7ae4bf189 100644
--- a/code/game/objects/items/paint.dm
+++ b/code/game/objects/items/paint.dm
@@ -57,7 +57,7 @@
/obj/item/paint/anycolor/attack_self(mob/user)
var/t1 = input(user, "Please select a color:", "[src]", null) in sortList(list( "red", "blue", "green", "yellow", "violet", "black", "white"))
- if ((user.get_active_held_item() != src || user.stat || user.restrained()))
+ if ((user.get_active_held_item() != src || user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)))
return
switch(t1)
if("red")
diff --git a/code/game/objects/items/scrolls.dm b/code/game/objects/items/scrolls.dm
index 408a3332d40..83d0ec2f210 100644
--- a/code/game/objects/items/scrolls.dm
+++ b/code/game/objects/items/scrolls.dm
@@ -31,7 +31,7 @@
/obj/item/teleportation_scroll/Topic(href, href_list)
..()
- if (usr.stat || usr.restrained() || src.loc != usr)
+ if (usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || src.loc != usr)
return
if (!ishuman(usr))
return 1
diff --git a/code/game/objects/items/storage/secure.dm b/code/game/objects/items/storage/secure.dm
index 67b8000bc05..9dfa343ccab 100644
--- a/code/game/objects/items/storage/secure.dm
+++ b/code/game/objects/items/storage/secure.dm
@@ -80,7 +80,7 @@
/obj/item/storage/secure/Topic(href, href_list)
..()
- if ((usr.stat || usr.restrained()) || (get_dist(src, usr) > 1))
+ if (usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || (get_dist(src, usr) > 1))
return
if (href_list["type"])
if (href_list["type"] == "E")
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index 96b7e905c63..6011a426d6b 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -82,7 +82,7 @@
user.visible_message("[user] starts climbing onto [src].", \
"You start climbing onto [src]...")
var/adjusted_climb_time = climb_time
- if(user.restrained()) //climbing takes twice as long when restrained.
+ if(HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //climbing takes twice as long without help from the hands.
adjusted_climb_time *= 2
if(isalien(user))
adjusted_climb_time *= 0.25 //aliens are terrifyingly fast
diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm
index 071d1d0392e..7122f417980 100644
--- a/code/game/objects/structures/noticeboard.dm
+++ b/code/game/objects/structures/noticeboard.dm
@@ -58,7 +58,7 @@
..()
usr.set_machine(src)
if(href_list["remove"])
- if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open
+ if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED)) //For when a player is handcuffed while they have the notice window open
return
var/obj/item/I = locate(href_list["remove"]) in contents
if(istype(I) && I.loc == src)
@@ -68,7 +68,7 @@
icon_state = "nboard0[notices]"
if(href_list["write"])
- if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open
+ if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED)) //For when a player is handcuffed while they have the notice window open
return
var/obj/item/P = locate(href_list["write"]) in contents
if(istype(P) && P.loc == src)
diff --git a/code/game/objects/structures/spirit_board.dm b/code/game/objects/structures/spirit_board.dm
index 095c696640e..d3a75cebf67 100644
--- a/code/game/objects/structures/spirit_board.dm
+++ b/code/game/objects/structures/spirit_board.dm
@@ -67,7 +67,7 @@
var/users_in_range = 0
for(var/mob/living/L in orange(1,src))
if(L.ckey && L.client)
- if((world.time - L.client.inactivity) < (world.time - 300) || L.stat != CONSCIOUS || L.restrained())//no playing with braindeads or corpses or handcuffed dudes.
+ if((world.time - L.client.inactivity) < (world.time - 300) || L.stat != CONSCIOUS || HAS_TRAIT(L, TRAIT_HANDS_BLOCKED))//no playing with braindeads or corpses or handcuffed dudes.
to_chat(M, "[L] doesn't seem to be paying attention...")
else
users_in_range++
diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm
index d630d1dcede..a6312838f20 100644
--- a/code/game/objects/structures/windoor_assembly.dm
+++ b/code/game/objects/structures/windoor_assembly.dm
@@ -338,7 +338,7 @@
set name = "Flip Windoor Assembly"
set category = "Object"
set src in oview(1)
- if(usr.stat || usr.restrained())
+ if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(isliving(usr))
diff --git a/code/modules/antagonists/_common/antag_spawner.dm b/code/modules/antagonists/_common/antag_spawner.dm
index 1adb5840915..c9aef9d3775 100644
--- a/code/modules/antagonists/_common/antag_spawner.dm
+++ b/code/modules/antagonists/_common/antag_spawner.dm
@@ -42,13 +42,13 @@
return
/obj/item/antag_spawner/contract/Topic(href, href_list)
- ..()
- var/mob/living/carbon/human/H = usr
+ . = ..()
- if(H.stat || H.restrained())
+ if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
- if(!ishuman(H))
- return 1
+ if(!ishuman(usr))
+ return TRUE
+ var/mob/living/carbon/human/H = usr
if(loc == H || (in_range(src, H) && isturf(loc)))
H.set_machine(src)
diff --git a/code/modules/antagonists/abductor/equipment/abduction_gear.dm b/code/modules/antagonists/abductor/equipment/abduction_gear.dm
index 067962f3b09..4d600d40cc9 100644
--- a/code/modules/antagonists/abductor/equipment/abduction_gear.dm
+++ b/code/modules/antagonists/abductor/equipment/abduction_gear.dm
@@ -592,7 +592,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
"[user] begins shaping an energy field around your hands!")
if(do_mob(user, C, time_to_cuff) && C.canBeHandcuffed())
if(!C.handcuffed)
- C.handcuffed = new /obj/item/restraints/handcuffs/energy/used(C)
+ C.set_handcuffed(new /obj/item/restraints/handcuffs/energy/used(C))
C.update_handcuffed()
to_chat(user, "You restrain [C].")
log_combat(user, C, "handcuffed")
diff --git a/code/modules/antagonists/changeling/powers/biodegrade.dm b/code/modules/antagonists/changeling/powers/biodegrade.dm
index 6e5112d0429..58ed367a4d9 100644
--- a/code/modules/antagonists/changeling/powers/biodegrade.dm
+++ b/code/modules/antagonists/changeling/powers/biodegrade.dm
@@ -9,7 +9,7 @@
/datum/action/changeling/biodegrade/sting_action(mob/living/carbon/human/user)
var/used = FALSE // only one form of shackles removed per use
- if(!user.restrained() && !user.legcuffed && isopenturf(user.loc))
+ if(!HAS_TRAIT(user, TRAIT_RESTRAINED) && !user.legcuffed && isopenturf(user.loc))
to_chat(user, "We are already free!")
return FALSE
diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm
index 11eda3846d7..79587b0e34b 100644
--- a/code/modules/antagonists/cult/blood_magic.dm
+++ b/code/modules/antagonists/cult/blood_magic.dm
@@ -526,7 +526,7 @@
"[user] begins shaping dark magic shackles around your wrists!")
if(do_mob(user, C, 30))
if(!C.handcuffed)
- C.handcuffed = new /obj/item/restraints/handcuffs/energy/cult/used(C)
+ C.set_handcuffed(new /obj/item/restraints/handcuffs/energy/cult/used(C))
C.update_handcuffed()
C.silent += 5
to_chat(user, "You shackle [C].")
diff --git a/code/modules/antagonists/cult/cult_comms.dm b/code/modules/antagonists/cult/cult_comms.dm
index 7310dc225f5..cdf4db9b8fc 100644
--- a/code/modules/antagonists/cult/cult_comms.dm
+++ b/code/modules/antagonists/cult/cult_comms.dm
@@ -4,7 +4,7 @@
icon_icon = 'icons/mob/actions/actions_cult.dmi'
background_icon_state = "bg_demon"
buttontooltipstyle = "cult"
- check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_CONSCIOUS
+ check_flags = AB_CHECK_HANDS_BLOCKED|AB_CHECK_IMMOBILE|AB_CHECK_CONSCIOUS
/datum/action/innate/cult/IsAvailable()
if(!iscultist(owner))
diff --git a/code/modules/antagonists/eldritch_cult/eldritch_items.dm b/code/modules/antagonists/eldritch_cult/eldritch_items.dm
index 5021282ac98..f512f0a3d99 100644
--- a/code/modules/antagonists/eldritch_cult/eldritch_items.dm
+++ b/code/modules/antagonists/eldritch_cult/eldritch_items.dm
@@ -38,7 +38,7 @@
background_icon_state = "bg_ecult"
button_icon_state = "shatter"
icon_icon = 'icons/mob/actions/actions_ecult.dmi'
- check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN
+ check_flags = AB_CHECK_HANDS_BLOCKED|AB_CHECK_IMMOBILE
var/mob/living/carbon/human/holder
var/obj/item/melee/sickly_blade/sword
diff --git a/code/modules/antagonists/revolution/revolution.dm b/code/modules/antagonists/revolution/revolution.dm
index bfdab56924b..f9e56b0530f 100644
--- a/code/modules/antagonists/revolution/revolution.dm
+++ b/code/modules/antagonists/revolution/revolution.dm
@@ -296,7 +296,7 @@
var/list/datum/mind/promotable = list()
var/list/datum/mind/nonhuman_promotable = list()
for(var/datum/mind/khrushchev in non_heads)
- if(khrushchev.current && !khrushchev.current.incapacitated() && !khrushchev.current.restrained() && khrushchev.current.client && khrushchev.current.stat != DEAD)
+ if(khrushchev.current && !khrushchev.current.incapacitated() && !HAS_TRAIT(khrushchev.current, TRAIT_RESTRAINED) && khrushchev.current.client)
if(ROLE_REV in khrushchev.current.client.prefs.be_special)
if(ishuman(khrushchev.current))
promotable += khrushchev
diff --git a/code/modules/antagonists/wizard/equipment/spellbook.dm b/code/modules/antagonists/wizard/equipment/spellbook.dm
index c2dd89325a1..aee416db91b 100644
--- a/code/modules/antagonists/wizard/equipment/spellbook.dm
+++ b/code/modules/antagonists/wizard/equipment/spellbook.dm
@@ -739,13 +739,13 @@
return
/obj/item/spellbook/Topic(href, href_list)
- ..()
- var/mob/living/carbon/human/H = usr
+ . = ..()
- if(H.stat || H.restrained())
+ if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
- if(!ishuman(H))
+ if(!ishuman(usr))
return TRUE
+ var/mob/living/carbon/human/H = usr
if(H.mind.special_role == "apprentice")
temp = "If you got caught sneaking a peek from your teacher's spellbook, you'd likely be expelled from the Wizard Academy. Better not."
diff --git a/code/modules/awaymissions/bluespaceartillery.dm b/code/modules/awaymissions/bluespaceartillery.dm
index 22473fcac7a..9949840923b 100644
--- a/code/modules/awaymissions/bluespaceartillery.dm
+++ b/code/modules/awaymissions/bluespaceartillery.dm
@@ -40,7 +40,7 @@
var/A
A = input("Area to bombard", "Open Fire", A) in GLOB.teleportlocs
var/area/thearea = GLOB.teleportlocs[A]
- if(usr.stat || usr.restrained())
+ if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(reload < reload_cooldown)
return
diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm
index 9999ac31a5d..d6e337e8d1a 100644
--- a/code/modules/clothing/shoes/miscellaneous.dm
+++ b/code/modules/clothing/shoes/miscellaneous.dm
@@ -445,7 +445,7 @@
/obj/item/clothing/shoes/cowboy/MouseDrop_T(mob/living/target, mob/living/user)
. = ..()
- if(user.stat || !(user.mobility_flags & MOBILITY_USE) || user.restrained() || !Adjacent(user) || !user.Adjacent(target) || target.stat == DEAD)
+ if(!(user.mobility_flags & MOBILITY_USE) || user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user) || !user.Adjacent(target) || target.stat == DEAD)
return
if(occupants.len >= max_occupants)
to_chat(user, "[src] are full!")
diff --git a/code/modules/food_and_drinks/kitchen_machinery/processor.dm b/code/modules/food_and_drinks/kitchen_machinery/processor.dm
index bd0cd5a9dfa..eee6eeb3c67 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/processor.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/processor.dm
@@ -131,7 +131,7 @@
set category = "Object"
set name = "Eject Contents"
set src in oview(1)
- if(usr.stat || usr.restrained())
+ if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(isliving(usr))
var/mob/living/L = usr
diff --git a/code/modules/instruments/items.dm b/code/modules/instruments/items.dm
index d44441ae5ca..ba0d2d5cc93 100644
--- a/code/modules/instruments/items.dm
+++ b/code/modules/instruments/items.dm
@@ -40,7 +40,7 @@
ui_interact(user)
/obj/item/instrument/ui_interact(mob/living/user)
- if(!isliving(user) || user.stat || user.restrained())
+ if(!isliving(user) || user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
user.set_machine(src)
diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm
index 6c8dfaae8dc..1f5b30fac4c 100644
--- a/code/modules/library/lib_items.dm
+++ b/code/modules/library/lib_items.dm
@@ -145,7 +145,7 @@
if(contents.len)
var/obj/item/book/choice = input(user, "Which book would you like to remove from the shelf?") as null|obj in sortNames(contents.Copy())
if(choice)
- if(!(user.mobility_flags & MOBILITY_USE) || user.stat || user.restrained() || !in_range(loc, user))
+ if(!(user.mobility_flags & MOBILITY_USE) || user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !in_range(loc, user))
return
if(ishuman(user))
if(!user.get_active_held_item())
diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm
index 8d5835f1f9f..8cc31dd4e66 100644
--- a/code/modules/mob/emote.dm
+++ b/code/modules/mob/emote.dm
@@ -35,7 +35,7 @@
/datum/emote/flip
key = "flip"
key_third_person = "flips"
- restraint_check = TRUE
+ hands_use_check = TRUE
mob_type_allowed_typecache = list(/mob/living, /mob/dead/observer)
mob_type_ignore_stat_typecache = list(/mob/dead/observer)
@@ -69,7 +69,7 @@
/datum/emote/spin
key = "spin"
key_third_person = "spins"
- restraint_check = TRUE
+ hands_use_check = TRUE
mob_type_allowed_typecache = list(/mob/living, /mob/dead/observer)
mob_type_ignore_stat_typecache = list(/mob/dead/observer)
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
index e6fe7f1346a..ba453facb39 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
@@ -31,8 +31,6 @@
. = ..()
AddComponent(/datum/component/footstep, FOOTSTEP_MOB_CLAW, 0.5, -3)
-/mob/living/carbon/alien/humanoid/restrained(ignore_grab)
- return handcuffed
/mob/living/carbon/alien/humanoid/show_inv(mob/user)
user.set_machine(src)
diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm
index 6b4097e6faf..4bb89e4ede1 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva.dm
@@ -59,8 +59,6 @@
/mob/living/carbon/alien/larva/attack_ui(slot_id)
return
-/mob/living/carbon/alien/larva/restrained(ignore_grab)
- . = 0
// new damage icon system
// now constructs damage icon for each organ from mask * damage field
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 73fa2d7bef2..89419e88441 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -173,9 +173,6 @@
newtonian_move(get_dir(target, src))
thrown_thing.safe_throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed + power_throw, src, null, null, null, move_force)
-/mob/living/carbon/restrained(ignore_grab)
- . = (handcuffed || (!ignore_grab && pulledby && pulledby.grab_state >= GRAB_AGGRESSIVE))
-
/mob/living/carbon/proc/canBeHandcuffed()
return FALSE
@@ -269,7 +266,7 @@
return FALSE
/mob/living/carbon/resist_buckle()
- if(restrained())
+ if(HAS_TRAIT(src, TRAIT_RESTRAINED))
changeNext_move(CLICK_CD_BREAKOUT)
last_special = world.time + CLICK_CD_BREAKOUT
var/buckle_cd = 600
@@ -350,7 +347,7 @@
/mob/living/carbon/proc/uncuff()
if (handcuffed)
var/obj/item/W = handcuffed
- handcuffed = null
+ set_handcuffed(null)
if (buckled && buckled.buckle_requires_restraints)
buckled.unbuckle_mob(src)
update_handcuffed()
@@ -394,7 +391,7 @@
else
if(I == handcuffed)
handcuffed.forceMove(drop_location())
- handcuffed = null
+ set_handcuffed(null)
I.dropped(src)
if(buckled && buckled.buckle_requires_restraints)
buckled.unbuckle_mob(src)
@@ -880,7 +877,7 @@
suiciding = FALSE
regenerate_limbs()
regenerate_organs()
- handcuffed = initial(handcuffed)
+ set_handcuffed(null)
for(var/obj/item/restraints/R in contents) //actually remove cuffs from inventory
qdel(R)
update_handcuffed()
@@ -1278,3 +1275,18 @@
return
brain.update_skillchips()
+
+
+/// Modifies the handcuffed value if a different value is passed, returning FALSE otherwise. The variable should only be changed through this proc.
+/mob/living/carbon/proc/set_handcuffed(new_value)
+ if(handcuffed == new_value)
+ return FALSE
+ . = handcuffed
+ handcuffed = new_value
+ if(.)
+ if(!handcuffed)
+ REMOVE_TRAIT(src, TRAIT_RESTRAINED, HANDCUFFED_TRAIT)
+ REMOVE_TRAIT(src, TRAIT_HANDS_BLOCKED, HANDCUFFED_TRAIT)
+ else if(handcuffed)
+ ADD_TRAIT(src, TRAIT_RESTRAINED, HANDCUFFED_TRAIT)
+ ADD_TRAIT(src, TRAIT_HANDS_BLOCKED, HANDCUFFED_TRAIT)
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index 7719964287c..69fb4d7b8a1 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -50,9 +50,7 @@
return
if(get_active_held_item())
return
- if(!(mobility_flags & MOBILITY_MOVE))
- return
- if(restrained())
+ if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
return
return TRUE
diff --git a/code/modules/mob/living/carbon/carbon_movement.dm b/code/modules/mob/living/carbon/carbon_movement.dm
index 18b18009bda..7367995a613 100644
--- a/code/modules/mob/living/carbon/carbon_movement.dm
+++ b/code/modules/mob/living/carbon/carbon_movement.dm
@@ -51,9 +51,11 @@
if(isnull(.))
return
if(. == 0)
+ REMOVE_TRAIT(src, TRAIT_HANDS_BLOCKED, LACKING_MANIPULATION_APPENDAGES_TRAIT)
if(usable_hands != 0) //From having no usable hands to having some.
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, LACKING_LOCOMOTION_APPENDAGES_TRAIT)
- else if(usable_hands == 0) //From having usable hands to no longer having them.
+ else if(usable_hands == 0 && default_num_hands > 0) //From having usable hands to no longer having them.
+ ADD_TRAIT(src, TRAIT_HANDS_BLOCKED, LACKING_MANIPULATION_APPENDAGES_TRAIT)
if(!usable_legs && !(movement_type & (FLYING | FLOATING)))
ADD_TRAIT(src, TRAIT_IMMOBILIZED, LACKING_LOCOMOTION_APPENDAGES_TRAIT)
diff --git a/code/modules/mob/living/carbon/emote.dm b/code/modules/mob/living/carbon/emote.dm
index 464e47a22a6..af8dad2dc8a 100644
--- a/code/modules/mob/living/carbon/emote.dm
+++ b/code/modules/mob/living/carbon/emote.dm
@@ -4,7 +4,7 @@
/datum/emote/living/carbon/airguitar
key = "airguitar"
message = "is strumming the air and headbanging like a safari chimp."
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/carbon/blink
key = "blink"
@@ -20,7 +20,7 @@
key_third_person = "claps"
message = "claps."
muzzle_ignore = TRUE
- restraint_check = TRUE
+ hands_use_check = TRUE
emote_type = EMOTE_AUDIBLE
vary = TRUE
@@ -64,14 +64,14 @@
key_third_person = "rolls"
message = "rolls."
mob_type_allowed_typecache = list(/mob/living/carbon/monkey, /mob/living/carbon/alien)
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/carbon/scratch
key = "scratch"
key_third_person = "scratches"
message = "scratches."
mob_type_allowed_typecache = list(/mob/living/carbon/monkey, /mob/living/carbon/alien)
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/carbon/screech
key = "screech"
@@ -84,7 +84,7 @@
key_third_person = "signs"
message_param = "signs the number %t."
mob_type_allowed_typecache = list(/mob/living/carbon/monkey, /mob/living/carbon/alien)
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/carbon/sign/select_param(mob/user, params)
. = ..()
@@ -96,7 +96,7 @@
key_third_person = "signals"
message_param = "raises %t fingers."
mob_type_allowed_typecache = list(/mob/living/carbon/human)
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/carbon/tail
key = "tail"
@@ -111,7 +111,7 @@
/datum/emote/living/carbon/circle
key = "circle"
key_third_person = "circles"
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/carbon/circle/run_emote(mob/user, params, type_override, intentional)
. = ..()
@@ -125,7 +125,7 @@
/datum/emote/living/carbon/slap
key = "slap"
key_third_person = "slaps"
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/carbon/slap/run_emote(mob/user, params, type_override, intentional)
. = ..()
diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm
index 57077f30927..9a8b251b70b 100644
--- a/code/modules/mob/living/carbon/human/emote.dm
+++ b/code/modules/mob/living/carbon/human/emote.dm
@@ -12,7 +12,7 @@
key_third_person = "daps"
message = "sadly can't find anybody to give daps to, and daps themself. Shameful."
message_param = "give daps to %t."
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/carbon/human/eyebrow
key = "eyebrow"
@@ -28,7 +28,7 @@
key = "handshake"
message = "shakes their own hands."
message_param = "shakes hands with %t."
- restraint_check = TRUE
+ hands_use_check = TRUE
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/hug
@@ -36,7 +36,7 @@
key_third_person = "hugs"
message = "hugs themself."
message_param = "hugs %t."
- restraint_check = TRUE
+ hands_use_check = TRUE
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/mumble
@@ -78,14 +78,14 @@
key = "raise"
key_third_person = "raises"
message = "raises a hand."
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/carbon/human/salute
key = "salute"
key_third_person = "salutes"
message = "salutes."
message_param = "salutes to %t."
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/carbon/human/shrug
key = "shrug"
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 9d87bb91aeb..e445c78a7dc 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -660,10 +660,6 @@
..()
-/mob/living/carbon/human/RestrainedClickOn(atom/A)
- . = ..()
- if(src == A)
- check_self_for_injuries()
/mob/living/carbon/human/check_self_for_injuries()
if(stat >= UNCONSCIOUS)
diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm
index 62237843e99..eb85fb2e360 100644
--- a/code/modules/mob/living/carbon/human/human_helpers.dm
+++ b/code/modules/mob/living/carbon/human/human_helpers.dm
@@ -1,8 +1,4 @@
-/mob/living/carbon/human/restrained(ignore_grab)
- . = ((wear_suit && wear_suit.breakouttime) || ..())
-
-
/mob/living/carbon/human/canBeHandcuffed()
if(num_hands < 2)
return FALSE
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index 83cc98ceec8..edf9be57b88 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -148,6 +148,8 @@
if(I.flags_inv & HIDEJUMPSUIT)
update_inv_w_uniform()
if(wear_suit.breakouttime) //when equipping a straightjacket
+ ADD_TRAIT(src, TRAIT_RESTRAINED, SUIT_TRAIT)
+ ADD_TRAIT(src, TRAIT_HANDS_BLOCKED, SUIT_TRAIT)
stop_pulling() //can't pull if restrained
update_action_buttons_icon() //certain action buttons will no longer be usable.
update_inv_wear_suit()
@@ -203,6 +205,8 @@
if(s_store && invdrop)
dropItemToGround(s_store, TRUE) //It makes no sense for your suit storage to stay on you if you drop your suit.
if(wear_suit.breakouttime) //when unequipping a straightjacket
+ REMOVE_TRAIT(src, TRAIT_RESTRAINED, SUIT_TRAIT)
+ REMOVE_TRAIT(src, TRAIT_HANDS_BLOCKED, SUIT_TRAIT)
drop_all_held_items() //suit is restraining
update_action_buttons_icon() //certain action buttons may be usable again.
wear_suit = null
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 3bc52333ce6..4c3e9aca3fb 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -1971,7 +1971,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
/datum/action/innate/flight
name = "Toggle Flight"
- check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_STUN
+ check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_IMMOBILE
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "flight"
diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm
index 2248c225816..3b989e72057 100644
--- a/code/modules/mob/living/carbon/inventory.dm
+++ b/code/modules/mob/living/carbon/inventory.dm
@@ -77,7 +77,7 @@
wear_neck = I
update_inv_neck(I)
if(ITEM_SLOT_HANDCUFFED)
- handcuffed = I
+ set_handcuffed(I)
update_handcuffed()
if(ITEM_SLOT_LEGCUFFED)
legcuffed = I
@@ -125,7 +125,7 @@
if(!QDELETED(src))
update_inv_neck(I)
else if(I == handcuffed)
- handcuffed = null
+ set_handcuffed(null)
if(buckled && buckled.buckle_requires_restraints)
buckled.unbuckle_mob(src)
if(!QDELETED(src))
diff --git a/code/modules/mob/living/carbon/monkey/combat.dm b/code/modules/mob/living/carbon/monkey/combat.dm
index cafc5ab2d5a..add4c5e30f2 100644
--- a/code/modules/mob/living/carbon/monkey/combat.dm
+++ b/code/modules/mob/living/carbon/monkey/combat.dm
@@ -129,7 +129,7 @@
/mob/living/carbon/monkey/proc/handle_combat()
if(pickupTarget)
- if(IsDeadOrIncap() || restrained() || blacklistItems[pickupTarget] || HAS_TRAIT(pickupTarget, TRAIT_NODROP))
+ if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED) || IsDeadOrIncap() || blacklistItems[pickupTarget] || HAS_TRAIT(pickupTarget, TRAIT_NODROP))
pickupTarget = null
else
pickupTimer++
diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm
index 6f11b5872e4..f39903603fd 100644
--- a/code/modules/mob/living/carbon/monkey/life.dm
+++ b/code/modules/mob/living/carbon/monkey/life.dm
@@ -11,7 +11,7 @@
if(!client)
if(stat == CONSCIOUS)
- if(on_fire || buckled || restrained())
+ if(on_fire || buckled || HAS_TRAIT(src, TRAIT_RESTRAINED) || (pulledby && pulledby.grab_state > GRAB_PASSIVE))
if(!resisting && prob(MONKEY_RESIST_PROB))
resisting = TRUE
walk_to(src,0)
diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm
index 33cbe505e6e..8d5a223dca8 100644
--- a/code/modules/mob/living/emote.dm
+++ b/code/modules/mob/living/emote.dm
@@ -14,7 +14,7 @@
key_third_person = "bows"
message = "bows."
message_param = "bows to %t."
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/burp
key = "burp"
@@ -32,7 +32,7 @@
key = "cross"
key_third_person = "crosses"
message = "crosses their arms."
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/chuckle
key = "chuckle"
@@ -67,7 +67,7 @@
key = "dance"
key_third_person = "dances"
message = "dances around happily."
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/deathgasp
key = "deathgasp"
@@ -116,7 +116,7 @@
key = "flap"
key_third_person = "flaps"
message = "flaps their wings."
- restraint_check = TRUE
+ hands_use_check = TRUE
var/wing_time = 20
/datum/emote/living/flap/run_emote(mob/user, params, type_override, intentional)
@@ -136,7 +136,7 @@
key = "aflap"
key_third_person = "aflaps"
message = "flaps their wings ANGRILY!"
- restraint_check = TRUE
+ hands_use_check = TRUE
wing_time = 10
/datum/emote/living/frown
@@ -191,7 +191,7 @@
key = "jump"
key_third_person = "jumps"
message = "jumps!"
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/kiss
key = "kiss"
@@ -240,7 +240,7 @@
key_third_person = "points"
message = "points."
message_param = "points at %t."
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/point/run_emote(mob/user, params, type_override, intentional)
message_param = initial(message_param) // reset
diff --git a/code/modules/mob/living/init_signals.dm b/code/modules/mob/living/init_signals.dm
index 6b688df2ec4..dd4c88b3355 100644
--- a/code/modules/mob/living/init_signals.dm
+++ b/code/modules/mob/living/init_signals.dm
@@ -6,6 +6,12 @@
RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_DEATHCOMA), .proc/on_deathcoma_trait_gain)
RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_DEATHCOMA), .proc/on_deathcoma_trait_loss)
+ RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_IMMOBILIZED), .proc/on_immobilized_trait_gain)
+ RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_IMMOBILIZED), .proc/on_immobilized_trait_loss)
+
+ RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_HANDS_BLOCKED), .proc/on_handsblocked_trait_gain)
+ RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_HANDS_BLOCKED), .proc/on_handsblocked_trait_loss)
+
RegisterSignal(src, list(
SIGNAL_ADDTRAIT(TRAIT_CRITICAL_CONDITION),
SIGNAL_REMOVETRAIT(TRAIT_CRITICAL_CONDITION),
@@ -14,6 +20,7 @@
SIGNAL_REMOVETRAIT(TRAIT_NODEATH),
), .proc/update_succumb_action)
+
///Called when TRAIT_KNOCKEDOUT is added to the mob.
/mob/living/proc/on_knockedout_trait_gain(datum/source)
if(stat < UNCONSCIOUS)
@@ -33,6 +40,26 @@
/mob/living/proc/on_deathcoma_trait_loss(datum/source)
REMOVE_TRAIT(src, TRAIT_KNOCKEDOUT, TRAIT_DEATHCOMA)
+
+///Called when TRAIT_IMMOBILIZED is added to the mob.
+/mob/living/proc/on_immobilized_trait_gain(datum/source)
+ mobility_flags &= ~MOBILITY_MOVE
+
+///Called when TRAIT_IMMOBILIZED is removed from the mob.
+/mob/living/proc/on_immobilized_trait_loss(datum/source)
+ mobility_flags |= MOBILITY_MOVE
+
+
+///Called when TRAIT_HANDS_BLOCKED is added to the mob.
+/mob/living/proc/on_handsblocked_trait_gain(datum/source)
+ mobility_flags &= ~(MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_STORAGE)
+ drop_all_held_items()
+
+///Called when TRAIT_HANDS_BLOCKED is removed from the mob.
+/mob/living/proc/on_handsblocked_trait_loss(datum/source)
+ mobility_flags |= (MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_STORAGE)
+
+
/// Called when traits that alter succumbing are added/removed.
/// Will show or hide the succumb alert prompt.
/mob/living/proc/update_succumb_action()
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 152bcfe670c..d8489b8a026 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -94,7 +94,7 @@
ContactContractDisease(D)
//Should stop you pushing a restrained person out of the way
- if(L.pulledby && L.pulledby != src && L.restrained())
+ if(L.pulledby && L.pulledby != src && HAS_TRAIT(L, TRAIT_RESTRAINED))
if(!(world.time % 5))
to_chat(src, "[L] is restrained, you cannot push past.")
return TRUE
@@ -102,7 +102,7 @@
if(L.pulling)
if(ismob(L.pulling))
var/mob/P = L.pulling
- if(P.restrained())
+ if(HAS_TRAIT(P, TRAIT_RESTRAINED))
if(!(world.time % 5))
to_chat(src, "[L] is restraining [P], you cannot push past.")
return TRUE
@@ -138,8 +138,8 @@
mob_swap = TRUE
else if(
!(HAS_TRAIT(M, TRAIT_NOMOBSWAP) || HAS_TRAIT(src, TRAIT_NOMOBSWAP))&&\
- ((M.restrained() && !too_strong) || M.a_intent == INTENT_HELP) &&\
- (restrained() || a_intent == INTENT_HELP)
+ ((HAS_TRAIT(M, TRAIT_RESTRAINED) && !too_strong) || M.a_intent == INTENT_HELP) &&\
+ (HAS_TRAIT(src, TRAIT_RESTRAINED) || a_intent == INTENT_HELP)
)
mob_swap = TRUE
if(mob_swap)
@@ -401,7 +401,7 @@
death()
/mob/living/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, ignore_stasis = FALSE)
- if(stat || HAS_TRAIT(src, TRAIT_INCAPACITATED) || (!ignore_restraints && restrained(ignore_grab)) || (!ignore_stasis && IS_IN_STASIS(src)))
+ if(stat || HAS_TRAIT(src, TRAIT_INCAPACITATED) || (!ignore_restraints && (HAS_TRAIT(src, TRAIT_RESTRAINED) || (!ignore_grab && pulledby && pulledby.grab_state >= GRAB_AGGRESSIVE))) || (!ignore_stasis && IS_IN_STASIS(src)))
return TRUE
/mob/living/canUseStorage()
@@ -786,7 +786,7 @@
SEND_SIGNAL(src, COMSIG_LIVING_RESIST, src)
//resisting grabs (as if it helps anyone...)
- if(!restrained(ignore_grab = 1) && pulledby)
+ if(!HAS_TRAIT(src, TRAIT_RESTRAINED) && pulledby)
log_combat(src, pulledby, "resisted grab")
resist_grab()
return
@@ -1193,19 +1193,9 @@
return ..() && !(buckled && buckled.buckle_prevents_pull)
-//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
+//Updates lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
//Robots, animals and brains have their own version so don't worry about them
/mob/living/proc/update_mobility()
- var/stat_softcrit = stat == SOFT_CRIT
- var/stat_conscious = (stat == CONSCIOUS) || stat_softcrit
- var/chokehold = pulledby && pulledby.grab_state >= GRAB_NECK
- var/restrained = restrained()
- var/paralyzed = IsParalyzed()
- var/canmove = !HAS_TRAIT(src, TRAIT_IMMOBILIZED)
- if(canmove)
- mobility_flags |= MOBILITY_MOVE
- else
- mobility_flags &= ~MOBILITY_MOVE
var/canstand_involuntary = !HAS_TRAIT(src, TRAIT_FLOORED)
var/canstand = canstand_involuntary && !resting
@@ -1225,18 +1215,11 @@
mobility_flags |= MOBILITY_STAND
set_lying_angle(0)
- if(lying_angle != 0 || restrained || incapacitated())
+ if(lying_angle != 0 || HAS_TRAIT(src, TRAIT_HANDS_BLOCKED) || incapacitated())
mobility_flags &= ~(MOBILITY_UI|MOBILITY_PULL)
else
mobility_flags |= MOBILITY_UI|MOBILITY_PULL
- var/canitem = !paralyzed && !IsStun() && stat_conscious && !chokehold && !restrained && usable_hands
- if(canitem)
- mobility_flags |= (MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_STORAGE)
- else
- mobility_flags &= ~(MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_STORAGE)
- if(!(mobility_flags & MOBILITY_USE))
- drop_all_held_items()
if(!(mobility_flags & MOBILITY_PULL))
if(pulling)
stop_pulling()
@@ -1636,10 +1619,12 @@
if(CONSCIOUS)
if(stat >= UNCONSCIOUS)
ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT)
+ ADD_TRAIT(src, TRAIT_HANDS_BLOCKED, TRAIT_KNOCKEDOUT)
ADD_TRAIT(src, TRAIT_FLOORED, UNCONSCIOUS_TRAIT)
if(SOFT_CRIT)
if(stat >= UNCONSCIOUS)
ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT) //adding trait sources should come before removing to avoid unnecessary updates
+ ADD_TRAIT(src, TRAIT_HANDS_BLOCKED, TRAIT_KNOCKEDOUT)
if(pulledby)
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, PULLED_WHILE_SOFTCRIT_TRAIT)
if(UNCONSCIOUS)
@@ -1652,6 +1637,7 @@
if(CONSCIOUS)
if(. >= UNCONSCIOUS)
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT)
+ REMOVE_TRAIT(src, TRAIT_HANDS_BLOCKED, TRAIT_KNOCKEDOUT)
REMOVE_TRAIT(src, TRAIT_FLOORED, UNCONSCIOUS_TRAIT)
REMOVE_TRAIT(src, TRAIT_CRITICAL_CONDITION, STAT_TRAIT)
if(SOFT_CRIT)
@@ -1659,6 +1645,7 @@
ADD_TRAIT(src, TRAIT_IMMOBILIZED, PULLED_WHILE_SOFTCRIT_TRAIT) //adding trait sources should come before removing to avoid unnecessary updates
if(. >= UNCONSCIOUS)
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT)
+ REMOVE_TRAIT(src, TRAIT_HANDS_BLOCKED, TRAIT_KNOCKEDOUT)
ADD_TRAIT(src, TRAIT_CRITICAL_CONDITION, STAT_TRAIT)
if(UNCONSCIOUS)
if(. != HARD_CRIT)
@@ -1703,6 +1690,20 @@
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, PULLED_WHILE_SOFTCRIT_TRAIT)
+/// Updates the grab state of the mob and updates movespeed
+/mob/living/setGrabState(newstate)
+ . = ..()
+ switch(grab_state)
+ if(GRAB_PASSIVE)
+ remove_movespeed_modifier(MOVESPEED_ID_MOB_GRAB_STATE)
+ if(GRAB_AGGRESSIVE)
+ add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/aggressive)
+ if(GRAB_NECK)
+ add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/neck)
+ if(GRAB_KILL)
+ add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/kill)
+
+
/// Only defined for carbons who can wear masks and helmets, we just assume other mobs have visible faces
/mob/living/proc/is_face_visible()
return TRUE
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 415a8b4fd6f..5bb745c4704 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -372,8 +372,6 @@
else
mobility_flags = ALL
-/mob/living/silicon/ai/restrained(ignore_grab)
- . = 0
/mob/living/silicon/ai/Topic(href, href_list)
..()
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index 0f20e8455e7..d7b8b0bc1b7 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -200,8 +200,6 @@
else
. += text("Systems nonfunctional")
-/mob/living/silicon/pai/restrained(ignore_grab)
- . = FALSE
// See software.dm for Topic()
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index c34a42a35ef..b240f6a65d7 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -336,8 +336,6 @@
if(connected_ai)
. += "Master AI: [connected_ai.name]"
-/mob/living/silicon/robot/restrained(ignore_grab)
- return
/mob/living/silicon/robot/triggerAlarm(class, area/A, O, obj/alarmsource)
if(alarmsource.z != z)
diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm
index 215721d6e2e..eb8b06ca6f5 100644
--- a/code/modules/mob/living/simple_animal/bot/secbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/secbot.dm
@@ -265,7 +265,7 @@ Auto Patrol: []"},
if( !on || !Adjacent(C) || !isturf(C.loc) ) //if he's in a closet or not adjacent, we cancel cuffing.
return
if(!C.handcuffed)
- C.handcuffed = new /obj/item/restraints/handcuffs/cable/zipties/used(C)
+ C.set_handcuffed(new /obj/item/restraints/handcuffs/cable/zipties/used(C))
C.update_handcuffed()
playsound(src, "law", 50, FALSE)
back_to_idle()
diff --git a/code/modules/mob/living/simple_animal/hostile/ooze.dm b/code/modules/mob/living/simple_animal/hostile/ooze.dm
index a20fb00aae3..cd05aa9917f 100644
--- a/code/modules/mob/living/simple_animal/hostile/ooze.dm
+++ b/code/modules/mob/living/simple_animal/hostile/ooze.dm
@@ -151,7 +151,7 @@
background_icon_state = "bg_hive"
icon_icon = 'icons/mob/actions/actions_slime.dmi'
button_icon_state = "metabolic_boost"
- check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_STUN
+ check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_IMMOBILE
cooldown_time = 24 SECONDS
var/nutrition_cost = 10
var/active = FALSE
@@ -200,7 +200,7 @@
background_icon_state = "bg_hive"
icon_icon = 'icons/mob/actions/actions_slime.dmi'
button_icon_state = "consume"
- check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_STUN
+ check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_IMMOBILE
///The mob thats being consumed by this creature
var/mob/living/vored_mob
@@ -426,7 +426,7 @@
background_icon_state = "bg_hive"
icon_icon = 'icons/mob/actions/actions_slime.dmi'
button_icon_state = "gel_cocoon"
- check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_STUN
+ check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_IMMOBILE
cooldown_time = 10 SECONDS
///Try to put the pulled mob in a cocoon
diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm
index 722ebf0e5ff..70f520ca9b3 100644
--- a/code/modules/mob/living/simple_animal/hostile/statue.dm
+++ b/code/modules/mob/living/simple_animal/hostile/statue.dm
@@ -232,8 +232,3 @@
/mob/living/simple_animal/hostile/statue/sentience_act()
faction -= "neutral"
-
-/mob/living/simple_animal/hostile/statue/restrained(ignore_grab)
- . = ..()
- if(can_be_seen(loc))
- return 1
diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm
index bd861ad9131..2456ce6fe54 100644
--- a/code/modules/mob/living/ventcrawling.dm
+++ b/code/modules/mob/living/ventcrawling.dm
@@ -11,11 +11,11 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list(
if(stat)
to_chat(src, "You must be conscious to do this!")
return
- if(IsStun() || IsParalyzed())
- to_chat(src, "You can't vent crawl while you're stunned!")
+ if(HAS_TRAIT(src, TRAIT_IMMOBILIZED))
+ to_chat(src, "You can't move into the vent!")
return
- if(restrained())
- to_chat(src, "You can't vent crawl while you're restrained!")
+ if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
+ to_chat(src, "You need to be able to use your hands to ventcrawl!")
return
if(has_buckled_mobs())
to_chat(src, "You can't vent crawl with other creatures on you!")
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index ecbd3cc56f7..e44698a4011 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -285,9 +285,6 @@
/mob/proc/get_item_by_slot(slot_id)
return null
-///Is the mob restrained
-/mob/proc/restrained(ignore_grab)
- return
///Is the mob incapacitated
/mob/proc/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, ignore_stasis = FALSE)
@@ -870,7 +867,7 @@
return FALSE
if(notransform)
return FALSE
- if(restrained())
+ if(HAS_TRAIT(src, TRAIT_RESTRAINED))
return FALSE
return TRUE
@@ -1309,19 +1306,6 @@
update_movespeed(FALSE)
-/// Updates the grab state of the mob and updates movespeed
-/mob/setGrabState(newstate)
- . = ..()
- switch(grab_state)
- if(GRAB_PASSIVE)
- remove_movespeed_modifier(MOVESPEED_ID_MOB_GRAB_STATE)
- if(GRAB_AGGRESSIVE)
- add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/aggressive)
- if(GRAB_NECK)
- add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/neck)
- if(GRAB_KILL)
- add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/kill)
-
/mob/proc/update_equipment_speed_mods()
var/speedies = equipped_speed_mods()
if(!speedies)
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index a74fce35c09..b7c3145b9a4 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -170,7 +170,7 @@
if(mob.incapacitated(ignore_restraints = 1))
move_delay = world.time + 10
return TRUE
- else if(mob.restrained(ignore_grab = 1))
+ else if(HAS_TRAIT(mob, TRAIT_RESTRAINED))
move_delay = world.time + 10
to_chat(src, "You're restrained! You can't move!")
return TRUE
diff --git a/code/modules/modular_computers/computers/item/laptop.dm b/code/modules/modular_computers/computers/item/laptop.dm
index a5d2a7ed170..9bf0cd5a3ec 100644
--- a/code/modules/modular_computers/computers/item/laptop.dm
+++ b/code/modules/modular_computers/computers/item/laptop.dm
@@ -64,14 +64,16 @@
. = ..()
if(over_object == usr || over_object == src)
try_toggle_open(usr)
- else if(istype(over_object, /obj/screen/inventory/hand))
+ return
+ if(istype(over_object, /obj/screen/inventory/hand))
var/obj/screen/inventory/hand/H = over_object
var/mob/M = usr
- if(!M.restrained() && !M.stat)
- if(!isturf(loc) || !Adjacent(M))
- return
- M.put_in_hand(src, H.held_index)
+ if(M.stat != CONSCIOUS || HAS_TRAIT(M, TRAIT_HANDS_BLOCKED))
+ return
+ if(!isturf(loc) || !Adjacent(M))
+ return
+ M.put_in_hand(src, H.held_index)
/obj/item/modular_computer/laptop/attack_hand(mob/user)
. = ..()
diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm
index 437d8f676bb..98a92217bbc 100644
--- a/code/modules/paperwork/clipboard.dm
+++ b/code/modules/paperwork/clipboard.dm
@@ -70,7 +70,7 @@
/obj/item/clipboard/Topic(href, href_list)
..()
- if(usr.stat || usr.restrained())
+ if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(usr.contents.Find(src))
diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm
index 305099d1159..633ede44af3 100644
--- a/code/modules/paperwork/folders.dm
+++ b/code/modules/paperwork/folders.dm
@@ -76,7 +76,7 @@
/obj/item/folder/Topic(href, href_list)
..()
- if(usr.stat || usr.restrained())
+ if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(usr.contents.Find(src))
diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm
index 01442f1bf9e..6f8c212ce8c 100644
--- a/code/modules/power/singularity/emitter.dm
+++ b/code/modules/power/singularity/emitter.dm
@@ -413,7 +413,7 @@
auto.Grant(M, src)
/datum/action/innate/protoemitter
- check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUN | AB_CHECK_CONSCIOUS
+ check_flags = AB_CHECK_HANDS_BLOCKED | AB_CHECK_IMMOBILE | AB_CHECK_CONSCIOUS
var/obj/machinery/power/emitter/prototype/PE
var/mob/living/carbon/U
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 46bcbdcd6e2..9757477f9ff 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -655,7 +655,7 @@
/datum/action/toggle_scope_zoom
name = "Toggle Scope"
- check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_LYING
+ check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_HANDS_BLOCKED|AB_CHECK_IMMOBILE|AB_CHECK_LYING
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "sniper_zoom"
var/obj/item/gun/gun = null
diff --git a/code/modules/research/nanites/nanite_programs/utility.dm b/code/modules/research/nanites/nanite_programs/utility.dm
index 48641cc2437..72ca34e6350 100644
--- a/code/modules/research/nanites/nanite_programs/utility.dm
+++ b/code/modules/research/nanites/nanite_programs/utility.dm
@@ -346,7 +346,7 @@
/datum/action/innate/nanite_button
name = "Button"
icon_icon = 'icons/mob/actions/actions_items.dmi'
- check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_CONSCIOUS
+ check_flags = AB_CHECK_HANDS_BLOCKED|AB_CHECK_IMMOBILE|AB_CHECK_CONSCIOUS
button_icon_state = "power_green"
var/datum/nanite_program/dermal_button/program
diff --git a/code/modules/research/xenobiology/crossbreeding/prismatic.dm b/code/modules/research/xenobiology/crossbreeding/prismatic.dm
index 6b4e058c866..9cfc4542d52 100644
--- a/code/modules/research/xenobiology/crossbreeding/prismatic.dm
+++ b/code/modules/research/xenobiology/crossbreeding/prismatic.dm
@@ -116,7 +116,7 @@ Prismatic extracts:
/obj/item/slimecross/prismatic/rainbow/attack_self(mob/user)
var/newcolor = input(user, "Choose the slime color:", "Color change",paintcolor) as color|null
- if ((user.get_active_held_item() != src || user.stat || user.restrained()))
+ if(user.get_active_held_item() != src || user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(!newcolor)
return
diff --git a/code/modules/research/xenobiology/crossbreeding/selfsustaining.dm b/code/modules/research/xenobiology/crossbreeding/selfsustaining.dm
index cdb14b68b6c..3088ddd0fee 100644
--- a/code/modules/research/xenobiology/crossbreeding/selfsustaining.dm
+++ b/code/modules/research/xenobiology/crossbreeding/selfsustaining.dm
@@ -36,7 +36,7 @@ Self-sustaining extracts:
var/amount = 5
var/secondary
- if ((user.get_active_held_item() != src || user.stat || user.restrained()))
+ if (user.get_active_held_item() != src || user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(!reagentselect)
return
diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm
index 532276e1da3..5e09c7b3d98 100644
--- a/code/modules/surgery/bodyparts/dismemberment.dm
+++ b/code/modules/surgery/bodyparts/dismemberment.dm
@@ -233,7 +233,7 @@
if(C.handcuffed)
C.handcuffed.forceMove(drop_location())
C.handcuffed.dropped(C)
- C.handcuffed = null
+ C.set_handcuffed(null)
C.update_handcuffed()
if(C.hud_used)
var/obj/screen/inventory/hand/R = C.hud_used.hand_slots["[held_index]"]
@@ -251,7 +251,7 @@
if(C.handcuffed)
C.handcuffed.forceMove(drop_location())
C.handcuffed.dropped(C)
- C.handcuffed = null
+ C.set_handcuffed(null)
C.update_handcuffed()
if(C.hud_used)
var/obj/screen/inventory/hand/L = C.hud_used.hand_slots["[held_index]"]
diff --git a/code/modules/swarmers/swarmer.dm b/code/modules/swarmers/swarmer.dm
index 05d92defe56..133e05968e3 100644
--- a/code/modules/swarmers/swarmer.dm
+++ b/code/modules/swarmers/swarmer.dm
@@ -243,7 +243,7 @@
if(ishuman(target))
var/mob/living/carbon/human/victim = target
if(!victim.handcuffed)
- victim.handcuffed = new /obj/item/restraints/handcuffs/energy/used(victim)
+ victim.set_handcuffed(new /obj/item/restraints/handcuffs/energy/used(victim))
victim.update_handcuffed()
log_combat(src, victim, "handcuffed")
diff --git a/code/modules/vehicles/cars/car.dm b/code/modules/vehicles/cars/car.dm
index d222d1d3e33..860d526a78f 100644
--- a/code/modules/vehicles/cars/car.dm
+++ b/code/modules/vehicles/cars/car.dm
@@ -33,7 +33,7 @@
return TRUE
/obj/vehicle/sealed/car/MouseDrop_T(atom/dropping, mob/M)
- if(M.stat || M.restrained())
+ if(M.stat != CONSCIOUS || HAS_TRAIT(M, TRAIT_HANDS_BLOCKED))
return FALSE
if((car_traits & CAN_KIDNAP) && isliving(dropping) && M != dropping)
var/mob/living/L = dropping
diff --git a/code/modules/vehicles/vehicle_actions.dm b/code/modules/vehicles/vehicle_actions.dm
index 4b3157ac24f..af66d0927b8 100644
--- a/code/modules/vehicles/vehicle_actions.dm
+++ b/code/modules/vehicles/vehicle_actions.dm
@@ -92,7 +92,7 @@
/***************** ACTION DATUMS *****************/
/datum/action/vehicle
- check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUN | AB_CHECK_CONSCIOUS
+ check_flags = AB_CHECK_HANDS_BLOCKED | AB_CHECK_IMMOBILE | AB_CHECK_CONSCIOUS
icon_icon = 'icons/mob/actions/actions_vehicle.dmi'
button_icon_state = "vehicle_eject"
var/obj/vehicle/vehicle_target
diff --git a/modular_skyrat/modules/emotes/code/emotes.dm b/modular_skyrat/modules/emotes/code/emotes.dm
index e9a64120120..378ad15a82b 100644
--- a/modular_skyrat/modules/emotes/code/emotes.dm
+++ b/modular_skyrat/modules/emotes/code/emotes.dm
@@ -4,7 +4,7 @@
message = "rustles their quills."
emote_type = EMOTE_AUDIBLE
muzzle_ignore = TRUE
- restraint_check = FALSE
+ hands_use_check = FALSE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/quill/run_emote(mob/living/user, params)
@@ -82,7 +82,7 @@
message = "peeps like a bird!"
emote_type = EMOTE_AUDIBLE
muzzle_ignore = FALSE
- restraint_check = FALSE
+ hands_use_check = FALSE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/peep/run_emote(mob/living/user, params)
@@ -99,7 +99,7 @@
message = "peeps twice like a bird!"
emote_type = EMOTE_AUDIBLE
muzzle_ignore = FALSE
- restraint_check = FALSE
+ hands_use_check = FALSE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/peep2/run_emote(mob/living/user, params)
@@ -123,7 +123,7 @@
message = "snaps their fingers."
emote_type = EMOTE_AUDIBLE
muzzle_ignore = TRUE
- restraint_check = TRUE
+ hands_use_check = TRUE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/snap/run_emote(mob/living/user, params)
@@ -140,7 +140,7 @@
message = "snaps twice."
emote_type = EMOTE_AUDIBLE
muzzle_ignore = TRUE
- restraint_check = TRUE
+ hands_use_check = TRUE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/snap2/run_emote(mob/living/user, params)
@@ -157,7 +157,7 @@
message = "snaps thrice."
emote_type = EMOTE_AUDIBLE
muzzle_ignore = TRUE
- restraint_check = TRUE
+ hands_use_check = TRUE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/snap3/run_emote(mob/living/user, params)
@@ -174,7 +174,7 @@
message = "lets out an awoo!"
emote_type = EMOTE_AUDIBLE
muzzle_ignore = FALSE
- restraint_check = FALSE
+ hands_use_check = FALSE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/awoo/run_emote(mob/living/user, params)
@@ -191,7 +191,7 @@
message = "lets out a nya!"
emote_type = EMOTE_AUDIBLE
muzzle_ignore = FALSE
- restraint_check = FALSE
+ hands_use_check = FALSE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/nya/run_emote(mob/living/user, params)
@@ -208,7 +208,7 @@
message = "lets out a weh!"
emote_type = EMOTE_AUDIBLE
muzzle_ignore = FALSE
- restraint_check = FALSE
+ hands_use_check = FALSE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/weh/run_emote(mob/living/user, params)
@@ -224,7 +224,7 @@
key_third_person = "suddenly hits a dab"
message = "suddenly hits a dab!"
emote_type = EMOTE_AUDIBLE
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/mothsqueak
key = "msqueak"
@@ -232,7 +232,7 @@
message = "lets out a tiny squeak!"
emote_type = EMOTE_AUDIBLE
muzzle_ignore = FALSE
- restraint_check = FALSE
+ hands_use_check = FALSE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/mothsqueak/run_emote(mob/living/user, params)
@@ -249,7 +249,7 @@
message = "merps!"
emote_type = EMOTE_AUDIBLE
muzzle_ignore = FALSE
- restraint_check = FALSE
+ hands_use_check = FALSE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/merp/run_emote(mob/living/user, params)
@@ -266,7 +266,7 @@
message = "barks!"
emote_type = EMOTE_AUDIBLE
muzzle_ignore = FALSE
- restraint_check = FALSE
+ hands_use_check = FALSE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/bark/run_emote(mob/living/user, params)
@@ -284,7 +284,7 @@
message = "squishes!"
emote_type = EMOTE_AUDIBLE
muzzle_ignore = FALSE
- restraint_check = FALSE
+ hands_use_check = FALSE
mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
/datum/emote/living/squish/run_emote(mob/living/user, params)