From 8fbecaf435b67ad8b85adeb4f63dbec3dbed9f33 Mon Sep 17 00:00:00 2001
From: Zwei <35403274+Gottfrei@users.noreply.github.com>
Date: Sat, 11 May 2024 22:20:54 +0300
Subject: [PATCH] add/refactor: Hands Blocked Trait (#4977)
Hands Blocked Trait
---
code/__DEFINES/alerts.dm | 7 +-
code/__DEFINES/traits/sources.dm | 2 +
code/__HELPERS/mobs.dm | 2 +-
code/_onclick/ai.dm | 10 +-
code/_onclick/click.dm | 6 +-
code/_onclick/cyborg.dm | 13 +-
code/_onclick/hud/screen_objects.dm | 4 +-
code/_onclick/other_mobs.dm | 60 ++++-
code/controllers/subsystem/afk.dm | 2 +-
code/datums/action.dm | 25 +-
.../viruses/advance/symptoms/uncotrollable.dm | 2 +-
code/datums/emote/emote.dm | 2 +-
.../alien_spells/corrosive_acid_spit.dm | 2 +-
.../spells/alien_spells/transfer_plasma.dm | 6 +-
code/datums/spells/banana_touch.dm | 2 +-
.../spells/lavaland_spells/healtouch.dm | 2 +-
code/datums/spells/mime_malaise.dm | 2 +-
code/datums/spells/touch_attacks.dm | 3 +
code/datums/status_effects/debuffs.dm | 21 +-
code/datums/uplink_item.dm | 2 +-
code/game/atoms.dm | 2 +-
code/game/atoms_movable.dm | 10 +-
code/game/dna/dna_modifier.dm | 6 +-
code/game/dna/genes/goon_powers.dm | 17 +-
.../gamemodes/clockwork/clockwork_items.dm | 6 +-
code/game/gamemodes/cult/blood_magic.dm | 4 +-
code/game/gamemodes/cult/cult_items.dm | 2 +-
.../gamemodes/devil/true_devil/_true_devil.dm | 2 +
.../miniantags/abduction/abduction_gear.dm | 4 +-
.../abduction/machinery/experiment.dm | 2 +-
code/game/gamemodes/miniantags/borer/borer.dm | 2 +
.../gamemodes/miniantags/bot_swarm/swarmer.dm | 8 +-
.../demons/pulse_demon/pulse_demon.dm | 2 +
.../demons/shadow_demon/shadow_demon.dm | 5 +-
code/game/gamemodes/nuclear/nuclear.dm | 2 +-
code/game/gamemodes/nuclear/pinpointer.dm | 6 +-
code/game/gamemodes/revolution/revolution.dm | 2 +-
code/game/gamemodes/wizard/apprentice.dm | 12 +-
code/game/gamemodes/wizard/godhand.dm | 12 +-
code/game/machinery/OpTable.dm | 4 +-
code/game/machinery/Sleeper.dm | 10 +-
code/game/machinery/adv_med.dm | 6 +-
.../game/machinery/computer/buildandrepair.dm | 6 +-
code/game/machinery/computer/card.dm | 2 +-
code/game/machinery/computer/law.dm | 37 +--
code/game/machinery/cryo.dm | 10 +-
code/game/machinery/cryopod.dm | 6 +-
code/game/machinery/defib_mount.dm | 4 +-
code/game/machinery/deployable.dm | 2 +-
code/game/machinery/doors/door.dm | 2 +-
code/game/machinery/doors/windowdoor.dm | 2 +-
code/game/machinery/doppler_array.dm | 3 +-
code/game/machinery/iv_drip.dm | 2 +-
code/game/machinery/mass_driver.dm | 4 +-
code/game/machinery/pipe/construction.dm | 11 +-
code/game/machinery/pipe/pipe_dispenser.dm | 2 +-
code/game/machinery/rechargestation.dm | 2 +-
code/game/machinery/recycler.dm | 4 +-
code/game/machinery/suit_storage_unit.dm | 6 +-
code/game/machinery/washing_machine.dm | 2 +-
code/game/mecha/mecha.dm | 2 +-
code/game/objects/buckling.dm | 2 +-
code/game/objects/items.dm | 49 ++--
code/game/objects/items/bodybag.dm | 2 +-
code/game/objects/items/crayons.dm | 2 +-
code/game/objects/items/devices/flashlight.dm | 6 +-
code/game/objects/items/devices/pizza_bomb.dm | 4 +-
.../objects/items/devices/radio/beacon.dm | 2 +-
.../game/objects/items/devices/radio/radio.dm | 8 +-
code/game/objects/items/devices/scanners.dm | 3 +
.../items/devices/scanners/gas_analyzer.dm | 6 +-
.../objects/items/devices/sensor_device.dm | 2 +-
.../objects/items/devices/taperecorder.dm | 4 +-
code/game/objects/items/devices/tts.dm | 17 +-
code/game/objects/items/flag.dm | 2 +-
code/game/objects/items/stacks/stack.dm | 12 +-
code/game/objects/items/toys.dm | 13 +-
code/game/objects/items/weapons/cards_ids.dm | 13 +-
code/game/objects/items/weapons/cigs.dm | 2 +-
code/game/objects/items/weapons/defib.dm | 5 +-
.../objects/items/weapons/flamethrower.dm | 8 +-
code/game/objects/items/weapons/handcuffs.dm | 51 ++--
code/game/objects/items/weapons/holosign.dm | 4 +-
.../items/weapons/implants/implantchair.dm | 4 +-
.../items/weapons/implants/implantpad.dm | 2 +-
code/game/objects/items/weapons/legcuffs.dm | 8 +-
.../objects/items/weapons/melee/energy.dm | 2 +-
code/game/objects/items/weapons/rpd.dm | 4 +-
code/game/objects/items/weapons/scrolls.dm | 4 +-
code/game/objects/items/weapons/staff.dm | 2 +-
.../items/weapons/storage/artistic_toolbox.dm | 2 +-
.../objects/items/weapons/storage/backpack.dm | 4 +-
.../objects/items/weapons/storage/bags.dm | 4 +-
.../objects/items/weapons/storage/belt.dm | 4 +-
.../objects/items/weapons/storage/firstaid.dm | 2 +-
.../objects/items/weapons/storage/internal.dm | 2 +-
.../objects/items/weapons/storage/secure.dm | 8 +-
.../objects/items/weapons/storage/storage.dm | 4 +-
.../objects/items/weapons/tanks/watertank.dm | 7 +-
.../objects/items/weapons/teleportation.dm | 2 +-
code/game/objects/structures.dm | 2 +-
code/game/objects/structures/coathanger.dm | 2 +-
.../structures/crates_lockers/closets.dm | 6 +-
.../closets/secure/secure_closets.dm | 19 +-
.../structures/crates_lockers/crates.dm | 18 +-
code/game/objects/structures/electricchair.dm | 2 +-
code/game/objects/structures/extinguisher.dm | 6 +-
code/game/objects/structures/inflatable.dm | 8 +-
code/game/objects/structures/morgue.dm | 18 +-
code/game/objects/structures/noticeboard.dm | 4 +-
code/game/objects/structures/pit.dm | 2 +-
code/game/objects/structures/railings.dm | 9 +-
code/game/objects/structures/reflector.dm | 17 +-
code/game/objects/structures/snow.dm | 2 +-
code/game/objects/structures/spirit_board.dm | 2 +-
code/game/objects/structures/stairs.dm | 5 +-
code/game/objects/structures/statues.dm | 6 +-
.../stool_bed_chair_nest/alien_nests.dm | 2 +
.../structures/stool_bed_chair_nest/bed.dm | 2 +-
.../structures/stool_bed_chair_nest/chairs.dm | 10 +-
code/game/objects/structures/tables_racks.dm | 6 +-
code/game/objects/structures/tribune.dm | 3 +
.../objects/structures/windoor_assembly.dm | 13 +-
code/game/objects/structures/window.dm | 12 +-
code/game/verbs/suicide.dm | 5 -
.../changeling/powers/biodegrade.dm | 2 +-
.../machinery/ninja_mindscan_machine.dm | 2 +-
.../ninja_spirit_form.dm | 3 +-
code/modules/antagonists/thief/thief_kit.dm | 6 +-
.../contractor/items/contractor_baton.dm | 2 +-
code/modules/assembly/health.dm | 2 +-
code/modules/assembly/infrared.dm | 4 +-
code/modules/assembly/mousetrap.dm | 2 +-
code/modules/assembly/proximity.dm | 2 +-
code/modules/assembly/signaler.dm | 4 +-
code/modules/assembly/timer.dm | 2 +-
.../components/binary_devices/pump.dm | 19 +-
.../components/binary_devices/volume_pump.dm | 16 +-
.../components/trinary_devices/filter.dm | 16 +-
.../components/trinary_devices/mixer.dm | 16 +-
.../portable/portable_atmospherics.dm | 8 +-
.../mission_code/ruins/USSP_gorky17.dm | 4 +-
code/modules/clothing/clothing.dm | 76 +++---
code/modules/clothing/head/hardhat.dm | 2 +-
code/modules/clothing/head/soft_caps.dm | 2 +-
code/modules/clothing/masks/breath.dm | 6 +-
code/modules/clothing/neck/ponchos.dm | 30 +--
code/modules/clothing/shoes/magboots.dm | 2 +-
code/modules/clothing/shoes/miscellaneous.dm | 4 +-
code/modules/clothing/spacesuits/hardsuit.dm | 4 +
code/modules/clothing/spacesuits/plasmamen.dm | 5 +-
code/modules/clothing/suits/hood.dm | 4 +
.../clothing/under/accessories/accessory.dm | 8 +-
.../clothing/under/accessories/holster.dm | 5 +-
code/modules/customitems/item_defines.dm | 12 +-
.../detectivework/microscope/dnascanner.dm | 6 +-
.../detectivework/microscope/microscope.dm | 6 +-
.../detectivework/tools/sample_kits.dm | 4 +-
code/modules/economy/EFTPOS.dm | 8 +-
code/modules/fish/fishtank.dm | 4 +-
code/modules/food_and_drinks/drinks/drinks.dm | 2 +-
.../food_and_drinks/drinks/drinks/cans.dm | 6 +-
.../drinks/drinks/shotglass.dm | 2 +-
code/modules/food_and_drinks/food/snacks.dm | 6 +-
.../kitchen_machinery/gibber.dm | 4 +-
.../kitchen_machinery/smartfridge.dm | 4 +-
code/modules/games/cards.dm | 43 +--
code/modules/hydroponics/hydroitemdefines.dm | 2 +-
code/modules/hydroponics/hydroponics.dm | 10 +-
.../instruments/objs/items/headphones.dm | 2 +-
.../instruments/objs/structures/drumkit.dm | 11 +-
.../mining/equipment/marker_beacons.dm | 8 +-
.../mining/equipment/mineral_scanner.dm | 4 +
code/modules/mining/fulton.dm | 2 +-
.../mining/lavaland/loot/hierophant_loot.dm | 2 +-
.../mining/lavaland/loot/tendril_loot.dm | 2 +-
code/modules/mining/satchel_ore_boxdm.dm | 2 +-
code/modules/mob/dead/observer/observer.dm | 15 --
code/modules/mob/holder.dm | 2 +-
code/modules/mob/holder_pet_carrier.dm | 10 +-
code/modules/mob/inventory.dm | 10 +-
code/modules/mob/living/carbon/alien/alien.dm | 4 -
.../living/carbon/alien/humanoid/humanoid.dm | 14 +-
.../living/carbon/alien/humanoid/inventory.dm | 4 +-
.../mob/living/carbon/alien/larva/larva.dm | 16 +-
code/modules/mob/living/carbon/carbon.dm | 26 +-
.../mob/living/carbon/carbon_defense.dm | 14 +-
code/modules/mob/living/carbon/give.dm | 10 +-
code/modules/mob/living/carbon/human/human.dm | 37 +--
.../mob/living/carbon/human/human_emote.dm | 2 +-
.../living/carbon/human/human_interaction.dm | 6 +-
.../mob/living/carbon/human/human_movement.dm | 13 +-
.../mob/living/carbon/human/inventory.dm | 8 +-
code/modules/mob/living/carbon/human/life.dm | 2 +-
.../mob/living/carbon/human/species/wryn.dm | 4 +-
.../mob/living/carbon/human/update_icons.dm | 1 -
code/modules/mob/living/carbon/inventory.dm | 247 ++++++++----------
code/modules/mob/living/init_signals.dm | 33 +++
code/modules/mob/living/living.dm | 32 ++-
code/modules/mob/living/living_defense.dm | 2 +-
code/modules/mob/living/silicon/ai/ai.dm | 2 -
code/modules/mob/living/silicon/pai/pai.dm | 9 +-
.../living/silicon/robot/drone/drone_items.dm | 3 +-
.../modules/mob/living/silicon/robot/robot.dm | 2 -
code/modules/mob/living/silicon/silicon.dm | 13 +
.../mob/living/simple_animal/bot/cleanbot.dm | 2 +
.../mob/living/simple_animal/bot/ed209bot.dm | 8 +-
.../mob/living/simple_animal/bot/floorbot.dm | 2 +
.../mob/living/simple_animal/bot/griefsky.dm | 2 +-
.../mob/living/simple_animal/bot/honkbot.dm | 2 +-
.../mob/living/simple_animal/bot/medbot.dm | 2 +
.../mob/living/simple_animal/bot/mulebot.dm | 7 +-
.../mob/living/simple_animal/bot/secbot.dm | 8 +-
.../mob/living/simple_animal/bot/syndicate.dm | 2 +-
.../living/simple_animal/friendly/diona.dm | 4 +-
.../living/simple_animal/hostile/statue.dm | 5 +-
.../mob/living/simple_animal/parrot.dm | 2 +-
code/modules/mob/living/update_status.dm | 2 +-
code/modules/mob/mob.dm | 5 +-
code/modules/mob/mob_movement.dm | 6 +-
code/modules/mob/update_status.dm | 7 -
code/modules/newscaster/obj/newscaster.dm | 2 +-
code/modules/newscaster/obj/newspaper.dm | 2 +-
code/modules/paperwork/carbonpaper.dm | 3 +
code/modules/paperwork/clipboard.dm | 8 +-
code/modules/paperwork/desk_bell.dm | 2 +-
code/modules/paperwork/faxmachine.dm | 2 +-
code/modules/paperwork/folders.dm | 2 +-
code/modules/paperwork/paper.dm | 4 +-
code/modules/paperwork/paper_bundle.dm | 2 +-
code/modules/paperwork/papershredder.dm | 2 +-
code/modules/paperwork/photocopier.dm | 10 +-
code/modules/paperwork/photography.dm | 14 +-
code/modules/pda/PDA.dm | 29 +-
code/modules/power/apc.dm | 6 +-
code/modules/power/singularity/emitter.dm | 23 +-
.../particle_accelerator.dm | 4 +-
code/modules/projectiles/gun.dm | 6 +-
code/modules/projectiles/guns/energy.dm | 4 +-
.../projectiles/guns/projectile/revolver.dm | 5 +-
.../projectiles/guns/projectile/shotgun.dm | 2 +-
.../projectiles/guns/throw/crossbow.dm | 20 +-
.../chemistry/machinery/chem_heater.dm | 2 +-
.../reagents/chemistry/reagents/drugs.dm | 4 +-
.../reagents/chemistry/reagents/misc.dm | 2 +-
code/modules/reagents/reagent_containers.dm | 15 +-
.../reagent_containers/glass_containers.dm | 2 +-
.../reagents/reagent_containers/syringes.dm | 2 +-
code/modules/recycling/disposal.dm | 6 +-
.../recycling/disposal/construction.dm | 11 +-
.../research/xenobiology/xenobiology.dm | 15 +-
code/modules/spacepods/parts.dm | 28 +-
code/modules/spacepods/spacepod.dm | 137 +++++-----
code/modules/surgery/organs/augments_tail.dm | 4 +-
code/modules/telesci/gps.dm | 4 +-
code/modules/tgui/modules/item_pixel_shift.dm | 2 +-
code/modules/vehicle/ambulance.dm | 2 +-
code/modules/vehicle/vehicle.dm | 4 +-
258 files changed, 1203 insertions(+), 1079 deletions(-)
diff --git a/code/__DEFINES/alerts.dm b/code/__DEFINES/alerts.dm
index 2649def1895..3e03a35daee 100644
--- a/code/__DEFINES/alerts.dm
+++ b/code/__DEFINES/alerts.dm
@@ -1,7 +1,10 @@
/** Environment related */
#define ALERT_GRAVITY "gravity"
-#define ALERT_BUCKLED "buckled"
-
#define ALERT_GHOST_NEST "ghost_nest"
+/** Mob related */
+#define ALERT_BUCKLED "buckled"
+#define ALERT_HANDCUFFED "handcuffed"
+#define ALERT_LEGCUFFED "legcuffed"
+
diff --git a/code/__DEFINES/traits/sources.dm b/code/__DEFINES/traits/sources.dm
index 8ad0d56bdb3..31c9831e411 100644
--- a/code/__DEFINES/traits/sources.dm
+++ b/code/__DEFINES/traits/sources.dm
@@ -80,6 +80,8 @@
/// Trait associated to being cuffed
#define HANDCUFFED_TRAIT "handcuffed_trait"
+/// trait associated to not having fine manipulation appendages such as hands
+#define LACKING_MANIPULATION_APPENDAGES_TRAIT "lacking-manipulation-appengades"
/// Trait associated to wearing a suit
#define SUIT_TRAIT "suit_trait"
/// Trait associated to lying down (having a [lying_angle] of a different value than zero).
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index 362965a0142..a86e0c8f9dc 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -361,7 +361,7 @@
|| (!(timed_action_flags & IGNORE_WEAKENED) && user.IsWeakened()) \
|| (!(timed_action_flags & IGNORE_PARALYZED) && user.IsParalyzed()) \
|| (!(timed_action_flags & IGNORE_LYING) && user.IsLying()) \
- || (!(timed_action_flags & IGNORE_RESTRAINED) && user.restrained()) \
+ || (!(timed_action_flags & IGNORE_RESTRAINED) && HAS_TRAIT(user, TRAIT_RESTRAINED)) \
|| (gripper_check && gripper?.isEmpty()) \
|| extra_checks?.Invoke())
. = FALSE
diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm
index 0328499cf9e..c3615c349c3 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.
@@ -97,12 +94,7 @@
set_waypoint(A)
waypoint_mode = 0
return
- /*
- AI restrained() currently does nothing
- if(restrained())
- RestrainedClickOn(A)
- else
- */
+
A.add_hiddenprint(src)
A.attack_ai(src)
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index 3c7053c19af..995a8cb048d 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -123,7 +123,7 @@
var/obj/mecha/M = loc
return M.click_action(A, src, params)
- if(restrained())
+ if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
changeNext_move(CLICK_CD_HANDCUFFED) //Doing shit in cuffs shall be vey slow
RestrainedClickOn(A)
return
@@ -223,10 +223,10 @@
proximity_flag is not currently passed to attack_hand, and is instead used
in human click code to allow glove touches only at melee range.
*/
-/mob/proc/UnarmedAttack(var/atom/A, var/proximity_flag)
+/mob/proc/UnarmedAttack(atom/A, proximity_flag)
if(ismob(A))
changeNext_move(CLICK_CD_MELEE)
- return
+
/*
Ranged unarmed attack:
diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm
index 43f0623c6ea..416b7d8ba12 100644
--- a/code/_onclick/cyborg.dm
+++ b/code/_onclick/cyborg.dm
@@ -60,13 +60,6 @@
to_chat(src, "Your camera isn't functional.")
return
- /*
- cyborg restrained() currently does nothing
- if(restrained())
- RestrainedClickOn(A)
- return
- */
-
var/obj/item/W = get_active_hand()
// Cyborgs have no range-checking unless there is item use
@@ -75,6 +68,10 @@
A.attack_robot(src)
return
+ //if your "hands" are blocked you shouldn't be able to use modules
+ if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
+ return
+
// buckled cannot prevent machine interlinking but stops arm movement
if( buckled )
return
@@ -196,6 +193,8 @@
change attack_robot() above to the proper function
*/
/mob/living/silicon/robot/UnarmedAttack(atom/A)
+ if(!can_unarmed_attack())
+ return
A.attack_robot(src)
/mob/living/silicon/robot/RangedAttack(atom/A, params)
diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm
index c760909549c..e4fee5ebd2d 100644
--- a/code/_onclick/hud/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects.dm
@@ -195,7 +195,7 @@
/obj/screen/storage/MouseDrop_T(obj/item/I, mob/user, params)
- if(!user || !istype(I) || user.incapacitated(ignore_restraints = TRUE, ignore_lying = TRUE) || ismecha(user.loc) || !master)
+ if(!user || !master || !istype(I) || user.incapacitated(ignore_restraints = TRUE, ignore_lying = TRUE) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || ismecha(user.loc))
return FALSE
if(is_ventcrawling(user))
@@ -529,7 +529,7 @@
/obj/screen/inventory/MouseDrop_T(obj/item/I, mob/user, params)
- if(!user || !istype(I) || user.incapacitated() || ismecha(user.loc) || is_ventcrawling(user))
+ if(!user || !istype(I) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || ismecha(user.loc) || is_ventcrawling(user))
return FALSE
if(isalien(user) && !I.allowed_for_alien()) // We need to do this here
diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm
index ddfafac439f..a7b0bf13f89 100644
--- a/code/_onclick/other_mobs.dm
+++ b/code/_onclick/other_mobs.dm
@@ -4,12 +4,15 @@
Otherwise pretty standard.
*/
-/mob/living/carbon/human/UnarmedAttack(atom/A, proximity)
+/mob/living/carbon/human/UnarmedAttack(atom/A, proximity_flag)
+ if(!can_unarmed_attack())
+ return
+
// Special glove functions:
// If the gloves do anything, have them return 1 to stop
// normal attack_hand() here.
var/obj/item/clothing/gloves/G = gloves // not typecast specifically enough in defines
- if(proximity && istype(G) && G.Touch(A, 1))
+ if(proximity_flag && istype(G) && G.Touch(A, proximity_flag))
return
@@ -61,27 +64,60 @@
if(isturf(A) && get_dist(src, A) <= 1)
Move_Pulled(A)
+
+/**
+ * Checks if this mob is in a valid state to punch someone.
+ *
+ * (Potentially) gives feedback to the mob if they cannot.
+ */
+/mob/living/proc/can_unarmed_attack()
+ return !HAS_TRAIT(src, TRAIT_HANDS_BLOCKED)
+
+
+/mob/living/carbon/human/can_unarmed_attack()
+ . = ..()
+ if(!.)
+ return FALSE
+
+ if(!get_active_hand()) //can't attack without a hand.
+ var/obj/item/organ/external/limb = get_organ(hand ? BODY_ZONE_PRECISE_L_HAND : BODY_ZONE_PRECISE_R_HAND)
+ if(!limb)
+ to_chat(src, span_warning("You look at your arm and sigh."))
+ return FALSE
+ if(!limb.is_usable())
+ to_chat(src, span_warning("Your [limb.name] is in no condition to be used."))
+ return FALSE
+
+ return TRUE
+
+
/*
Animals & All Unspecified
*/
-/mob/living/UnarmedAttack(var/atom/A)
+/mob/living/UnarmedAttack(atom/A, proximity_flag)
+ if(!can_unarmed_attack())
+ return
A.attack_animal(src)
-/mob/living/simple_animal/hostile/UnarmedAttack(var/atom/A)
+/mob/living/simple_animal/hostile/UnarmedAttack(atom/A, proximity_flag)
+ if(!can_unarmed_attack())
+ return
target = A
AttackingTarget()
/atom/proc/attack_animal(mob/user)
return
-/mob/living/RestrainedClickOn(var/atom/A)
+/mob/living/RestrainedClickOn(atom/A)
return
/*
Aliens
Defaults to same as monkey in most places
*/
-/mob/living/carbon/alien/UnarmedAttack(atom/A)
+/mob/living/carbon/alien/UnarmedAttack(atom/A, proximity_flag)
+ if(!can_unarmed_attack())
+ return
A.attack_alien(src)
/atom/proc/attack_alien(mob/living/carbon/alien/user)
@@ -91,7 +127,9 @@
return
// Babby aliens
-/mob/living/carbon/alien/larva/UnarmedAttack(atom/A)
+/mob/living/carbon/alien/larva/UnarmedAttack(atom/A, proximity_flag)
+ if(!can_unarmed_attack())
+ return
A.attack_larva(src)
/atom/proc/attack_larva(mob/user)
@@ -101,7 +139,9 @@
Slimes
Nothing happening here
*/
-/mob/living/simple_animal/slime/UnarmedAttack(atom/A)
+/mob/living/simple_animal/slime/UnarmedAttack(atom/A, proximity_flag)
+ if(!can_unarmed_attack())
+ return
A.attack_slime(src)
/atom/proc/attack_slime(mob/user)
@@ -117,6 +157,8 @@
/mob/new_player/ClickOn()
return
+
// pAIs are not intended to interact with anything in the world
-/mob/living/silicon/pai/UnarmedAttack(var/atom/A)
+/mob/living/silicon/pai/UnarmedAttack(atom/A, proximity_flag)
return
+
diff --git a/code/controllers/subsystem/afk.dm b/code/controllers/subsystem/afk.dm
index 9e1c8273117..4bf175bc565 100644
--- a/code/controllers/subsystem/afk.dm
+++ b/code/controllers/subsystem/afk.dm
@@ -32,7 +32,7 @@ SUBSYSTEM_DEF(afk)
// Only players and players with the AFK watch enabled
// No dead, unconcious, restrained, people without jobs or people on other Z levels than the station
if(!H.client || !(H.client.prefs.toggles2 & PREFTOGGLE_2_AFKWATCH) || !H.mind || \
- H.stat || H.restrained() || !H.job || !is_station_level((T = get_turf(H)).z)) // Assign the turf as last. Small optimization
+ H.stat || HAS_TRAIT(H, TRAIT_RESTRAINED) || !H.job || !is_station_level((T = get_turf(H)).z)) // Assign the turf as last. Small optimization
if(afk_players[H.ckey])
toRemove += H.ckey
continue
diff --git a/code/datums/action.dm b/code/datums/action.dm
index fa04562a087..2cf09d80c5d 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -36,12 +36,15 @@
return FALSE
Remove(owner)
owner = user
- user.actions += src
+ owner.actions += src
- if(user.client)
- user.client.screen += button
+ if(owner.client)
+ owner.client.screen += button
button.locked = TRUE
- user.update_action_buttons()
+ owner.update_action_buttons()
+
+ if(check_flags & AB_CHECK_HANDS_BLOCKED)
+ RegisterSignal(owner, list(SIGNAL_ADDTRAIT(TRAIT_HANDS_BLOCKED), SIGNAL_REMOVETRAIT(TRAIT_HANDS_BLOCKED)), PROC_REF(update_status_on_signal))
return TRUE
@@ -60,9 +63,21 @@
user.actions -= src
user.update_action_buttons()
+ // Clean up our check_flag signals
+ UnregisterSignal(user, list(
+ SIGNAL_ADDTRAIT(TRAIT_HANDS_BLOCKED),
+ SIGNAL_REMOVETRAIT(TRAIT_HANDS_BLOCKED),
+ ))
+
return TRUE
+/// A general use signal proc that reacts to an event and updates JUST our button
+/datum/action/proc/update_status_on_signal(datum/source, new_stat, old_stat)
+ SIGNAL_HANDLER
+ UpdateButtonIcon()
+
+
/datum/action/proc/Trigger(left_click = TRUE)
if(!IsAvailable())
return FALSE
@@ -101,7 +116,7 @@
return FALSE
var/owner_is_living = isliving(owner)
var/mob/living/living_owner = owner
- if((check_flags & AB_CHECK_HANDS_BLOCKED) && owner.restrained())
+ if((check_flags & AB_CHECK_HANDS_BLOCKED) && HAS_TRAIT(owner, TRAIT_HANDS_BLOCKED))
return FALSE
if((check_flags & AB_CHECK_IMMOBILE) && owner_is_living && living_owner.IsImmobilized())
return FALSE
diff --git a/code/datums/diseases/viruses/advance/symptoms/uncotrollable.dm b/code/datums/diseases/viruses/advance/symptoms/uncotrollable.dm
index a06f6e17316..d31319411de 100644
--- a/code/datums/diseases/viruses/advance/symptoms/uncotrollable.dm
+++ b/code/datums/diseases/viruses/advance/symptoms/uncotrollable.dm
@@ -52,7 +52,7 @@ Uncontrollable Aggression
aggressor.say(pick("ААААААААААА!!!!", "ГРРР!!!", "СУКА!! БЛЯТЬ!!!", "ЁБАНЫЕ ГОВНЮКИ!!", "ВАААААААГХХ!!"))
if(A.stage >= 5 && prob(50))
- if(aggressor.incapacitated())
+ if(aggressor.incapacitated() || HAS_TRAIT(aggressor, TRAIT_HANDS_BLOCKED))
aggressor.visible_message(span_danger("[aggressor] spasms and twitches!"))
return
aggressor.visible_message(span_danger("[aggressor] thrashes around violently!"))
diff --git a/code/datums/emote/emote.dm b/code/datums/emote/emote.dm
index 8e54abfa871..0138fb40527 100644
--- a/code/datums/emote/emote.dm
+++ b/code/datums/emote/emote.dm
@@ -508,7 +508,7 @@
if(HAS_TRAIT(user, TRAIT_FAKEDEATH))
// Don't let people blow their cover by mistake
return FALSE
- if(hands_use_check && !user.can_use_hands() && iscarbon(user))
+ if(hands_use_check && HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
if(!intentional)
return FALSE
to_chat(user, span_warning("You cannot use your hands to [key] right now!"))
diff --git a/code/datums/spells/alien_spells/corrosive_acid_spit.dm b/code/datums/spells/alien_spells/corrosive_acid_spit.dm
index 07990e55e8d..1de74fee5b0 100644
--- a/code/datums/spells/alien_spells/corrosive_acid_spit.dm
+++ b/code/datums/spells/alien_spells/corrosive_acid_spit.dm
@@ -48,7 +48,7 @@
if(target == user)
return ..()
- if(!proximity || isalien(target) || !iscarbon(user) || user.incapacitated()) // Don't want xenos ditching out of cuffs
+ if(!proximity || isalien(target) || !iscarbon(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) // Don't want xenos ditching out of cuffs
return
if(!plasma_check(plasma_cost, user))
diff --git a/code/datums/spells/alien_spells/transfer_plasma.dm b/code/datums/spells/alien_spells/transfer_plasma.dm
index b0c2dbf8a5c..a4796b56787 100644
--- a/code/datums/spells/alien_spells/transfer_plasma.dm
+++ b/code/datums/spells/alien_spells/transfer_plasma.dm
@@ -9,6 +9,10 @@
/obj/effect/proc_holder/spell/touch/alien_spell/transfer_plasma/Click(mob/living/carbon/user = usr)
+ if(HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, span_warning("You can't control your hands!"))
+ return
+
if(attached_hand)
return ..()
@@ -62,7 +66,7 @@
if(target == user)
return ..()
- if(!proximity || !isalien(target) || !iscarbon(user) || user.incapacitated())
+ if(!proximity || !isalien(target) || !iscarbon(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
var/mob/living/carbon/transfering_to = target
diff --git a/code/datums/spells/banana_touch.dm b/code/datums/spells/banana_touch.dm
index 6fab2114f18..667763b1149 100644
--- a/code/datums/spells/banana_touch.dm
+++ b/code/datums/spells/banana_touch.dm
@@ -22,7 +22,7 @@
/obj/item/melee/touch_attack/banana/afterattack(atom/target, mob/living/carbon/user, proximity)
- if(!proximity || target == user || !ishuman(target) || !iscarbon(user) || user.incapacitated())
+ if(!proximity || target == user || !ishuman(target) || !iscarbon(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
var/datum/effect_system/smoke_spread/smoke = new
diff --git a/code/datums/spells/lavaland_spells/healtouch.dm b/code/datums/spells/lavaland_spells/healtouch.dm
index a942a5918b0..7646acb1e9d 100644
--- a/code/datums/spells/lavaland_spells/healtouch.dm
+++ b/code/datums/spells/lavaland_spells/healtouch.dm
@@ -26,7 +26,7 @@
var/heal_self = FALSE
/obj/item/melee/touch_attack/healtouch/afterattack(atom/target, mob/living/carbon/user, proximity)
- if(!proximity || (target == user && !heal_self) || !ismob(target) || !iscarbon(user) || user.incapacitated())
+ if(!proximity || (target == user && !heal_self) || !ismob(target) || !iscarbon(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
var/mob/living/M = target
new /obj/effect/temp_visual/heal(get_turf(M), "#899d39")
diff --git a/code/datums/spells/mime_malaise.dm b/code/datums/spells/mime_malaise.dm
index 3a973bb005f..74a118fabf4 100644
--- a/code/datums/spells/mime_malaise.dm
+++ b/code/datums/spells/mime_malaise.dm
@@ -23,7 +23,7 @@
/obj/item/melee/touch_attack/mime_malaise/afterattack(atom/target, mob/living/carbon/user, proximity)
- if(!proximity || target == user || !ishuman(target) || !iscarbon(user) || user.incapacitated())
+ if(!proximity || target == user || !ishuman(target) || !iscarbon(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
var/datum/effect_system/smoke_spread/s = new
diff --git a/code/datums/spells/touch_attacks.dm b/code/datums/spells/touch_attacks.dm
index 8560b457ddd..fe67423e1fc 100644
--- a/code/datums/spells/touch_attacks.dm
+++ b/code/datums/spells/touch_attacks.dm
@@ -15,6 +15,9 @@
/obj/effect/proc_holder/spell/touch/Click(mob/user = usr)
+ if(HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, span_warning("You can't control your hands!!"))
+ return FALSE
if(attached_hand)
discharge_hand(user, TRUE)
return FALSE
diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm
index eedfab008c7..4085ba34411 100644
--- a/code/datums/status_effects/debuffs.dm
+++ b/code/datums/status_effects/debuffs.dm
@@ -246,7 +246,7 @@
if(t_hearts && prob(t_hearts * 10)) // 60% on MAX
owner.adjustFireLoss(t_hearts) // 6 MAX
- if(!owner.incapacitated() && prob(30 + t_eyes * 7)) // 100% on MAX
+ if(!owner.incapacitated() && !HAS_TRAIT(owner, TRAIT_HANDS_BLOCKED) && prob(30 + t_eyes * 7)) // 100% on MAX
// lets check our arms first
var/obj/item/left_hand = owner.l_hand
var/obj/item/right_hand = owner.r_hand
@@ -613,6 +613,8 @@
status_type = STATUS_EFFECT_REPLACE
alert_type = null
var/needs_update_stat = FALSE
+ var/list/traits_to_apply
+
/datum/status_effect/incapacitating/on_creation(mob/living/new_owner, set_duration)
if(isnum(set_duration))
@@ -625,26 +627,41 @@
. = ..()
if(. && (needs_update_stat || issilicon(owner)))
owner.update_stat()
- owner.update_canmove()
+ owner?.update_canmove()
+
+
+/datum/status_effect/incapacitating/on_apply()
+ . = ..()
+ if(traits_to_apply)
+ owner.add_traits(traits_to_apply, TRAIT_STATUS_EFFECT(id))
/datum/status_effect/incapacitating/on_remove()
if(needs_update_stat || issilicon(owner)) //silicons need stat updates in addition to normal canmove updates
owner.update_stat()
+ if(traits_to_apply)
+ owner.remove_traits(traits_to_apply, TRAIT_STATUS_EFFECT(id))
owner.update_canmove()
return ..()
+
//STUN - prevents movement and actions, victim stays standing
/datum/status_effect/incapacitating/stun
id = "stun"
+ traits_to_apply = list(TRAIT_HANDS_BLOCKED)
+
//IMMOBILIZED - prevents movement, victim can still stand and act
/datum/status_effect/incapacitating/immobilized
id = "immobilized"
+ traits_to_apply = list(TRAIT_IMMOBILIZED)
+
//WEAKENED - prevents movement and action, victim falls over
/datum/status_effect/incapacitating/weakened
id = "weakened"
+ traits_to_apply = list(TRAIT_HANDS_BLOCKED)
+
//PARALYZED - prevents movement and action, victim falls over, victim cannot hear or see.
/datum/status_effect/incapacitating/paralyzed
diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm
index 82d2bef6e97..c0b6c441a91 100644
--- a/code/datums/uplink_item.dm
+++ b/code/datums/uplink_item.dm
@@ -136,7 +136,7 @@
if(!istype(target_uplink))
return FALSE
- if(buyer.stat || buyer.restrained())
+ if(buyer.stat || HAS_TRAIT(buyer, TRAIT_HANDS_BLOCKED))
return FALSE
if(!ishuman(buyer))
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 54700aea5f8..418cae92e73 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -1310,7 +1310,7 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
// Sanity check that the user can, indeed, rename the thing.
// This, sadly, means you can't rename things with a telekinetic pen, but that's
// too much of a hassle to make work nicely.
- if((implement && implement.loc != user) || !in_range(src, user) || user.incapacitated(ignore_lying = TRUE))
+ if((implement && implement.loc != user) || !in_range(src, user) || user.incapacitated(ignore_lying = TRUE) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return null
var/prefix = ""
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 31678678839..56f93c187ad 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -194,11 +194,17 @@
if(previous_puller)
add_attack_logs(AM, previous_puller, "pulled from", ATKLOG_ALMOSTALL)
if(show_message)
- visible_message(span_danger("[src] перехватил[genderize_ru(gender,"","а","о","и")] [mob_target] у [previous_puller]."))
+ mob_target.visible_message(
+ span_danger("[src] перехватил[genderize_ru(gender,"","а","о","и")] [mob_target] у [previous_puller]."),
+ span_danger("[src] перехватил[genderize_ru(gender,"","а","о","и")] Вас у [previous_puller]!"),
+ )
else
add_attack_logs(src, mob_target, "pulls", ATKLOG_ALMOSTALL)
if(show_message)
- visible_message(span_warning("[src] схватил[genderize_ru(gender,"","а","о","и")] [mob_target]!"))
+ mob_target.visible_message(
+ span_warning("[src] схватил[genderize_ru(gender,"","а","о","и")] [mob_target]!"),
+ span_warning("[src] схватил[genderize_ru(gender,"","а","о","и")] Вас!"),
+ )
mob_target.LAssailant = iscarbon(src) ? src : null
return TRUE
diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm
index c5d66026e53..5d1e01c829e 100644
--- a/code/game/dna/dna_modifier.dm
+++ b/code/game/dna/dna_modifier.dm
@@ -116,7 +116,7 @@
set category = null
set name = "Eject DNA Scanner"
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
eject_occupant(usr)
add_fingerprint(usr)
@@ -142,7 +142,7 @@
set category = null
set name = "Enter DNA Scanner"
- if(usr.incapacitated() || usr.buckled) //are you cuffed, dying, lying, stunned or other
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || usr.buckled) //are you cuffed, dying, lying, stunned or other
return
if(!ishuman(usr)) //Make sure they're a mob that has dna
to_chat(usr, "Try as you might, you can not climb up into the [src].")
@@ -168,7 +168,7 @@
return
if(O.loc == user) //no you can't pull things out of your ass
return
- if(user.incapacitated()) //are you cuffed, dying, lying, stunned or other
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //are you cuffed, dying, lying, stunned or other
return
if(O.anchored || get_dist(user, src) > 1 || get_dist(user, O) > 1 || user.contents.Find(src)) // is the mob anchored, too far away from you, or are you too far away from the source
return
diff --git a/code/game/dna/genes/goon_powers.dm b/code/game/dna/genes/goon_powers.dm
index 6f2837e79ce..91e38bb5f2c 100644
--- a/code/game/dna/genes/goon_powers.dm
+++ b/code/game/dna/genes/goon_powers.dm
@@ -75,7 +75,7 @@
block = GLOB.chameleonblock
/datum/dna/gene/basic/stealth/chameleon/OnMobLife(mob/M)
- if((world.time - M.last_movement) >= 30 && !M.stat && M.canmove && !M.restrained())
+ if((world.time - M.last_movement) >= 30 && M.canmove && !HAS_TRAIT(M, TRAIT_RESTRAINED))
M.alpha -= 25
else
M.alpha = round(255 * 0.80)
@@ -345,7 +345,7 @@
/obj/effect/proc_holder/spell/leap/cast(list/targets, mob/living/user = usr)
var/failure = FALSE
- if(ismob(user.loc) || user.incapacitated() || user.buckled)
+ if(ismob(user.loc) || user.incapacitated(ignore_restraints = TRUE) || user.buckled)
to_chat(user, "You can't jump right now!")
return
var/turf/turf_to_check = get_turf(user)
@@ -354,13 +354,12 @@
return
if(isturf(user.loc))
- if(user.restrained())//Why being pulled while cuffed prevents you from moving
- for(var/mob/living/M in range(user, 1))
- if(M.pulling == user)
- if(!M.restrained() && M.stat == 0 && M.canmove && user.Adjacent(M))
- failure = TRUE
- else
- M.stop_pulling()
+ if(HAS_TRAIT(user, TRAIT_RESTRAINED))//Why being pulled while cuffed prevents you from moving
+ var/mob/puller = user.pulledby
+ if(puller && !puller.stat && puller.canmove && user.Adjacent(puller))
+ failure = TRUE
+ else if(puller)
+ puller.stop_pulling()
user.visible_message("[user.name] takes a huge leap!")
playsound(user.loc, 'sound/weapons/thudswoosh.ogg', 50, 1)
diff --git a/code/game/gamemodes/clockwork/clockwork_items.dm b/code/game/gamemodes/clockwork/clockwork_items.dm
index 145b77d63cd..d838fd687f3 100644
--- a/code/game/gamemodes/clockwork/clockwork_items.dm
+++ b/code/game/gamemodes/clockwork/clockwork_items.dm
@@ -249,7 +249,7 @@
return ..()
var/mob/living/living = hit_atom
if(isclocker(living))
- if(ishuman(living) && !living.restrained() && living.put_in_active_hand(src))
+ if(ishuman(living) && living.put_in_active_hand(src))
playsound(src, 'sound/weapons/throwtap.ogg', 50)
living.visible_message("[living] catches [src] out of the air!")
else
@@ -392,7 +392,7 @@
return ..()
var/mob/living/living = hit_atom
if(isclocker(living))
- if(ishuman(living) && !living.restrained() && living.put_in_active_hand(src))
+ if(ishuman(living) && living.put_in_active_hand(src))
playsound(src, 'sound/weapons/throwtap.ogg', 50)
living.visible_message("[living] catches [src] out of the air!")
else
@@ -492,7 +492,7 @@
return ..()
var/mob/living/living = hit_atom
if(isclocker(living))
- if(ishuman(living) && !living.restrained() && living.put_in_active_hand(src))
+ if(ishuman(living) && living.put_in_active_hand(src))
playsound(src, 'sound/weapons/throwtap.ogg', 50)
living.visible_message("[living] catches [src] out of the air!")
else
diff --git a/code/game/gamemodes/cult/blood_magic.dm b/code/game/gamemodes/cult/blood_magic.dm
index 046b9360f18..8824343ca71 100644
--- a/code/game/gamemodes/cult/blood_magic.dm
+++ b/code/game/gamemodes/cult/blood_magic.dm
@@ -523,7 +523,7 @@
/obj/item/melee/blood_magic/shackles/afterattack(atom/target, mob/living/carbon/user, proximity)
if(iscarbon(target) && proximity)
var/mob/living/carbon/C = target
- if(C.canBeHandcuffed())
+ if(C.has_organ_for_slot(ITEM_SLOT_HANDCUFFED))
if(C.getStaminaLoss() > 90 || C.health <= HEALTH_THRESHOLD_CRIT || C.IsSleeping())
CuffAttack(C, user)
else
@@ -540,7 +540,7 @@
"[user] begins shaping dark magic shackles around your wrists!")
if(do_after(user, 1 SECONDS, C, NONE))
if(!C.handcuffed)
- C.set_handcuffed(new /obj/item/restraints/handcuffs/energy/cult/used(C))
+ C.apply_restraints(new /obj/item/restraints/handcuffs/energy/cult/used(null), ITEM_SLOT_HANDCUFFED, TRUE)
C.Silence(12 SECONDS)
to_chat(user, "You shackle [C].")
add_attack_logs(user, C, "shackled")
diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm
index 350e004be14..8fd66e0380c 100644
--- a/code/game/gamemodes/cult/cult_items.dm
+++ b/code/game/gamemodes/cult/cult_items.dm
@@ -635,7 +635,7 @@
var/mob/living/L = hit_atom
if(iscultist(L))
playsound(src, 'sound/weapons/throwtap.ogg', 50)
- if(!L.restrained() && L.put_in_active_hand(src))
+ if(ishuman(L) && L.put_in_active_hand(src))
L.visible_message("[L] catches [src] out of the air!")
else
L.visible_message("[src] bounces off of [L], as if repelled by an unseen force!")
diff --git a/code/game/gamemodes/devil/true_devil/_true_devil.dm b/code/game/gamemodes/devil/true_devil/_true_devil.dm
index c2ae3e0bcf6..d0c75522530 100644
--- a/code/game/gamemodes/devil/true_devil/_true_devil.dm
+++ b/code/game/gamemodes/devil/true_devil/_true_devil.dm
@@ -125,6 +125,8 @@
return TRUE
/mob/living/carbon/true_devil/UnarmedAttack(atom/A, proximity)
+ if(!can_unarmed_attack())
+ return
if(!ishuman(A))
// `attack_hand` on mobs assumes the attacker is a human
// I am the worst
diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
index 8f0a07d5b75..83b41c5d697 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
@@ -545,7 +545,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
if(!iscarbon(L))
return
var/mob/living/carbon/C = L
- if(!C.handcuffed)
+ if(C.has_organ_for_slot(ITEM_SLOT_HANDCUFFED) && !C.handcuffed)
playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2)
C.visible_message("[user] begins restraining [C] with [src]!", \
"[user] begins shaping an energy field around your hands!")
@@ -553,7 +553,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
if(C.handcuffed)
return
- C.set_handcuffed(new /obj/item/restraints/handcuffs/cable/zipties/used(C))
+ C.apply_restraints(new /obj/item/restraints/handcuffs/cable/zipties/used(null), ITEM_SLOT_HANDCUFFED, TRUE)
to_chat(user, "You handcuff [C].")
add_attack_logs(user, C, "Handcuffed ([src])")
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
index e8ddd06cdd7..07efe47eb9a 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
@@ -26,7 +26,7 @@
/obj/machinery/abductor/experiment/MouseDrop_T(mob/living/carbon/human/target, mob/user, params)
if(stat)
return
- if(user.incapacitated() || !Adjacent(user) || !target.Adjacent(user) || !ishuman(target))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user) || !target.Adjacent(user) || !ishuman(target))
return
if(isabductor(target))
return
diff --git a/code/game/gamemodes/miniantags/borer/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm
index 4360011e3b7..75b021aa20a 100644
--- a/code/game/gamemodes/miniantags/borer/borer.dm
+++ b/code/game/gamemodes/miniantags/borer/borer.dm
@@ -305,6 +305,8 @@
return ..()
/mob/living/simple_animal/borer/UnarmedAttack(mob/living/carbon/human/M)
+ if(!can_unarmed_attack())
+ return
if(istype(M))
to_chat(src, span_notice("Вы анализируете жизненные показатели [M]."))
healthscan(src, M, 1, TRUE)
diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
index 6045b3d6e32..73f0605413a 100644
--- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
+++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
@@ -531,7 +531,7 @@
changeNext_move(CLICK_CD_MELEE)
target.ex_act(EXPLODE_LIGHT)
-/mob/living/simple_animal/hostile/swarmer/proc/DisperseTarget(var/mob/living/target)
+/mob/living/simple_animal/hostile/swarmer/proc/DisperseTarget(mob/living/target)
if(target == src)
return
@@ -552,9 +552,9 @@
// If we're getting rid of a human, slap some energy cuffs on
// them to keep them away from us a little longer
- var/mob/living/carbon/human/H = target
- if(istype(H) && (!H.handcuffed))
- H.set_handcuffed(new /obj/item/restraints/handcuffs/energy/used(H))
+ var/mob/living/carbon/c_target = target
+ if(istype(c_target) && !c_target.handcuffed)
+ c_target.apply_restraints(new /obj/item/restraints/handcuffs/energy/used(null), TRUE)
do_sparks(4, 0, target)
playsound(src,'sound/effects/sparks4.ogg', 50, TRUE)
diff --git a/code/game/gamemodes/miniantags/demons/pulse_demon/pulse_demon.dm b/code/game/gamemodes/miniantags/demons/pulse_demon/pulse_demon.dm
index fdd8abc7446..5984752391e 100644
--- a/code/game/gamemodes/miniantags/demons/pulse_demon/pulse_demon.dm
+++ b/code/game/gamemodes/miniantags/demons/pulse_demon/pulse_demon.dm
@@ -752,6 +752,8 @@
try_shock_mob(L)
/mob/living/simple_animal/demon/pulse_demon/UnarmedAttack(atom/A)
+ if(!can_unarmed_attack())
+ return
if(isliving(A))
try_attack_mob(A)
else if(isitem(A) && !is_under_tile())
diff --git a/code/game/gamemodes/miniantags/demons/shadow_demon/shadow_demon.dm b/code/game/gamemodes/miniantags/demons/shadow_demon/shadow_demon.dm
index 12fe5030817..ad3eb257b0a 100644
--- a/code/game/gamemodes/miniantags/demons/shadow_demon/shadow_demon.dm
+++ b/code/game/gamemodes/miniantags/demons/shadow_demon/shadow_demon.dm
@@ -61,6 +61,9 @@
/mob/living/simple_animal/demon/shadow/UnarmedAttack(atom/target)
+ if(!can_unarmed_attack())
+ return
+
if(!ishuman(target))
if(isitem(target))
target.extinguish_light(TRUE)
@@ -134,7 +137,7 @@
/obj/structure/shadowcocoon/AltClick(mob/user)
- if(!isdemon(user))
+ if(!isdemon(user) || user.incapacitated())
return ..()
if(silent)
to_chat(user, span_notice("You twist and change your trapped victim in [src] to lure in more prey."))
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index 01ecac73c5f..b3ba294b443 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -438,7 +438,7 @@
if(M.current.stat == DEAD)
scoreboard.score_ops_killed++
- else if(M.current.restrained())
+ else if(HAS_TRAIT(M, TRAIT_RESTRAINED))
scoreboard.score_arrested++
if(foecount == scoreboard.score_arrested)
diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm
index 7cac6d22d02..a8218a51b62 100644
--- a/code/game/gamemodes/nuclear/pinpointer.dm
+++ b/code/game/gamemodes/nuclear/pinpointer.dm
@@ -236,7 +236,7 @@
/obj/item/pinpointer/advpinpointer/proc/toggle_mode(mob/user)
- if(!iscarbon(user) || user.incapacitated())
+ if(!iscarbon(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(modelocked)
@@ -512,7 +512,7 @@
/obj/item/pinpointer/crew/proc/choose_signal(mob/living/carbon/user)
- if(!iscarbon(user) || user.incapacitated())
+ if(!iscarbon(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
var/list/name_counts = list()
@@ -626,7 +626,7 @@
/obj/item/pinpointer/thief/proc/toggle_mode(mob/user)
- if(!iscarbon(user) || user.incapacitated())
+ if(!iscarbon(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
switch(alert("Выберите режим пинпоинтера.", "Выбор режима пинпоинтера", "Локация", "Сигнатура Объекта", "Цели"))
diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm
index ccc5e2866f0..c8acb81a118 100644
--- a/code/game/gamemodes/revolution/revolution.dm
+++ b/code/game/gamemodes/revolution/revolution.dm
@@ -327,7 +327,7 @@
if(M.current.stat == DEAD)
scoreboard.score_ops_killed++
- else if(M.current.restrained())
+ else if(HAS_TRAIT(M, TRAIT_RESTRAINED))
scoreboard.score_arrested++
if(foecount == scoreboard.score_arrested)
diff --git a/code/game/gamemodes/wizard/apprentice.dm b/code/game/gamemodes/wizard/apprentice.dm
index 03e241d4c1e..75cf42af0e4 100644
--- a/code/game/gamemodes/wizard/apprentice.dm
+++ b/code/game/gamemodes/wizard/apprentice.dm
@@ -19,12 +19,12 @@
..()
if(!ishuman(usr))
to_chat(usr, "Вы даже не гуманоид... Вы не понимаете как этим пользоваться и что здесь написано.")
- return 0
+ return FALSE
var/mob/living/carbon/human/teacher = usr
- if(teacher.stat || teacher.restrained())
- return 0
+ if(teacher.incapacitated() || HAS_TRAIT(teacher, TRAIT_HANDS_BLOCKED))
+ return FALSE
if(loc == teacher || (in_range(src, teacher) && isturf(loc)))
teacher.set_machine(src)
@@ -99,12 +99,12 @@
..()
if(!ishuman(usr))
to_chat(usr, "Вы даже не гуманоид... Вы не понимаете как этим пользоваться и что здесь написано.")
- return 0
+ return FALSE
var/mob/living/carbon/human/apprentice = usr
- if(apprentice.stat || apprentice.restrained())
- return 0
+ if(apprentice.incapacitated() || HAS_TRAIT(apprentice, TRAIT_HANDS_BLOCKED))
+ return FALSE
if(loc == apprentice || (in_range(src, apprentice) && isturf(loc)))
apprentice.set_machine(src)
diff --git a/code/game/gamemodes/wizard/godhand.dm b/code/game/gamemodes/wizard/godhand.dm
index 2d0c80bd7d5..6de1f35bdd6 100644
--- a/code/game/gamemodes/wizard/godhand.dm
+++ b/code/game/gamemodes/wizard/godhand.dm
@@ -51,13 +51,15 @@
/obj/item/melee/touch_attack/attack(mob/target, mob/living/carbon/user)
if(!iscarbon(user)) //Look ma, no hands
return
- if(user.incapacitated())
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
to_chat(user, "You can't reach out!")
return
..()
/obj/item/melee/touch_attack/afterattack(atom/target, mob/user, proximity)
+ if(HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ return
if(catchphrase)
user.say(catchphrase)
playsound(get_turf(user), on_use_sound, 50, TRUE)
@@ -76,7 +78,7 @@
/obj/item/melee/touch_attack/disintegrate/afterattack(atom/target, mob/living/carbon/user, proximity)
- if(!proximity || target == user || !ismob(target) || !iscarbon(user) || user.incapacitated()) //exploding after touching yourself would be bad
+ if(!proximity || target == user || !ismob(target) || !iscarbon(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //exploding after touching yourself would be bad
return
var/mob/M = target
do_sparks(4, 0, M.loc) //no idea what the 0 is
@@ -94,7 +96,7 @@
/obj/item/melee/touch_attack/fleshtostone/afterattack(atom/target, mob/living/carbon/user, proximity)
- if(!proximity || target == user || !isliving(target) || !iscarbon(user)) //getting hard after touching yourself would also be bad
+ if(!proximity || target == user || !isliving(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //getting hard after touching yourself would also be bad
return
if(user.incapacitated())
to_chat(user, "You can't reach out!")
@@ -116,7 +118,7 @@
/obj/item/melee/touch_attack/fake_disintegrate/afterattack(atom/target, mob/living/carbon/user, proximity)
- if(!proximity || target == user || !ismob(target) || !iscarbon(user) || user.incapacitated()) //not exploding after touching yourself would be bad
+ if(!proximity || target == user || !ismob(target) || !iscarbon(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //not exploding after touching yourself would be bad
return
do_sparks(4, 0, target.loc)
playsound(target.loc, 'sound/goonstation/effects/gib.ogg', 50, 1)
@@ -133,7 +135,7 @@
/obj/item/melee/touch_attack/cluwne/afterattack(atom/target, mob/living/carbon/user, proximity)
- if(!proximity || target == user || !ishuman(target) || !iscarbon(user) || user.incapacitated()) //clowning around after touching yourself would unsurprisingly, be bad
+ if(!proximity || target == user || !ishuman(target) || !iscarbon(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //clowning around after touching yourself would unsurprisingly, be bad
return
if(iswizard(target))
diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm
index 192a3647c28..4ab663afcc3 100644
--- a/code/game/machinery/OpTable.dm
+++ b/code/game/machinery/OpTable.dm
@@ -37,7 +37,7 @@
return
if(!check_table()) //If the Operating Table is occupied, you cannot put someone else on it
return
- if(user.buckled || user.incapacitated()) //Is the person trying to use the table incapacitated or restrained?
+ if(user.buckled || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //Is the person trying to use the table incapacitated or restrained?
return
if(!ismob(O) || !iscarbon(O)) //Only Mobs and Carbons can go on this table (no syptic patches please)
return
@@ -98,7 +98,7 @@
set name = "Climb On Table"
set category = "Object"
set src in oview(1)
- if(usr.stat || !iscarbon(usr) || usr.restrained() || !check_table())
+ if(!iscarbon(usr) || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || !check_table())
return
take_patient(usr, usr)
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm
index 30cb8b9a736..5bdaee6f8c6 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/Sleeper.dm
@@ -467,7 +467,7 @@
if(usr.default_can_use_topic(src) != STATUS_INTERACTIVE)
return
- if(usr.incapacitated()) //are you cuffed, dying, lying, stunned or other
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED)) //are you cuffed, dying, lying, stunned or other
return
go_out()
@@ -479,7 +479,7 @@
set category = "Object"
set src in oview(1)
- if(usr.incapacitated() || !Adjacent(usr))
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || !Adjacent(usr))
return
if(beaker)
@@ -494,7 +494,7 @@
/obj/machinery/sleeper/MouseDrop_T(atom/movable/O, mob/user, params)
if(O.loc == user) //no you can't pull things out of your ass
return
- if(user.incapacitated()) //are you cuffed, dying, lying, stunned or other
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //are you cuffed, dying, lying, stunned or other
return
if(get_dist(user, src) > 1 || get_dist(user, O) > 1 || user.contents.Find(src)) // is the mob anchored, too far away from you, or are you too far away from the source
return
@@ -559,7 +559,7 @@
set name = "Enter Sleeper"
set category = "Object"
set src in oview(1)
- if(usr.stat != 0 || !(ishuman(usr)))
+ if(!ishuman(usr) || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || usr.buckled)
return
if(occupant)
to_chat(usr, span_boldnotice("The sleeper is already occupied!"))
@@ -567,8 +567,6 @@
if(panel_open)
to_chat(usr, span_boldnotice("Close the maintenance panel first."))
return
- if(usr.incapacitated() || usr.buckled) //are you cuffed, dying, lying, stunned or other
- return
if(usr.has_buckled_mobs()) //mob attached to us
to_chat(usr, span_warning("[usr] will not fit into [src] because [usr.p_they()] [usr.p_have()] a slime latched onto [usr.p_their()] head."))
return
diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm
index bcf96816afb..35ab78ac682 100644
--- a/code/game/machinery/adv_med.dm
+++ b/code/game/machinery/adv_med.dm
@@ -117,7 +117,7 @@
/obj/machinery/bodyscanner/MouseDrop_T(mob/living/carbon/human/H, mob/user, params)
if(!istype(H))
return FALSE //not human
- if(user.incapacitated())
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return FALSE //user shouldn't be doing things
if(H.anchored)
return FALSE //mob is anchored???
@@ -177,7 +177,7 @@
ui_interact(user)
/obj/machinery/bodyscanner/relaymove(mob/user)
- if(user.incapacitated())
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return FALSE //maybe they should be able to get out with cuffs, but whatever
go_out()
@@ -186,7 +186,7 @@
set category = "Object"
set name = "Eject Body Scanner"
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
go_out()
add_fingerprint(usr)
diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm
index 53ea75324b7..1079c167b59 100644
--- a/code/game/machinery/computer/buildandrepair.dm
+++ b/code/game/machinery/computer/buildandrepair.dm
@@ -553,11 +553,11 @@
/obj/structure/computerframe/AltClick(mob/user)
- if(user.incapacitated())
- to_chat(user, span_warning("You can't do that right now!"))
- return
if(!Adjacent(user))
return
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, span_warning("You can't do that right now!"))
+ return
if(anchored)
to_chat(user, span_warning("The frame is anchored to the floor!"))
return
diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm
index 982580bac54..b16b7993ef8 100644
--- a/code/game/machinery/computer/card.dm
+++ b/code/game/machinery/computer/card.dm
@@ -131,7 +131,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
set name = "Eject ID Card"
set src in oview(1)
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(scan)
diff --git a/code/game/machinery/computer/law.dm b/code/game/machinery/computer/law.dm
index 5d4164f2c9f..3e5c1ee8721 100644
--- a/code/game/machinery/computer/law.dm
+++ b/code/game/machinery/computer/law.dm
@@ -5,29 +5,12 @@
icon_keyboard = "med_key"
circuit = /obj/item/circuitboard/aiupload
var/mob/living/silicon/ai/current = null
- var/opened = 0
light_color = LIGHT_COLOR_WHITE
light_range_on = 2
-// What the fuck even is this
-/obj/machinery/computer/aiupload/verb/AccessInternals()
- set category = "Object"
- set name = "Access Computer's Internals"
- set src in oview(1)
- if(get_dist(src, usr) > 1 || usr.incapacitated() || istype(usr, /mob/living/silicon))
- return
-
- opened = !opened
- if(opened)
- to_chat(usr, span_notice("The access panel is now open."))
- else
- to_chat(usr, span_notice("The access panel is now closed."))
- return
-
-
-/obj/machinery/computer/aiupload/attackby(obj/item/O as obj, mob/user as mob, params)
+/obj/machinery/computer/aiupload/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/aiModule))
if(!current)//no AI selected
to_chat(user, span_danger("No AI selected. Please chose a target before proceeding with upload."))
@@ -46,7 +29,7 @@
return ..()
-/obj/machinery/computer/aiupload/attack_hand(var/mob/user as mob)
+/obj/machinery/computer/aiupload/attack_hand(mob/user)
if(src.stat & NOPOWER)
to_chat(usr, "The upload computer has no power!")
return
@@ -65,8 +48,10 @@
to_chat(usr, "[src.current.name] selected for law changes.")
return
-/obj/machinery/computer/aiupload/attack_ghost(user as mob)
- return 1
+
+/obj/machinery/computer/aiupload/attack_ghost(mob/user)
+ return TRUE
+
// Why is this not a subtype
/obj/machinery/computer/borgupload
@@ -78,7 +63,7 @@
var/mob/living/silicon/robot/current = null
-/obj/machinery/computer/borgupload/attackby(obj/item/aiModule/module as obj, mob/user as mob, params)
+/obj/machinery/computer/borgupload/attackby(obj/item/aiModule/module, mob/user, params)
if(istype(module, /obj/item/aiModule))
if(!current)//no borg selected
to_chat(user, span_danger("No borg selected. Please chose a target before proceeding with upload."))
@@ -92,7 +77,7 @@
return ..()
-/obj/machinery/computer/borgupload/attack_hand(var/mob/user as mob)
+/obj/machinery/computer/borgupload/attack_hand(mob/user)
if(src.stat & NOPOWER)
to_chat(usr, "The upload computer has no power!")
return
@@ -108,5 +93,7 @@
to_chat(usr, "[src.current.name] selected for law changes.")
return
-/obj/machinery/computer/borgupload/attack_ghost(user as mob)
- return 1
+
+/obj/machinery/computer/borgupload/attack_ghost(mob/user)
+ return TRUE
+
diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm
index 846d33739aa..e4b93656210 100644
--- a/code/game/machinery/cryo.dm
+++ b/code/game/machinery/cryo.dm
@@ -130,7 +130,7 @@
/obj/machinery/atmospherics/unary/cryo_cell/MouseDrop_T(atom/movable/O, mob/living/user, params)
if(O.loc == user) //no you can't pull things out of your ass
return
- if(user.incapacitated()) //are you cuffed, dying, lying, stunned or other
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //are you cuffed, dying, lying, stunned or other
return
if(get_dist(user, src) > 1 || get_dist(user, O) > 1 || user.contents.Find(src)) // is the mob anchored, too far away from you, or are you too far away from the source
return
@@ -486,7 +486,7 @@
/obj/machinery/atmospherics/unary/cryo_cell/AltClick(mob/living/carbon/user)
- if(user && (!iscarbon(user) || user.incapacitated() || user.restrained() || !Adjacent(user)))
+ if(!iscarbon(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user))
return
go_out()
add_fingerprint(user)
@@ -508,12 +508,12 @@
else
if(usr.default_can_use_topic(src) != STATUS_INTERACTIVE)
return
- if(usr.incapacitated()) //are you cuffed, dying, lying, stunned or other
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED)) //are you cuffed, dying, lying, stunned or other
return
add_attack_logs(usr, occupant, "Ejected from cryo cell at [COORD(src)]")
go_out()
add_fingerprint(usr)
- return
+
/obj/machinery/atmospherics/unary/cryo_cell/narsie_act()
go_out()
@@ -538,7 +538,7 @@
if(stat & (NOPOWER|BROKEN))
return
- if(usr.incapacitated() || usr.buckled) //are you cuffed, dying, lying, stunned or other
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || usr.buckled) //are you cuffed, dying, lying, stunned or other
return
put_mob(usr)
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index e6127d34c67..48a23ad3729 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -538,7 +538,7 @@
if(O.loc == user) //no you can't pull things out of your ass
return
- if(user.incapacitated()) //are you cuffed, dying, lying, stunned or other
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //are you cuffed, dying, lying, stunned or other
return
if(get_dist(user, src) > 1 || get_dist(user, O) > 1 || user.contents.Find(src)) // is the mob anchored, too far away from you, or are you too far away from the source
return
@@ -636,7 +636,7 @@
set category = "Object"
set src in oview(1)
- if(usr.stat != 0)
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(usr != occupant)
@@ -661,7 +661,7 @@
set category = "Object"
set src in oview(1)
- if(usr.stat != 0 || !check_occupant_allowed(usr))
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || !check_occupant_allowed(usr))
return
if(occupant)
diff --git a/code/game/machinery/defib_mount.dm b/code/game/machinery/defib_mount.dm
index f2f56ef4cac..676db7bd715 100644
--- a/code/game/machinery/defib_mount.dm
+++ b/code/game/machinery/defib_mount.dm
@@ -142,9 +142,9 @@
/obj/machinery/defibrillator_mount/AltClick(mob/living/carbon/human/user)
- if(!Adjacent(user))
+ if(!istype(user) || !Adjacent(user))
return
- if(!istype(user) || user.incapacitated())
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
to_chat(user, span_warning("You can't do that right now!"))
return
if(!defib)
diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm
index cdbca9e8467..226b0cc0186 100644
--- a/code/game/machinery/deployable.dm
+++ b/code/game/machinery/deployable.dm
@@ -169,7 +169,7 @@
. += span_notice("Alt-click to toggle modes.")
/obj/item/grenade/barrier/AltClick(mob/living/carbon/user)
- if(!istype(user) || !user.Adjacent(src) || user.incapacitated())
+ if(!istype(user) || !user.Adjacent(src) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
toggle_mode(user)
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 21284f8846f..9c2e3cde763 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -108,7 +108,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(M.mob_size > MOB_SIZE_TINY)
bumpopen(M)
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index f107c8cbb7d..38cd8a945a4 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -90,7 +90,7 @@
if(!SSticker)
return
var/mob/living/M = moving_atom
- if(!M.restrained() && M.mob_size > MOB_SIZE_TINY && (!(isrobot(M) && M.stat)))
+ if(!HAS_TRAIT(M, TRAIT_HANDS_BLOCKED) && M.mob_size > MOB_SIZE_TINY && (!(isrobot(M) && M.stat)))
bumpopen(M)
/obj/machinery/door/window/bumpopen(mob/user)
diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm
index 89c854ebf4b..aec0faf51a0 100644
--- a/code/game/machinery/doppler_array.dm
+++ b/code/game/machinery/doppler_array.dm
@@ -64,6 +64,7 @@ GLOBAL_LIST_EMPTY(doppler_arrays)
/obj/machinery/doppler_array/attack_ghost(mob/user)
ui_interact(user)
+
/obj/machinery/doppler_array/AltClick(mob/user)
rotate(user)
@@ -76,7 +77,7 @@ GLOBAL_LIST_EMPTY(doppler_arrays)
/obj/machinery/doppler_array/proc/rotate(mob/user)
- if(user.incapacitated())
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(!Adjacent(user))
return
diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm
index a76550a7ee8..f466b97cc43 100644
--- a/code/game/machinery/iv_drip.dm
+++ b/code/game/machinery/iv_drip.dm
@@ -27,7 +27,7 @@
/obj/machinery/iv_drip/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
- if(usr.incapacitated() || !ishuman(usr) || !ishuman(over_object) || !Adjacent(over_object) || !usr.Adjacent(over_object))
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || !ishuman(usr) || !ishuman(over_object) || !Adjacent(over_object) || !usr.Adjacent(over_object))
return FALSE
add_fingerprint(usr)
diff --git a/code/game/machinery/mass_driver.dm b/code/game/machinery/mass_driver.dm
index 788effb9b46..4d98f81c249 100644
--- a/code/game/machinery/mass_driver.dm
+++ b/code/game/machinery/mass_driver.dm
@@ -195,8 +195,8 @@
set name = "Rotate Frame"
set src in view(1)
- if( usr.stat || usr.restrained() || HAS_TRAIT(usr, TRAIT_FAKEDEATH))
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || HAS_TRAIT(usr, TRAIT_FAKEDEATH))
return
src.dir = turn(src.dir, -90)
- return
+
diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm
index f8ae64fa80f..c77465e42b5 100644
--- a/code/game/machinery/pipe/construction.dm
+++ b/code/game/machinery/pipe/construction.dm
@@ -152,7 +152,8 @@
return ..()
/obj/item/pipe/AltClick(mob/user)
- rotate()
+ if(Adjacent(user))
+ rotate()
/obj/item/pipe/proc/update(var/obj/machinery/atmospherics/make_from)
name = "[get_pipe_name(pipe_type, PIPETYPE_ATMOS)] fitting"
@@ -182,7 +183,7 @@
set name = "Rotate Pipe"
set src in view(1)
- if( usr.stat || usr.restrained() )
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(pipe_type == PIPE_CIRCULATOR)
@@ -193,14 +194,13 @@
fixdir()
- return
/obj/item/pipe/verb/flip()
set category = "Object"
set name = "Flip Pipe"
set src in view(1)
- if(usr.stat || usr.restrained())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(pipe_type in list(PIPE_GAS_FILTER, PIPE_GAS_MIXER, PIPE_TVALVE, PIPE_DTVALVE, PIPE_CIRCULATOR))
@@ -215,7 +215,6 @@
fixdir()
- return
/obj/item/pipe/Move()
. = ..()
@@ -324,7 +323,7 @@
else if(pipe_type in list(PIPE_MANIFOLD4W, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W))
dir = 2
-/obj/item/pipe/attack_self(mob/user as mob)
+/obj/item/pipe/attack_self(mob/user)
return rotate()
/obj/item/pipe/wrench_act(mob/user, obj/item/I)
diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm
index 7f3d4dc7396..fa518e1cfae 100644
--- a/code/game/machinery/pipe/pipe_dispenser.dm
+++ b/code/game/machinery/pipe/pipe_dispenser.dm
@@ -139,7 +139,7 @@
//Allow you to drag-drop disposal pipes into it
/obj/machinery/pipedispenser/disposal/MouseDrop_T(obj/structure/disposalconstruct/pipe, mob/user, params)
- if(user.incapacitated())
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(!istype(pipe) || get_dist(user, src) > 1 || get_dist(src, pipe) > 1 )
diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm
index 17d5212ca5d..c36adb4cfff 100644
--- a/code/game/machinery/rechargestation.dm
+++ b/code/game/machinery/rechargestation.dm
@@ -172,7 +172,7 @@
/obj/machinery/recharge_station/proc/go_out(mob/user = usr)
if(!occupant)
return
- if(user?.incapacitated() || user?.restrained())
+ if(user && (user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)))
return
occupant.forceMove(loc)
occupant = null
diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm
index 33b2bc3c359..eda89339c75 100644
--- a/code/game/machinery/recycler.dm
+++ b/code/game/machinery/recycler.dm
@@ -202,7 +202,7 @@
var/mob/living/user = usr
- if(usr.incapacitated())
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(anchored)
to_chat(usr, "[src] is fastened to the floor!")
@@ -218,7 +218,7 @@
var/mob/living/user = usr
- if(usr.incapacitated())
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(anchored)
to_chat(usr, "[src] is fastened to the floor!")
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index 755229e5130..6543f3226fd 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -383,7 +383,7 @@
qdel(src)
/obj/machinery/suit_storage_unit/MouseDrop_T(atom/A, mob/user, params)
- if(user.incapacitated() || !Adjacent(user) || !Adjacent(A) || !isliving(A))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user) || !Adjacent(A) || !isliving(A))
return
. = TRUE
var/mob/living/target = A
@@ -708,9 +708,7 @@
set category = "Object"
set src in oview(1)
- if(usr.stat)
- return
- if(usr.incapacitated() || usr.buckled) //are you cuffed, dying, lying, stunned or other
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || usr.buckled) //are you cuffed, dying, lying, stunned or other
return
if(!state_open)
to_chat(usr, span_warning("The unit's doors are shut."))
diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm
index 178eb9e1375..4b605c83856 100644
--- a/code/game/machinery/washing_machine.dm
+++ b/code/game/machinery/washing_machine.dm
@@ -28,7 +28,7 @@
set category = "Object"
set src in oview(1)
- if(!isliving(usr)) //ew ew ew usr, but it's the only way to check.
+ if(!isliving(usr) || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED)) //ew ew ew usr, but it's the only way to check.
return
if( state != 4 )
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 3acde986c05..7a34faefc57 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -1242,7 +1242,7 @@
if(frozen)
to_chat(user, span_warning("Do not enter Admin-Frozen mechs."))
return TRUE
- if(user.incapacitated())
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(user != M)
return
diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm
index 41d91255142..de7581c3be1 100644
--- a/code/game/objects/buckling.dm
+++ b/code/game/objects/buckling.dm
@@ -231,7 +231,7 @@
return FALSE
// If the buckle requires restraints, make sure the target is actually restrained.
- if(buckle_requires_restraints && !target.restrained())
+ if(buckle_requires_restraints && !HAS_TRAIT(target, TRAIT_RESTRAINED))
return FALSE
//If buckling is forbidden for the target, cancel
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index fdc928d61e3..7a6762359f7 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -349,18 +349,6 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/g
if(!user)
return
- if(ishuman(user))
- var/mob/living/carbon/human/H = user
- var/obj/item/organ/external/temp = H.bodyparts_by_name[BODY_ZONE_PRECISE_R_HAND]
- if(user.hand)
- temp = H.bodyparts_by_name[BODY_ZONE_PRECISE_L_HAND]
- if(!temp)
- to_chat(user, span_warning("You try to use your hand, but it's missing!"))
- return
- if(temp && !temp.is_usable())
- to_chat(user, span_warning("You try to move your [temp.name], but cannot!"))
- return
-
if((resistance_flags & ON_FIRE) && !pickupfireoverride)
var/mob/living/carbon/human/H = user
if(istype(H))
@@ -388,6 +376,9 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/g
if(throwing)
throwing.finalize()
+ if(anchored)
+ return
+
if(loc == user)
if(!allow_attack_hand_drop(user))
return
@@ -796,26 +787,11 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/g
set category = null
set name = "Pick up"
- if(!(usr)) //BS12 EDIT
- return
- if(usr.incapacitated() || !Adjacent(usr))
+ if(usr.incapacitated() || !isturf(loc) || !Adjacent(usr))
return
- if(!iscarbon(usr) || isbrain(usr)) //Is humanoid, and is not a brain
- to_chat(usr, "You can't pick things up!")
+ if(!iscarbon(usr))
+ to_chat(usr, span_warning("You can't pick things up!"))
return
- if(anchored) //Object isn't anchored
- to_chat(usr, "You can't pick that up!")
- return
- if(!usr.hand && usr.r_hand) //Right hand is not full
- to_chat(usr, "Your right hand is full.")
- return
- if(usr.hand && usr.l_hand) //Left hand is not full
- to_chat(usr, "Your left hand is full.")
- return
- if(!isturf(loc)) //Object is on a turf
- to_chat(usr, "You can't pick that up!")
- return
- //All checks are done, time to pick it up!
usr.UnarmedAttack(src)
@@ -1048,7 +1024,7 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/g
/obj/item/MouseDrop_T(atom/dropping, mob/user, params)
- if(!user || user.incapacitated(ignore_lying = TRUE) || src == dropping)
+ if(!user || user.incapacitated(ignore_lying = TRUE) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || src == dropping)
return FALSE
if(loc && dropping.loc == loc && isstorage(loc) && loc.Adjacent(user)) // Are we trying to swap two items in the storage?
@@ -1099,7 +1075,7 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/g
return 0
-/obj/item/proc/update_equipped_item(update_buttons = TRUE)
+/obj/item/proc/update_equipped_item(update_buttons = TRUE, update_speedmods = TRUE)
if(!ismob(loc) || QDELETED(src) || QDELETED(loc))
return
@@ -1161,7 +1137,14 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/g
if(ITEM_SLOT_HAND_RIGHT)
owner.update_inv_r_hand()
- owner.update_equipment_speed_mods()
+ if(ITEM_SLOT_HANDCUFFED)
+ owner.update_inv_handcuffed()
+
+ if(ITEM_SLOT_LEGCUFFED)
+ owner.update_inv_legcuffed()
+
+ if(update_speedmods)
+ owner.update_equipment_speed_mods()
if(update_buttons)
for(var/datum/action/action as anything in actions)
diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm
index edc214b21c9..6b5c9ee8b5b 100644
--- a/code/game/objects/items/bodybag.dm
+++ b/code/game/objects/items/bodybag.dm
@@ -62,7 +62,7 @@
/obj/structure/closet/body_bag/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
- if(over_object == usr && ishuman(usr) && !usr.incapacitated() && !opened && !length(contents) && usr.Adjacent(src))
+ if(over_object == usr && ishuman(usr) && !usr.incapacitated() && !HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) && !opened && !length(contents) && usr.Adjacent(src))
usr.visible_message(
span_notice("[usr] folds up [src]."),
span_notice("You fold up [src]."),
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index d89c7af52b6..0a78c48befb 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -73,7 +73,7 @@
temp = pick(graffiti)
else
temp = href_list["type"]
- if((usr.restrained() || usr.stat || !usr.is_in_active_hand(src)))
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || !usr.is_in_active_hand(src))
return
drawtype = temp
update_window(usr)
diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm
index b1d63635c34..42914c79103 100644
--- a/code/game/objects/items/devices/flashlight.dm
+++ b/code/game/objects/items/devices/flashlight.dm
@@ -158,8 +158,10 @@
set category = "Object"
set src in oview(1)
- if(!usr.stat)
- attack_self(usr)
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ return
+
+ attack_self(usr)
//Bananalamp
/obj/item/flashlight/lamp/bananalamp
diff --git a/code/game/objects/items/devices/pizza_bomb.dm b/code/game/objects/items/devices/pizza_bomb.dm
index 9b4ffeadd23..a53992f0314 100644
--- a/code/game/objects/items/devices/pizza_bomb.dm
+++ b/code/game/objects/items/devices/pizza_bomb.dm
@@ -53,7 +53,7 @@
if(!timer_set)
update_appearance(UPDATE_ICON_STATE|UPDATE_NAME|UPDATE_DESC)
timer = (input(user, "Set a timer, from one second to ten seconds.", "Timer", "[timer]") as num) * 10
- if(!in_range(src, usr) || issilicon(usr) || !usr.canmove || usr.restrained())
+ if(!Adjacent(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
timer_set = 0
name = "pizza box"
desc = "A box suited for pizzas."
@@ -92,7 +92,7 @@
if(I.tool_behaviour == TOOL_WIRECUTTER && primed)
to_chat(user, "Oh God, what wire do you cut?!")
var/chosen_wire = input(user, "OH GOD OH GOD", "WHAT WIRE?!") in wires
- if(!in_range(src, usr) || issilicon(usr) || !usr.canmove || usr.restrained())
+ if(!Adjacent(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
playsound(src, I.usesound, 50, 1, 1)
user.visible_message("[user] cuts the [chosen_wire] wire!", "You cut the [chosen_wire] wire!")
diff --git a/code/game/objects/items/devices/radio/beacon.dm b/code/game/objects/items/devices/radio/beacon.dm
index 418a1296131..605b6ea8883 100644
--- a/code/game/objects/items/devices/radio/beacon.dm
+++ b/code/game/objects/items/devices/radio/beacon.dm
@@ -40,7 +40,7 @@
set category = "Object"
set src in usr
- if(usr.stat || usr.restrained())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
code = t
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index e8564ee5380..2868ad24e3c 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -596,11 +596,11 @@ GLOBAL_LIST_INIT(default_medbay_channels, list(
. += "Ctrl-Shift-click on the [name] to toggle speaker.
Alt-click on the [name] to toggle broadcasting."
/obj/item/radio/AltClick(mob/user)
- if(!Adjacent(user))
+ if(!iscarbon(user) && !isrobot(user))
return
- if(!iscarbon(usr) && !isrobot(usr))
+ if(!Adjacent(user))
return
- if(!istype(user) || user.incapacitated())
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
to_chat(user, "You can't do that right now!")
return
broadcasting = !broadcasting
@@ -611,7 +611,7 @@ GLOBAL_LIST_INIT(default_medbay_channels, list(
return
if(!iscarbon(usr) && !isrobot(usr))
return
- if(!istype(user) || user.incapacitated())
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
to_chat(user, "You can't do that right now!")
return
listening = !listening
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index d26a37750c1..a0f17c15721 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -623,6 +623,9 @@ REAGENT SCANNER
set name = "Вкл/Выкл локализацию"
set category = "Object"
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ return
+
mode = !mode
switch(mode)
if(1)
diff --git a/code/game/objects/items/devices/scanners/gas_analyzer.dm b/code/game/objects/items/devices/scanners/gas_analyzer.dm
index 9afa0ff7fd2..462653c58bd 100644
--- a/code/game/objects/items/devices/scanners/gas_analyzer.dm
+++ b/code/game/objects/items/devices/scanners/gas_analyzer.dm
@@ -40,10 +40,10 @@
return BRUTELOSS
/obj/item/analyzer/AltClick(mob/living/user) //Barometer output for measuring when the next storm happens
- if(!istype(user) || user.incapacitated())
- to_chat(user, "You can't do that right now!")
+ if(!istype(user) || !Adjacent(user))
return
- if(!Adjacent(user))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, "You can't do that right now!")
return
if(cooldown)
to_chat(user, "[src]'s barometer function is prepraring itself.")
diff --git a/code/game/objects/items/devices/sensor_device.dm b/code/game/objects/items/devices/sensor_device.dm
index 0e0393327f5..671ee2ce0f8 100644
--- a/code/game/objects/items/devices/sensor_device.dm
+++ b/code/game/objects/items/devices/sensor_device.dm
@@ -27,7 +27,7 @@
return FALSE
var/mob/user = usr
- if(user.incapacitated() || !ishuman(user))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !ishuman(user))
return FALSE
if(over_object == user)
diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm
index 313704c45c2..9a7004de19e 100644
--- a/code/game/objects/items/devices/taperecorder.dm
+++ b/code/game/objects/items/devices/taperecorder.dm
@@ -114,7 +114,7 @@
/obj/item/taperecorder/AltClick(mob/living/user)
- if(istype(user) && in_range(user, src) && mytape && !user.incapacitated())
+ if(istype(user) && mytape && !user.incapacitated() && !HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) && Adjacent(user))
var/list/options = list( "Playback Tape" = image(icon = 'icons/obj/device.dmi', icon_state = "taperecorder_playing"),
"Print Transcript" = image(icon = 'icons/obj/bureaucracy.dmi', icon_state = "paper_words"),
"Eject Tape" = image(icon = 'icons/obj/device.dmi', icon_state = "[mytape.icon_state]")
@@ -436,7 +436,7 @@
set src in view(1)
var/mob/living/carbon/user = usr
- if(!istype(user) || user.incapacitated())
+ if(!istype(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(ruined)
return
diff --git a/code/game/objects/items/devices/tts.dm b/code/game/objects/items/devices/tts.dm
index 36392762e92..7a2bce06026 100644
--- a/code/game/objects/items/devices/tts.dm
+++ b/code/game/objects/items/devices/tts.dm
@@ -26,12 +26,14 @@
add_say_logs(user, input, language = "TTS")
/obj/item/ttsdevice/AltClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, "You can't do that right now!")
+ if(!istype(user) || !Adjacent(user))
return
- if(!Adjacent(user))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, "You can't do that right now!")
return
var/noisechoice = input(user, "What noise would you like to make?", "Robot Noises") as null|anything in list("Beep","Buzz","Ping")
+ if(!noisechoice || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ return
switch(noisechoice)
if("Beep")
user.visible_message("[user] has made their TTS beep!", "You make your TTS beep!")
@@ -44,10 +46,11 @@
playsound(user, 'sound/machines/ping.ogg', 50, 1, -1)
/obj/item/ttsdevice/CtrlClick(mob/living/user)
- if(!src.Adjacent(user))
+ if(!Adjacent(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
var/new_name = input(user, "Name your Text-to-Speech device: \nThis matters for displaying it in the chat bar:", "TTS Device") as text|null
- if(new_name)
- new_name = reject_bad_name(new_name)
- name = "[new_name]'s [initial(name)]"
+ if(!new_name || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ return
+ new_name = reject_bad_name(new_name)
+ name = "[new_name]'s [initial(name)]"
change_voice(user)
diff --git a/code/game/objects/items/flag.dm b/code/game/objects/items/flag.dm
index 8bd06ec1d58..7b2c24949b1 100644
--- a/code/game/objects/items/flag.dm
+++ b/code/game/objects/items/flag.dm
@@ -42,7 +42,7 @@
custom_fire_overlay = initial(custom_fire_overlay)
if(resistance_flags & ON_FIRE)
item_state = "[item_state]_fire"
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
/obj/item/flag/proc/updateFlagIcon()
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index 3818c038852..4e1016bd6d2 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -291,21 +291,17 @@
/obj/item/stack/AltClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, span_warning("You can't do that right now!"))
- return
- if(!in_range(src, user))
- return
- if(!ishuman(user))
+ if(!ishuman(user) || amount < 1 || !Adjacent(user))
return
- if(amount < 1)
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, span_warning("You can't do that right now!"))
return
//get amount from user
var/max = get_amount()
var/stackmaterial = round(input(user, "How many sheets do you wish to take out of this stack? (Maximum: [max])") as null|num)
if(stackmaterial == null || stackmaterial <= 0 || stackmaterial > get_amount())
return
- if(!Adjacent(user, 1))
+ if(amount < 1 || !Adjacent(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
split_stack(user, stackmaterial)
do_pickup_animation(user)
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 3c8fc31ad1d..c9fae09b765 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -2069,18 +2069,15 @@
set category = "Object"
set src in oview(1)
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ to_chat(usr, "You can't do that right now!")
return
dir = turn(dir, 270)
- return 1
+ return TRUE
+
/obj/item/toy/desk/AltClick(mob/user)
- if(user.incapacitated())
- to_chat(user, "You can't do that right now!")
- return
- if(!in_range(src, user))
- return
- else
+ if(Adjacent(user))
rotate()
/obj/item/toy/desk/officetoy
diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm
index 6d14bac9b06..8b5bd82f023 100644
--- a/code/game/objects/items/weapons/cards_ids.dm
+++ b/code/game/objects/items/weapons/cards_ids.dm
@@ -31,17 +31,6 @@
var/special = null
item_state = "card-id"
-/obj/item/card/data/verb/label(t as text)
- set name = "Label Disk"
- set category = "Object"
- set src in usr
-
- if(t)
- src.name = text("Data Disk- '[]'", t)
- else
- src.name = "Data Disk"
- src.add_fingerprint(usr)
- return
/obj/item/card/data/clown
name = "coordinates to clown planet"
@@ -298,7 +287,7 @@
set category = "Object"
set src in range(0)
- if(usr.stat || !usr.canmove || usr.restrained())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(guest_pass)
diff --git a/code/game/objects/items/weapons/cigs.dm b/code/game/objects/items/weapons/cigs.dm
index 12027c5eaf0..5566f7cd1f5 100644
--- a/code/game/objects/items/weapons/cigs.dm
+++ b/code/game/objects/items/weapons/cigs.dm
@@ -170,7 +170,7 @@ LIGHTERS ARE IN LIGHTERS.DM
/obj/item/clothing/mask/cigarette/update_icon_state()
icon_state = lit ? icon_on : icon_off
item_state = lit ? icon_on : initial(item_state)
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
/obj/item/clothing/mask/cigarette/update_name(updates = ALL)
diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm
index 805319e2f56..ee503c074f6 100644
--- a/code/game/objects/items/weapons/defib.dm
+++ b/code/game/objects/items/weapons/defib.dm
@@ -113,7 +113,7 @@
/obj/item/defibrillator/CtrlClick(mob/user)
- if(!ishuman(user) || !Adjacent(user))
+ if(!ishuman(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user))
return
toggle_paddles(user)
@@ -178,6 +178,9 @@
set category = "Object"
set src in oview(1)
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ return
+
toggle_paddles(usr)
diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm
index 87a2750255e..8f02fc6a346 100644
--- a/code/game/objects/items/weapons/flamethrower.dm
+++ b/code/game/objects/items/weapons/flamethrower.dm
@@ -50,7 +50,7 @@
/obj/item/flamethrower/update_icon(updates = ALL)
. = ..()
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
@@ -154,10 +154,12 @@
toggle_igniter(user)
/obj/item/flamethrower/AltClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
+ if(!istype(user) || !Adjacent(user))
+ return
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
to_chat(user, "You can't do that right now!")
return
- if(ptank && user.Adjacent(src))
+ if(ptank)
ptank.forceMove_turf()
user.put_in_hands(ptank, ignore_anim = FALSE)
ptank = null
diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm
index fe4283b1340..ed564085e8a 100644
--- a/code/game/objects/items/weapons/handcuffs.dm
+++ b/code/game/objects/items/weapons/handcuffs.dm
@@ -21,11 +21,11 @@
var/ignoresClumsy = FALSE
-/obj/item/restraints/handcuffs/attack(mob/living/carbon/C, mob/living/user)
- if(!istype(C)) // Shouldn't be able to cuff anything but carbons.
+/obj/item/restraints/handcuffs/attack(mob/living/carbon/target, mob/living/user)
+ if(!iscarbon(target)) // Shouldn't be able to cuff anything but carbons.
return
- if(C.handcuffed)
+ if(target.handcuffed)
return
if(!user.IsAdvancedToolUser())
@@ -35,26 +35,36 @@
to_chat(user, span_warning("[src] is stuck to your hand!"))
return
- if(!C.has_organ_for_slot(ITEM_SLOT_HANDCUFFED))
+ if(!target.has_organ_for_slot(ITEM_SLOT_HANDCUFFED))
to_chat(user, span_warning("How do you suggest handcuffing someone with no hands?"))
return
- if((CLUMSY in user.mutations) && prob(50) && (!ignoresClumsy))
+ if(!ignoresClumsy && (CLUMSY in user.mutations) && prob(50))
+ playsound(loc, cuffsound, 30, TRUE, -2)
to_chat(user, span_warning("Uh... how do those things work?!"))
apply_cuffs(user, user)
return
- C.visible_message(span_danger("[user] is trying to put [name] on [C]!"), \
- span_userdanger("[user] is trying to put [name] on [C]!"))
- playsound(loc, cuffsound, 30, 1, -2)
+ playsound(loc, cuffsound, 30, TRUE, -2)
- if(do_after(user, 5 SECONDS, C, NONE))
+ if(user == target)
+ target.visible_message(
+ span_warning("[user] is trying to put [name] on [user.p_themselves()]!"),
+ span_warning("You are trying to put [name] on yourself!"),
+ )
+ else
+ target.visible_message(
+ span_danger("[user] is trying to put [name] on [target]!"),
+ span_userdanger("[user] is trying to put [name] on you!"),
+ )
+
+ if(do_after(user, target, 5 SECONDS))
if(isrobot(user))
- apply_cuffs(C, user, TRUE)
+ apply_cuffs(target, user, TRUE)
else
- apply_cuffs(C, user)
+ apply_cuffs(target, user)
else
- to_chat(user, span_warning("You fail to handcuff [C]."))
+ to_chat(user, span_warning("You failed to handcuff [user == target ? "yourself" : target ]!"))
/**
@@ -84,14 +94,23 @@
target.equip_to_slot(cuffs, ITEM_SLOT_HANDCUFFED)
- if(trashtype && !dispense)
- qdel(src)
+ if(user == target)
+ target.visible_message(
+ span_warning("[user] handcuffs [user.p_themselves()]!"),
+ span_warning("You handcuff yourself!"),
+ )
+ else
+ target.visible_message(
+ span_warning("[user] handcuffs [target]!"),
+ span_userdanger("[user] handcuffs you!"),
+ )
- target.visible_message(span_notice("[user] handcuffs [target]."), \
- span_userdanger("[user] handcuffs you."))
add_attack_logs(user, target, "Handcuffed ([src])")
SSblackbox.record_feedback("tally", "handcuffs", 1, type)
+ if(trashtype && !dispense)
+ qdel(src)
+
/obj/item/restraints/handcuffs/sinew
name = "sinew restraints"
diff --git a/code/game/objects/items/weapons/holosign.dm b/code/game/objects/items/weapons/holosign.dm
index cc6e9afec79..e74ad4b563b 100644
--- a/code/game/objects/items/weapons/holosign.dm
+++ b/code/game/objects/items/weapons/holosign.dm
@@ -73,7 +73,9 @@
var/wet_enabled = TRUE
/obj/item/holosign_creator/janitor/AltClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
+ if(!istype(user) || !Adjacent(user))
+ return
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
to_chat(user, "You can't do that right now!")
return
wet_enabled = !wet_enabled
diff --git a/code/game/objects/items/weapons/implants/implantchair.dm b/code/game/objects/items/weapons/implants/implantchair.dm
index f11a3e75097..4dc394004ce 100644
--- a/code/game/objects/items/weapons/implants/implantchair.dm
+++ b/code/game/objects/items/weapons/implants/implantchair.dm
@@ -144,7 +144,7 @@
return FALSE
if(target != user && (!Adjacent(user) && !user.Adjacent(target)))
return FALSE
- if(!isliving(user) || user.incapacitated())
+ if(!isliving(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return FALSE
if(!ishuman(target))
to_chat(user, span_warning("[src] cannot hold this!"))
@@ -169,7 +169,7 @@
return FALSE
if(occupant == user) // so that the guy inside can't eject himself -Agouri
return FALSE
- if(user && (!ishuman(user) || user.incapacitated()))
+ if(user && (!ishuman(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)))
return FALSE
occupant.forceMove(loc)
add_fingerprint(user)
diff --git a/code/game/objects/items/weapons/implants/implantpad.dm b/code/game/objects/items/weapons/implants/implantpad.dm
index 75adb54aa87..4c7e56bb50b 100644
--- a/code/game/objects/items/weapons/implants/implantpad.dm
+++ b/code/game/objects/items/weapons/implants/implantpad.dm
@@ -58,7 +58,7 @@
/obj/item/implantpad/AltClick(mob/living/user)
- if(!ishuman(user) || user.incapacitated() || !Adjacent(user))
+ if(!ishuman(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user))
return
eject_case(user)
diff --git a/code/game/objects/items/weapons/legcuffs.dm b/code/game/objects/items/weapons/legcuffs.dm
index 0d56ba3d350..446330f7bf4 100644
--- a/code/game/objects/items/weapons/legcuffs.dm
+++ b/code/game/objects/items/weapons/legcuffs.dm
@@ -51,7 +51,7 @@
/obj/item/restraints/legcuffs/beartrap/attack_self(mob/user)
..()
- if(ishuman(user) && !user.stat && !user.restrained())
+ if(ishuman(user) && !user.incapacitated() && !HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
armed = !armed
update_icon(UPDATE_ICON_STATE)
to_chat(user, span_notice("[src] is now [armed ? "armed" : "disarmed"]"))
@@ -144,7 +144,7 @@
else
moving_human.apply_damage(trap_damage, BRUTE, (pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)))
- if(moving_human.set_legcuffed(src)) //beartrap can't cuff you leg if there's already a beartrap or legcuffs.
+ if(moving_human.apply_restraints(src, ITEM_SLOT_LEGCUFFED)) //beartrap can't cuff you leg if there's already a beartrap or legcuffs.
SSblackbox.record_feedback("tally", "handcuffs", 1, type)
return
@@ -194,7 +194,7 @@
/obj/item/restraints/legcuffs/bola/update_icon_state()
item_state = spinning ? "[initial(item_state)]_spin" : initial(item_state)
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
/obj/item/restraints/legcuffs/bola/proc/spin_up_wrapper(datum/source, throw_mode_state) // so that signal handler works
@@ -290,7 +290,7 @@
target.visible_message(span_danger("[src] ensnares [target]!"))
to_chat(target, span_userdanger("[src] ensnares you!"))
- target.set_legcuffed(src)
+ target.apply_restraints(src, ITEM_SLOT_LEGCUFFED)
if(weaken_amt)
target.Weaken(weaken_amt)
playsound(loc, hitsound, 50, TRUE)
diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm
index dc4e4f2d543..c3437692121 100644
--- a/code/game/objects/items/weapons/melee/energy.dm
+++ b/code/game/objects/items/weapons/melee/energy.dm
@@ -54,7 +54,7 @@
icon_state = "sword[item_color]"
set_light_on(TRUE)
set_light_color(colormap[item_color])
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
/obj/item/melee/energy/attack_self(mob/living/carbon/user)
diff --git a/code/game/objects/items/weapons/rpd.dm b/code/game/objects/items/weapons/rpd.dm
index a7b354450f4..03cb19448c1 100644
--- a/code/game/objects/items/weapons/rpd.dm
+++ b/code/game/objects/items/weapons/rpd.dm
@@ -186,7 +186,9 @@
/obj/item/rpd/AltClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
+ if(!istype(user) || !Adjacent(user))
+ return
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
to_chat(user, "You can't do that right now!")
return
radial_menu(user)
diff --git a/code/game/objects/items/weapons/scrolls.dm b/code/game/objects/items/weapons/scrolls.dm
index 8b4b8fa492a..36e17417c97 100644
--- a/code/game/objects/items/weapons/scrolls.dm
+++ b/code/game/objects/items/weapons/scrolls.dm
@@ -30,7 +30,7 @@
/obj/item/teleportation_scroll/Topic(href, href_list)
..()
- if(usr.stat || usr.restrained() || src.loc != usr)
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || src.loc != usr)
return
var/mob/living/carbon/human/H = usr
if(!( ishuman(H)))
@@ -54,7 +54,7 @@
var/area/thearea = GLOB.teleportlocs[A]
- if(user.stat || user.restrained())
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(!((user == loc || (in_range(src, user) && istype(src.loc, /turf)))))
return
diff --git a/code/game/objects/items/weapons/staff.dm b/code/game/objects/items/weapons/staff.dm
index 4cb797b2ab3..eeaf4fcab62 100644
--- a/code/game/objects/items/weapons/staff.dm
+++ b/code/game/objects/items/weapons/staff.dm
@@ -22,7 +22,7 @@
/obj/item/twohanded/staff/broom/update_icon_state()
item_state = "[initial(icon_state)][HAS_TRAIT(src, TRAIT_WIELDED)]"
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
/obj/item/twohanded/staff/broom/wield(obj/item/source, mob/living/carbon/user)
diff --git a/code/game/objects/items/weapons/storage/artistic_toolbox.dm b/code/game/objects/items/weapons/storage/artistic_toolbox.dm
index 3cecdf74d96..92f8baec3b6 100644
--- a/code/game/objects/items/weapons/storage/artistic_toolbox.dm
+++ b/code/game/objects/items/weapons/storage/artistic_toolbox.dm
@@ -84,7 +84,7 @@
return
if(!victim)
return
- if(!victim.stat && !victim.restrained() && !victim.IsWeakened())
+ if(!victim.stat && !HAS_TRAIT(victim, TRAIT_RESTRAINED) && !victim.IsWeakened())
to_chat(user, "They're moving too much to feed to His Grace!")
return
user.visible_message("[user] is trying to feed [victim] to [src]!")
diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm
index 6bcf5a0570a..24b02850aa9 100644
--- a/code/game/objects/items/weapons/storage/backpack.dm
+++ b/code/game/objects/items/weapons/storage/backpack.dm
@@ -121,7 +121,7 @@
if(21 to INFINITY)
icon_state = "giftbag2"
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
/obj/item/storage/backpack/cultpack
@@ -391,7 +391,7 @@
set category = "Object"
set src in usr
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
strap_side_straight = !strap_side_straight
icon_state = strap_side_straight ? "satchel-flipped" : "satchel"
diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm
index 777b915f093..570ca836c9c 100644
--- a/code/game/objects/items/weapons/storage/bags.dm
+++ b/code/game/objects/items/weapons/storage/bags.dm
@@ -60,7 +60,7 @@
icon_state = "[initial(icon_state)]1"
else
icon_state = "[initial(icon_state)]"
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
/obj/item/storage/bag/trash/cyborg
@@ -230,7 +230,7 @@
set category = "Object"
set desc = "Activate to convert your plants into plantable seeds."
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
for(var/obj/item/O in contents)
seedify(O, 1)
diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm
index 3d121cf17db..34800a84744 100644
--- a/code/game/objects/items/weapons/storage/belt.dm
+++ b/code/game/objects/items/weapons/storage/belt.dm
@@ -711,7 +711,7 @@
if(length(contents))
icon_state = "[icon_state]-rapier"
item_state = "[item_state]-rapier"
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
// -------------------------------------
@@ -993,7 +993,7 @@
else
icon_state = initial(icon_state)
item_state = initial(item_state)
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
/obj/item/storage/belt/claymore/populate_contents()
diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm
index 7c19a65db25..0c6480cfc9c 100644
--- a/code/game/objects/items/weapons/storage/firstaid.dm
+++ b/code/game/objects/items/weapons/storage/firstaid.dm
@@ -357,7 +357,7 @@
/obj/item/storage/pill_bottle/MouseDrop(mob/living/carbon/user, src_location, over_location, src_control, over_control, params) // Best utilized if you're a cantankerous doctor with a Vicodin habit.
- if(iscarbon(user) && src == user.get_active_hand())
+ if(iscarbon(user) && src == user.get_active_hand() && !HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
if(!length(contents))
to_chat(user, span_notice("There is nothing in [src]!"))
return FALSE
diff --git a/code/game/objects/items/weapons/storage/internal.dm b/code/game/objects/items/weapons/storage/internal.dm
index f9bd2e2d2bb..2ed7d0fcd94 100644
--- a/code/game/objects/items/weapons/storage/internal.dm
+++ b/code/game/objects/items/weapons/storage/internal.dm
@@ -39,7 +39,7 @@
*/
/obj/item/storage/internal/proc/handle_mousedrop(mob/living/carbon/human/user, obj/over_object)
. = FALSE
- if(over_object == user && ishuman(user) && !user.incapacitated() && !ismecha(user.loc) && !is_ventcrawling(user) && user.Adjacent(master_item))
+ if(over_object == user && ishuman(user) && !user.incapacitated() && !HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) && !ismecha(user.loc) && !is_ventcrawling(user) && user.Adjacent(master_item))
open(user)
master_item.add_fingerprint(user)
return TRUE
diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm
index 999413b1db5..93832a643ba 100644
--- a/code/game/objects/items/weapons/storage/secure.dm
+++ b/code/game/objects/items/weapons/storage/secure.dm
@@ -103,16 +103,18 @@
/obj/item/storage/secure/AltClick(mob/living/user)
- if(istype(user) && !try_to_open())
+ if(!try_to_open(user))
return FALSE
return ..()
/obj/item/storage/secure/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
- if(!try_to_open())
+ if(!try_to_open(usr))
return FALSE
return ..()
-/obj/item/storage/secure/proc/try_to_open()
+/obj/item/storage/secure/proc/try_to_open(mob/living/user)
+ if(!istype(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user))
+ return TRUE
if(locked)
add_fingerprint(usr)
to_chat(usr, "It's locked!")
diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm
index 3447b45c1fd..0e27d955c58 100644
--- a/code/game/objects/items/weapons/storage/storage.dm
+++ b/code/game/objects/items/weapons/storage/storage.dm
@@ -140,7 +140,7 @@
/obj/item/storage/AltClick(mob/user)
- if(ishuman(user) && Adjacent(user) && !user.incapacitated(FALSE, TRUE, TRUE))
+ if(ishuman(user) && Adjacent(user) && !user.incapacitated(FALSE, TRUE, TRUE) && !HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
open(user)
else if(isobserver(user))
show_to(user)
@@ -557,7 +557,7 @@
set name = "Empty Contents"
set category = "Object"
- if((!ishuman(usr) && (loc != usr)) || usr.stat || usr.restrained())
+ if((!ishuman(usr) && (loc != usr)) || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
drop_inventory(usr)
diff --git a/code/game/objects/items/weapons/tanks/watertank.dm b/code/game/objects/items/weapons/tanks/watertank.dm
index f038d62e71c..0c9c8b8c0fb 100644
--- a/code/game/objects/items/weapons/tanks/watertank.dm
+++ b/code/game/objects/items/weapons/tanks/watertank.dm
@@ -32,11 +32,14 @@
/obj/item/watertank/verb/toggle_mister()
set name = "Toggle Mister"
set category = "Object"
+
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ return
+
if(usr.get_item_by_slot(ITEM_SLOT_BACK) != src)
to_chat(usr, "The watertank needs to be on your back to use.")
return
- if(usr.incapacitated())
- return
+
on = !on
var/mob/living/carbon/human/user = usr
diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm
index 171ab0f1a5e..f82027032d6 100644
--- a/code/game/objects/items/weapons/teleportation.dm
+++ b/code/game/objects/items/weapons/teleportation.dm
@@ -50,7 +50,7 @@
if(length(turfs))
L["None (Dangerous)"] = pick(turfs)
var/t1 = tgui_input_list(user, "Please select a teleporter to lock in on.", "Hand Teleporter", L)
- if(!t1 || (!user.is_in_active_hand(src) || user.stat || user.restrained()))
+ if(!t1 || !user.is_in_active_hand(src) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(active_portals >= 3)
user.show_message(span_notice("[src] is recharging!"))
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index 650bde7fc8c..4fcaa1ef907 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -222,7 +222,7 @@
return FALSE
if(!Adjacent(user))
return FALSE
- if(user.restrained() || user.buckled)
+ if(HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || user.buckled)
to_chat(user, span_notice("You need your hands and legs free for this."))
return FALSE
if(user.incapacitated())
diff --git a/code/game/objects/structures/coathanger.dm b/code/game/objects/structures/coathanger.dm
index 2f0f691800e..36c7b2aebdd 100644
--- a/code/game/objects/structures/coathanger.dm
+++ b/code/game/objects/structures/coathanger.dm
@@ -57,7 +57,7 @@
break
if(can_hang)
- if(user && !user.drop_transfer_item_to_loc(moving_atom, src))
+ if(user && (user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !user.drop_transfer_item_to_loc(moving_atom, src)))
return .
. = TRUE
coat = moving_atom
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index 1bf269622ea..3d264c2ca28 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -267,7 +267,7 @@ GLOBAL_LIST_EMPTY(closets)
return
if(O.loc == user)
return
- if(user.incapacitated())
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if((!( istype(O, /atom/movable) ) || O.anchored || get_dist(user, src) > 1 || get_dist(user, O) > 1 || user.contents.Find(src)))
return
@@ -320,7 +320,7 @@ GLOBAL_LIST_EMPTY(closets)
set category = null
set name = "Toggle Open"
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(ishuman(usr) || isrobot(usr) || istype(usr, /mob/living/simple_animal/hostile/gorilla))
@@ -449,7 +449,7 @@ GLOBAL_LIST_EMPTY(closets)
/obj/structure/closet/AltClick(mob/living/simple_animal/hostile/gorilla/gorilla)
- if(istype(gorilla) && in_range(gorilla, src))
+ if(istype(gorilla) && !gorilla.incapacitated() && !HAS_TRAIT(gorilla, TRAIT_HANDS_BLOCKED) && Adjacent(gorilla))
gorilla.face_atom(src)
toggle()
gorilla.oogaooga()
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm
index 3d3e952868f..61be2c7ca32 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm
@@ -60,7 +60,9 @@
/obj/structure/closet/secure_closet/proc/togglelock(mob/living/user)
- if(!istype(user) || user.incapacitated())
+ if(!istype(user))
+ return
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
to_chat(user, "You can't do that right now!")
return
if(opened)
@@ -79,32 +81,32 @@
update_icon()
else
to_chat(user, "Access Denied")
+ add_fingerprint(user)
+
/obj/structure/closet/secure_closet/closed_item_click(mob/user)
togglelock(user)
+
/obj/structure/closet/secure_closet/AltClick(mob/user)
if(Adjacent(user))
togglelock(user)
/obj/structure/closet/secure_closet/attack_hand(mob/user)
- add_fingerprint(user)
if(locked)
togglelock(user)
else
+ add_fingerprint(user)
toggle(user)
+
/obj/structure/closet/secure_closet/verb/verb_togglelock()
set src in oview(1) // One square distance
set category = "Object"
set name = "Toggle Lock"
- if(usr.incapacitated()) // Don't use it if you're not able to! Checks for stuns, ghost and restrain
- return
-
if(ishuman(usr) || isrobot(usr) || istype(usr, /mob/living/simple_animal/hostile/gorilla))
- add_fingerprint(usr)
togglelock(usr)
else
to_chat(usr, "This mob type can't use this verb.")
@@ -136,6 +138,9 @@
if(!locked && !welded)
return //It's a secure closet, but isn't locked. Easily escapable from, no need to 'resist'
+ if(user.incapacitated(ignore_restraints = TRUE))
+ return
+
//okay, so the closet is either welded or locked... resist!!!
visible_message(
span_danger("[src] begins to shake violently!"),
@@ -149,7 +154,7 @@
return
//closet/user destroyed OR user dead/unconcious OR user no longer in closet OR closet opened
- if(!src || !user || user.incapacitated() || user.loc != src || opened)
+ if(!src || !user || user.incapacitated(ignore_restraints = TRUE) || user.loc != src || opened)
return
//Perform the same set of checks as above for weld and lock status to determine if there is even still a point in 'resisting'...
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index e932461b3e4..afcdc63ad11 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -214,11 +214,16 @@
/obj/structure/closet/crate/secure/AltClick(mob/living/user)
- if(iscarbon(user) && !user.incapacitated() && Adjacent(user))
+ if(Adjacent(user))
togglelock(user)
-/obj/structure/closet/crate/secure/proc/togglelock(mob/user)
+/obj/structure/closet/crate/secure/proc/togglelock(mob/living/user)
+ if(!istype(user))
+ return
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, "You can't do that right now!")
+ return
if(opened)
to_chat(user, "Close the crate first.")
return
@@ -232,6 +237,7 @@
update_icon()
else
to_chat(user, "Access Denied")
+ add_fingerprint(user)
/obj/structure/closet/crate/secure/verb/verb_togglelock()
@@ -239,12 +245,8 @@
set category = null
set name = "Toggle Lock"
- if(!usr.canmove || usr.stat || usr.restrained()) // Don't use it if you're not able to! Checks for stuns, ghost and restrain
- return
-
if(ishuman(usr) || isrobot(usr) || istype(usr, /mob/living/simple_animal/hostile/gorilla))
- src.add_fingerprint(usr)
- src.togglelock(usr)
+ togglelock(usr)
else
to_chat(usr, "This mob type can't use this verb.")
@@ -260,10 +262,10 @@
manifest = null
update_icon()
return
- add_fingerprint(user)
if(locked)
togglelock(user)
else
+ add_fingerprint(user)
toggle(user, by_hand = TRUE)
diff --git a/code/game/objects/structures/electricchair.dm b/code/game/objects/structures/electricchair.dm
index cd532bf025c..2d889bfda2d 100644
--- a/code/game/objects/structures/electricchair.dm
+++ b/code/game/objects/structures/electricchair.dm
@@ -84,7 +84,7 @@
/obj/structure/chair/e_chair/proc/shock(mob/living/user)
- if(isliving(user) && (user.incapacitated() || user.restrained()))
+ if(isliving(user) && (user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)))
return
// special power handling
diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm
index a1c78dc4a8c..e7044cc4702 100644
--- a/code/game/objects/structures/extinguisher.dm
+++ b/code/game/objects/structures/extinguisher.dm
@@ -36,12 +36,12 @@
. += "Alt-click to [opened ? "close":"open"] it."
/obj/structure/extinguisher_cabinet/AltClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, "You can't do that right now!")
+ if(!iscarbon(usr) && !isrobot(usr))
return
if(!in_range(src, user))
return
- if(!iscarbon(usr) && !isrobot(usr))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, "You can't do that right now!")
return
playsound(loc, 'sound/machines/click.ogg', 15, TRUE, -3)
opened = !opened
diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm
index 2c110abd1e2..93fd3d1b5ae 100644
--- a/code/game/objects/structures/inflatable.dm
+++ b/code/game/objects/structures/inflatable.dm
@@ -47,10 +47,10 @@
add_fingerprint(user)
/obj/structure/inflatable/AltClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, "You can't do that right now!")
+ if(!istype(user) || !Adjacent(user))
return
- if(!Adjacent(user))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, "You can't do that right now!")
return
deconstruct(TRUE)
@@ -77,7 +77,7 @@
set category = "Object"
set src in oview(1)
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
deconstruct(TRUE)
diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm
index c2249944590..382df8028ef 100644
--- a/code/game/objects/structures/morgue.dm
+++ b/code/game/objects/structures/morgue.dm
@@ -189,7 +189,7 @@
/obj/structure/morgue/relaymove(mob/user)
- if(user.incapacitated())
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
tray_toggle(user)
@@ -212,7 +212,7 @@
/obj/structure/morgue/container_resist(mob/living/carbon/user)
- if(!iscarbon(user) || user.incapacitated())
+ if(!iscarbon(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
to_chat(user, span_alert("You attempt to slide yourself out of [src]..."))
@@ -291,13 +291,13 @@
/obj/structure/m_tray/MouseDrop_T(atom/movable/dropping, mob/living/user, params)
- if((!(istype(dropping)) || dropping.anchored || get_dist(user, src) > 1 || get_dist(user, dropping) > 1 || user.contents.Find(src) || user.contents.Find(dropping)))
+ if((!istype(dropping) || dropping.anchored || get_dist(user, src) > 1 || get_dist(user, dropping) > 1 || user.contents.Find(src) || user.contents.Find(dropping)))
return
if(!ismob(dropping) && !istype(dropping, /obj/structure/closet/body_bag))
return
- if(!ismob(user) || user.incapacitated())
+ if(!ismob(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(isliving(dropping))
@@ -508,13 +508,13 @@ GLOBAL_LIST_EMPTY(crematoriums)
/obj/machinery/crematorium/relaymove(mob/user)
- if(user.incapacitated() || cremating)
+ if(cremating || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
tray_toggle(user)
/obj/machinery/crematorium/container_resist(mob/living/carbon/user)
- if(!iscarbon(user) || user.incapacitated() || cremating)
+ if(cremating || !iscarbon(user) || user.incapacitated(ignore_lying = TRUE) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
to_chat(user, span_alert("You attempt to slide yourself out of [src]..."))
tray_toggle(user)
@@ -534,7 +534,7 @@ GLOBAL_LIST_EMPTY(crematoriums)
/obj/machinery/crematorium/proc/try_cremate(mob/user)
- if(user.incapacitated())
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(stat & NOPOWER)
@@ -707,13 +707,13 @@ GLOBAL_LIST_EMPTY(crematoriums)
/obj/structure/c_tray/MouseDrop_T(atom/movable/dropping, mob/living/user, params)
- if((!istype(dropping) || dropping.anchored || get_dist(user, src) > 1 || get_dist(user, dropping) > 1 || user.contents.Find(src) || user.contents.Find(dropping)))
+ if(!istype(dropping) || dropping.anchored || get_dist(user, src) > 1 || get_dist(user, dropping) > 1 || user.contents.Find(src) || user.contents.Find(dropping))
return
if(!ismob(dropping) && !istype(dropping, /obj/structure/closet/body_bag))
return
- if(!ismob(user) || user.incapacitated())
+ if(!ismob(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(isliving(dropping))
diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm
index 5829cbfc8a9..6279c7b4c97 100644
--- a/code/game/objects/structures/noticeboard.dm
+++ b/code/game/objects/structures/noticeboard.dm
@@ -69,7 +69,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.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED)) //For when a player is handcuffed while they have the notice window open
return
var/obj/item/paper/paper = locateUID(href_list["remove"])
if(istype(paper) && paper.loc == src)
@@ -80,7 +80,7 @@
update_icon(UPDATE_OVERLAYS)
if(href_list["write"])
- if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED)) //For when a player is handcuffed while they have the notice window open
return
var/obj/item/paper/paper = locateUID(href_list["write"])
if(istype(paper) && paper.loc == src) //ifthe paper's on the board
diff --git a/code/game/objects/structures/pit.dm b/code/game/objects/structures/pit.dm
index 17f68e28d69..9e70fd6e189 100644
--- a/code/game/objects/structures/pit.dm
+++ b/code/game/objects/structures/pit.dm
@@ -122,7 +122,7 @@
if(open)
return
- if(escapee.stat || escapee.restrained())
+ if(escapee.incapacitated() || HAS_TRAIT(escapee, TRAIT_HANDS_BLOCKED))
return
escapee.changeNext_click(CLICK_CD_CLICK_ABILITY)
diff --git a/code/game/objects/structures/railings.dm b/code/game/objects/structures/railings.dm
index 93a708dfee8..b2d91eafcea 100644
--- a/code/game/objects/structures/railings.dm
+++ b/code/game/objects/structures/railings.dm
@@ -127,11 +127,11 @@
add_fingerprint(user)
/obj/structure/railing/AltClick(mob/user)
- if(user.incapacitated())
- to_chat(user, "You can't do that right now!")
- return
if(!Adjacent(user))
return
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, "You can't do that right now!")
+ return
if(can_be_rotated(user))
setDir(turn(dir, 45))
@@ -176,6 +176,9 @@
/obj/structure/railing/wooden/AltClick(mob/user)
if(!Adjacent(user))
return
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, "You can't do that right now!")
+ return
if(anchored)
to_chat(user, "It is fastened to the floor!")
return
diff --git a/code/game/objects/structures/reflector.dm b/code/game/objects/structures/reflector.dm
index e753ba14e3d..3d8973b6b29 100644
--- a/code/game/objects/structures/reflector.dm
+++ b/code/game/objects/structures/reflector.dm
@@ -109,23 +109,20 @@
set category = "Object"
set src in oview(1)
- if(usr.incapacitated())
- return
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ to_chat(usr, "You can't do that right now!")
+ return FALSE
if(anchored)
to_chat(usr, "It is fastened to the floor!")
- return 0
+ return FALSE
dir = turn(dir, 270)
- return 1
+ return TRUE
/obj/structure/reflector/AltClick(mob/user)
- if(user.incapacitated())
- to_chat(user, "You can't do that right now!")
- return
- if(!in_range(src, user))
+ if(!Adjacent(user))
return
- else
- rotate()
+ rotate()
//TYPES OF REFLECTORS, SINGLE, DOUBLE, BOX
diff --git a/code/game/objects/structures/snow.dm b/code/game/objects/structures/snow.dm
index b61af8f21c9..a9336c48d6f 100644
--- a/code/game/objects/structures/snow.dm
+++ b/code/game/objects/structures/snow.dm
@@ -17,7 +17,7 @@
. = ..()
if(cooldown > world.time)
return
- if(ishuman(user) && Adjacent(user))
+ if(ishuman(user) && Adjacent(user) && !user.incapacitated() && !HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
var/mob/living/carbon/human/H = user
var/obj/item/snowball/S = new(drop_location())
cooldown = world.time + 3 SECONDS
diff --git a/code/game/objects/structures/spirit_board.dm b/code/game/objects/structures/spirit_board.dm
index 3d5a5c908d5..2fc720a6df8 100644
--- a/code/game/objects/structures/spirit_board.dm
+++ b/code/game/objects/structures/spirit_board.dm
@@ -68,7 +68,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.incapacitated() || 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/stairs.dm b/code/game/objects/structures/stairs.dm
index 5f7c765000b..6a32ed542ec 100644
--- a/code/game/objects/structures/stairs.dm
+++ b/code/game/objects/structures/stairs.dm
@@ -145,12 +145,15 @@
/obj/structure/stairs_frame/AltClick(mob/user)
if(!Adjacent(user))
return
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, "You can't do that right now!")
+ return
if(anchored)
to_chat(user, "It is fastened to the floor!")
return
add_fingerprint(usr)
setDir(turn(dir, 90))
- return
+
/obj/structure/stairs_frame/examine(mob/living/carbon/human/user)
. = ..()
diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm
index 4da36cda7a2..7b047fc4128 100644
--- a/code/game/objects/structures/statues.dm
+++ b/code/game/objects/structures/statues.dm
@@ -269,11 +269,11 @@
icon_state = "mime"
/obj/structure/statue/tranquillite/mime/AltClick(mob/user)//has 4 dirs
- if(user.incapacitated())
- to_chat(user, "You can't do that right now!")
- return
if(!Adjacent(user))
return
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, "You can't do that right now!")
+ return
if(anchored)
to_chat(user, "It is fastened to the floor!")
return
diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm
index 4c2cfe4dcda..bcf40174ee8 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm
@@ -93,6 +93,7 @@
/obj/structure/bed/nest/post_buckle_mob(mob/living/target)
+ ADD_TRAIT(target, TRAIT_HANDS_BLOCKED, type)
target.pixel_y = 0
target.pixel_x = initial(target.pixel_x) + 2
target.layer = BELOW_MOB_LAYER
@@ -100,6 +101,7 @@
/obj/structure/bed/nest/post_unbuckle_mob(mob/living/target)
+ REMOVE_TRAIT(target, TRAIT_HANDS_BLOCKED, type)
target.pixel_x = target.get_standard_pixel_x_offset(target.lying_angle)
target.pixel_y = target.get_standard_pixel_y_offset(target.lying_angle)
target.layer = initial(target.layer)
diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
index e656875699a..f449462bd7b 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
@@ -154,7 +154,7 @@
/obj/structure/bed/roller/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
- if(!has_buckled_mobs() && over_object == usr && ishuman(usr) && !usr.incapacitated() && usr.Adjacent(src))
+ if(!has_buckled_mobs() && over_object == usr && ishuman(usr) && !usr.incapacitated() && !HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) && usr.Adjacent(src))
usr.visible_message(
span_notice("[usr] collapses [src]."),
span_notice("You collapse [src]."),
diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
index a1fbf707096..511cef1f25a 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
@@ -67,7 +67,7 @@
/obj/structure/chair/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
if(over_object == usr && ishuman(usr) && item_chair && !anchored && !has_buckled_mobs() && usr.Adjacent(src))
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
to_chat(usr, span_warning("You can't do that right now!"))
return
if(!usr.has_right_hand() && !usr.has_left_hand())
@@ -133,7 +133,7 @@
if(isobserver(user))
if(!CONFIG_GET(flag/ghost_interaction))
return FALSE
- else if(!isliving(user) || user.incapacitated() || !Adjacent(user))
+ else if(!isliving(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user))
return FALSE
setDir(turn(dir, 90))
@@ -528,10 +528,10 @@
return
/obj/structure/chair/brass/AltClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, span_warning("You can't do that right now!"))
+ if(!istype(user) || !Adjacent(user))
return
- if(!in_range(src, user))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, span_warning("You can't do that right now!"))
return
add_fingerprint(user)
turns = 0
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index 935ad6d245f..4cb662841a8 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -203,7 +203,7 @@
return TRUE
if(!isitem(dropping) || user.get_active_hand() != dropping)
return FALSE
- if(isrobot(user))
+ if(isrobot(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return FALSE
if(!user.drop_item_ground(dropping))
return FALSE
@@ -797,7 +797,7 @@
. = FALSE
if((!isitem(dropping)) || user.get_active_hand() != dropping)
return .
- if(isrobot(user))
+ if(isrobot(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return .
if(dropping.loc != loc && user.transfer_item_to_loc(dropping, src.loc))
add_fingerprint(user)
@@ -862,7 +862,7 @@
/obj/structure/rack/gunrack/proc/place_gun(obj/item/gun/our_gun, mob/user, params)
. = FALSE
- if(!ishuman(user))
+ if(!ishuman(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return .
if(!(istype(our_gun)))
to_chat(user, span_warning("This item doesn't fit!"))
diff --git a/code/game/objects/structures/tribune.dm b/code/game/objects/structures/tribune.dm
index 3a6ade4f9b0..3e56b27c3b2 100644
--- a/code/game/objects/structures/tribune.dm
+++ b/code/game/objects/structures/tribune.dm
@@ -56,6 +56,9 @@
/obj/structure/tribune/AltClick(mob/user)
if(!Adjacent(user))
return
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, "You can't do that right now!")
+ return
if(anchored)
to_chat(user, "It is fastened to the floor!")
return
diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm
index e6cae489a20..33e0fb81e1a 100644
--- a/code/game/objects/structures/windoor_assembly.dm
+++ b/code/game/objects/structures/windoor_assembly.dm
@@ -301,7 +301,8 @@
set name = "Rotate Windoor Assembly"
set category = "Object"
set src in oview(1)
- if(usr.stat || !usr.canmove || usr.restrained())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ to_chat(usr, "You can't do that right now!")
return
if(anchored)
to_chat(usr, "[src] cannot be rotated while it is fastened to the floor!")
@@ -319,20 +320,16 @@
return TRUE
/obj/structure/windoor_assembly/AltClick(mob/user)
- if(user.incapacitated())
- to_chat(user, "You can't do that right now!")
+ if(!Adjacent(user))
return
- if(!in_range(src, user))
- return
- else
- revrotate()
+ revrotate()
//Flips the windoor assembly, determines whather the door opens to the left or the right
/obj/structure/windoor_assembly/verb/flip()
set name = "Flip Windoor Assembly"
set category = "Object"
set src in oview(1)
- if(usr.stat || !usr.canmove || usr.restrained())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(facing == "l")
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 5c35e8ebce9..8b1f0aa6f6b 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -398,7 +398,7 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e",
set category = "Object"
set src in oview(1)
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(anchored)
@@ -421,7 +421,7 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e",
set category = "Object"
set src in oview(1)
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(anchored)
@@ -441,14 +441,14 @@ GLOBAL_LIST_INIT(wcCommon, pick(list("#379963", "#0d8395", "#58b5c3", "#49e46e",
/obj/structure/window/AltClick(mob/user)
- if(user.incapacitated())
- to_chat(user, "You can't do that right now!")
- return
-
if(!Adjacent(user))
to_chat(user, "Move closer to the window!")
return
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, "You can't do that right now!")
+ return
+
if(anchored)
to_chat(user, "[src] cannot be rotated while it is fastened to the floor!")
return FALSE
diff --git a/code/game/verbs/suicide.dm b/code/game/verbs/suicide.dm
index c254850c5a2..3c925a30f94 100644
--- a/code/game/verbs/suicide.dm
+++ b/code/game/verbs/suicide.dm
@@ -70,11 +70,6 @@
updatehealth()
-/mob/living/simple_animal/mouse/do_suicide()
- visible_message(span_danger("[src] is playing dead permanently! It looks like [p_theyre()] trying to commit suicide."))
- adjustOxyLoss(max(100 - getBruteLoss(100), 0))
-
-
/mob/living/silicon/do_suicide()
to_chat(viewers(src), span_danger("[src] is powering down. It looks like [p_theyre()] trying to commit suicide."))
//put em at -175
diff --git a/code/modules/antagonists/changeling/powers/biodegrade.dm b/code/modules/antagonists/changeling/powers/biodegrade.dm
index 77008feb4bd..304e5765adb 100644
--- a/code/modules/antagonists/changeling/powers/biodegrade.dm
+++ b/code/modules/antagonists/changeling/powers/biodegrade.dm
@@ -12,7 +12,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 && !istype(user.loc, /obj/structure/closet) && !istype(user.loc, /obj/structure/spider/cocoon))
+ if(!HAS_TRAIT(user, TRAIT_RESTRAINED) && !istype(user.loc, /obj/structure/closet) && !istype(user.loc, /obj/structure/spider/cocoon) && !LAZYLEN(user.grabbed_by))
to_chat(user, span_warning("We are already free!"))
return FALSE
diff --git a/code/modules/antagonists/space_ninja/machinery/ninja_mindscan_machine.dm b/code/modules/antagonists/space_ninja/machinery/ninja_mindscan_machine.dm
index 00f38613cb1..b1a8597c642 100644
--- a/code/modules/antagonists/space_ninja/machinery/ninja_mindscan_machine.dm
+++ b/code/modules/antagonists/space_ninja/machinery/ninja_mindscan_machine.dm
@@ -73,7 +73,7 @@
return
if(dropped.loc == user) //no you can't pull things out of your ass
return
- if(user.incapacitated()) //are you cuffed, dying, lying, stunned or other
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //are you cuffed, dying, lying, stunned or other
return
if(get_dist(user, src) > 1 || get_dist(user, dropped) > 1 || user.contents.Find(src)) // is the mob anchored, too far away from you, or are you too far away from the source
return
diff --git a/code/modules/antagonists/space_ninja/suit/ninja_equipment_actions/ninja_spirit_form.dm b/code/modules/antagonists/space_ninja/suit/ninja_equipment_actions/ninja_spirit_form.dm
index 9beea7d7f8f..42dc647f144 100644
--- a/code/modules/antagonists/space_ninja/suit/ninja_equipment_actions/ninja_spirit_form.dm
+++ b/code/modules/antagonists/space_ninja/suit/ninja_equipment_actions/ninja_spirit_form.dm
@@ -86,11 +86,10 @@
if(ninja.handcuffed)
restraint = ninja.get_item_by_slot(ITEM_SLOT_HANDCUFFED)
restraint.visible_message("[restraint] falls from the [ninja] when he becomes unstable!")
- ninja.uncuff()
if(ninja.legcuffed)
restraint = ninja.get_item_by_slot(ITEM_SLOT_LEGCUFFED)
restraint.visible_message("[restraint] falls from the [ninja] when he becomes unstable!")
- ninja.uncuff()
+ ninja.uncuff()
if(istype(ninja.loc, /obj/structure/closet))
var/obj/structure/closet/restraint_closet = ninja.loc
if(!istype(restraint_closet))
diff --git a/code/modules/antagonists/thief/thief_kit.dm b/code/modules/antagonists/thief/thief_kit.dm
index 0a9f6f49b89..ffdc21f448d 100644
--- a/code/modules/antagonists/thief/thief_kit.dm
+++ b/code/modules/antagonists/thief/thief_kit.dm
@@ -88,10 +88,10 @@
/obj/item/thief_kit/interact(mob/user)
if(!ishuman(user))
to_chat(user, "Вы даже не гуманоид... Вы не понимаете как это открыть")
- return 0
+ return FALSE
- if(user.stat || user.restrained())
- return 0
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ return FALSE
if(loc == user || (in_range(src, user) && isturf(loc)))
ui_interact(user)
diff --git a/code/modules/antagonists/traitor/contractor/items/contractor_baton.dm b/code/modules/antagonists/traitor/contractor/items/contractor_baton.dm
index 54a0792e253..09407e4e9eb 100644
--- a/code/modules/antagonists/traitor/contractor/items/contractor_baton.dm
+++ b/code/modules/antagonists/traitor/contractor/items/contractor_baton.dm
@@ -162,7 +162,7 @@
"[user] is trying to put handcuffs on you!")
if(do_after(user, 1 SECONDS, target, NONE))
if(!target.handcuffed)
- target.set_handcuffed(new /obj/item/restraints/handcuffs/cable(target))
+ target.apply_restraints(new /obj/item/restraints/handcuffs/cable(null), ITEM_SLOT_HANDCUFFED, TRUE)
to_chat(user, "You shackle [target].")
add_attack_logs(user, target, "shackled")
cuffs--
diff --git a/code/modules/assembly/health.dm b/code/modules/assembly/health.dm
index d3ead86b0b4..283ff3cf974 100644
--- a/code/modules/assembly/health.dm
+++ b/code/modules/assembly/health.dm
@@ -94,7 +94,7 @@
var/mob/living/user = usr
- if(user.incapacitated() || user.restrained() || !in_range(loc, user))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !in_range(loc, user))
user << browse(null, "window=hscan")
onclose(user, "hscan")
return
diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm
index 0283b3e9892..aa14fb9171f 100644
--- a/code/modules/assembly/infrared.dm
+++ b/code/modules/assembly/infrared.dm
@@ -169,7 +169,7 @@
/obj/item/assembly/infra/Topic(href, href_list)
..()
- if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || !in_range(loc, usr))
usr << browse(null, "window=infra")
onclose(usr, "infra")
return
@@ -204,7 +204,7 @@
/obj/item/assembly/infra/proc/rotate(mob/living/user = usr)
- if(!isliving(user) || user.incapacitated() || user.restrained())
+ if(!isliving(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
dir = turn(dir, 90)
diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm
index 01a1b6734a6..d0d885c2df5 100644
--- a/code/modules/assembly/mousetrap.dm
+++ b/code/modules/assembly/mousetrap.dm
@@ -164,7 +164,7 @@
/obj/item/assembly/mousetrap/proc/hide_under(mob/user = usr)
- if(!isliving(user) || user.incapacitated() || user.restrained())
+ if(!isliving(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
layer = TURF_LAYER + 0.2
diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm
index a7488113dc8..0aa93c57feb 100644
--- a/code/modules/assembly/proximity.dm
+++ b/code/modules/assembly/proximity.dm
@@ -127,7 +127,7 @@
/obj/item/assembly/prox_sensor/Topic(href, href_list)
..()
- if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || !in_range(loc, usr))
usr << browse(null, "window=prox")
onclose(usr, "prox")
return
diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm
index 9d0f1b830e4..e2d30aedacf 100644
--- a/code/modules/assembly/signaler.dm
+++ b/code/modules/assembly/signaler.dm
@@ -39,7 +39,7 @@
/obj/item/assembly/signaler/AltClick(mob/user)
- if(!isliving(user) || user.incapacitated() || user.restrained() || !Adjacent(user))
+ if(!isliving(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user))
return ..()
to_chat(user, span_notice("You activate [src]."))
activate()
@@ -96,7 +96,7 @@
/obj/item/assembly/signaler/Topic(href, href_list)
..()
- if(usr.incapacitated() || usr.restrained() || !Adjacent(usr))
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || !Adjacent(usr))
usr << browse(null, "window=radio")
onclose(usr, "radio")
return
diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm
index 6084f4cd5ec..e27a23bf556 100644
--- a/code/modules/assembly/timer.dm
+++ b/code/modules/assembly/timer.dm
@@ -107,7 +107,7 @@
/obj/item/assembly/timer/Topic(href, href_list)
..()
- if(usr.incapacitated() || usr.restrained() || !Adjacent(usr))
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || !Adjacent(usr))
usr << browse(null, "window=timer")
onclose(usr, "timer")
return
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
index df18355640f..cec0f01dc3e 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
@@ -27,29 +27,32 @@ Thus, the two variables affect pump operation are set in New():
var/id = null
/obj/machinery/atmospherics/binary/pump/CtrlClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, span_warning("You can't do that right now!"))
+ if(!ishuman(user) && !issilicon(user))
return
- if(!in_range(src, user) && !issilicon(usr))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, span_warning("You can't do that right now!"))
return
- if(!ishuman(usr) && !issilicon(usr))
+ if(!in_range(src, user) && !issilicon(user))
return
toggle()
+
/obj/machinery/atmospherics/binary/pump/AICtrlClick()
toggle()
return ..()
+
/obj/machinery/atmospherics/binary/pump/AltClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, span_warning("You can't do that right now!"))
+ if(!ishuman(user) && !issilicon(user))
return
- if(!in_range(src, user) && !issilicon(usr))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, span_warning("You can't do that right now!"))
return
- if(!ishuman(usr) && !issilicon(usr))
+ if(!in_range(src, user) && !issilicon(user))
return
set_max()
+
/obj/machinery/atmospherics/binary/pump/AIAltClick()
set_max()
return ..()
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
index 8a445e62810..4d7c7d5b2b2 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
@@ -27,12 +27,12 @@ Thus, the two variables affect pump operation are set in New():
var/id = null
/obj/machinery/atmospherics/binary/volume_pump/CtrlClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, span_warning("You can't do that right now!"))
+ if(!ishuman(user) && !issilicon(user))
return
- if(!in_range(src, user) && !issilicon(usr))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, span_warning("You can't do that right now!"))
return
- if(!ishuman(usr) && !issilicon(usr))
+ if(!in_range(src, user) && !issilicon(user))
return
toggle()
@@ -41,12 +41,12 @@ Thus, the two variables affect pump operation are set in New():
return ..()
/obj/machinery/atmospherics/binary/volume_pump/AltClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, span_warning("You can't do that right now!"))
+ if(!ishuman(user) && !issilicon(user))
return
- if(!in_range(src, user) && !issilicon(usr))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, span_warning("You can't do that right now!"))
return
- if(!ishuman(usr) && !issilicon(usr))
+ if(!in_range(src, user) && !issilicon(user))
return
set_max()
diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
index 98d1b72d542..7af72b7a6db 100644
--- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
+++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
@@ -32,12 +32,12 @@
)
/obj/machinery/atmospherics/trinary/filter/CtrlClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, span_warning("You can't do that right now!"))
+ if(!ishuman(user) && !issilicon(user))
return
- if(!in_range(src, user) && !issilicon(usr))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, span_warning("You can't do that right now!"))
return
- if(!ishuman(usr) && !issilicon(usr))
+ if(!in_range(src, user) && !issilicon(user))
return
toggle()
@@ -46,12 +46,12 @@
return ..()
/obj/machinery/atmospherics/trinary/filter/AltClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, span_warning("You can't do that right now!"))
+ if(!ishuman(usr) && !issilicon(usr))
return
- if(!in_range(src, user) && !issilicon(usr))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, span_warning("You can't do that right now!"))
return
- if(!ishuman(usr) && !issilicon(usr))
+ if(!in_range(src, user) && !issilicon(user))
return
set_max()
diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
index 1cf9cabeb4b..f112fdc536e 100644
--- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
+++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
@@ -13,12 +13,12 @@
//node 3 is the outlet, nodes 1 & 2 are intakes
/obj/machinery/atmospherics/trinary/mixer/CtrlClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, span_warning("You can't do that right now!"))
+ if(!ishuman(user) && !issilicon(user))
return
- if(!in_range(src, user) && !issilicon(usr))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, span_warning("You can't do that right now!"))
return
- if(!ishuman(usr) && !issilicon(usr))
+ if(!in_range(src, user) && !issilicon(user))
return
toggle()
@@ -27,12 +27,12 @@
return ..()
/obj/machinery/atmospherics/trinary/mixer/AltClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, span_warning("You can't do that right now!"))
+ if(!ishuman(user) && !issilicon(user))
return
- if(!in_range(src, user) && !issilicon(usr))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, span_warning("You can't do that right now!"))
return
- if(!ishuman(usr) && !issilicon(usr))
+ if(!in_range(src, user) && !issilicon(user))
return
set_max()
diff --git a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm
index e0316a5a52e..56648303a63 100644
--- a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm
+++ b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm
@@ -92,12 +92,12 @@
return air_contents
/obj/machinery/portable_atmospherics/AltClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, span_warning("You can't do that right now!"))
+ if(!ishuman(user) && !issilicon(user))
return
- if(!in_range(src, user))
+ if(!Adjacent(user))
return
- if(!ishuman(usr) && !issilicon(usr))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, span_warning("You can't do that right now!"))
return
if(holding)
to_chat(user, span_notice("You remove [holding] from [src]."))
diff --git a/code/modules/awaymissions/mission_code/ruins/USSP_gorky17.dm b/code/modules/awaymissions/mission_code/ruins/USSP_gorky17.dm
index 364c18fe8aa..be6013e9b7e 100644
--- a/code/modules/awaymissions/mission_code/ruins/USSP_gorky17.dm
+++ b/code/modules/awaymissions/mission_code/ruins/USSP_gorky17.dm
@@ -310,9 +310,7 @@
set name = "Enter name"
set category = "Object"
set src in oview(1)
- if(usr.incapacitated())
- return
- if(!ishuman(usr))
+ if(!ishuman(usr) || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
var/temp_name = reject_bad_name(input("Enter cardholder name:", "Cardholder name", usr.name), TRUE)
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index 7b37753c5b1..f974659b7e6 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -98,7 +98,7 @@
/obj/item/clothing/proc/can_use(mob/user)
- if(isliving(user) && !user.incapacitated())
+ if(isliving(user) && !user.incapacitated() && !HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return TRUE
return FALSE
@@ -262,7 +262,7 @@ BLIND // can't see anything
var/mob/living/carbon/human/user = usr
if(!istype(user))
return
- if(user.incapacitated()) //Dead spessmen adjust no glasses. Resting/buckled ones do, though
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //Dead spessmen adjust no glasses. Resting/buckled ones do, though
return
var/action_fluff = "You adjust \the [src]"
@@ -327,7 +327,7 @@ BLIND // can't see anything
/obj/item/clothing/under/proc/set_sensors(mob/living/user)
- if(user.stat || user.restrained())
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
for(var/obj/item/grab/grabbed in user.grabbed_by)
if(grabbed.state >= GRAB_NECK)
@@ -628,7 +628,7 @@ BLIND // can't see anything
return
icon_state = "[icon_state]_opentoe"
item_state = "[item_state]_opentoe"
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
//Suit
@@ -974,7 +974,7 @@ BLIND // can't see anything
return TRUE
else
- to_chat(user, "You cannot attach more accessories of this type to [src].")
+ to_chat(user, span_notice("You cannot attach more accessories of this type to [src]."))
return FALSE
@@ -983,28 +983,29 @@ BLIND // can't see anything
if(has_sensor)
switch(sensor_mode)
if(0)
- . += "Its sensors appear to be disabled."
+ . += span_notice("Its sensors appear to be disabled.")
if(1)
- . += "Its binary life sensors appear to be enabled."
+ . += span_notice("Its binary life sensors appear to be enabled.")
if(2)
- . += "Its vital tracker appears to be enabled."
+ . += span_notice("Its vital tracker appears to be enabled.")
if(3)
- . += "Its vital tracker and tracking beacon appear to be enabled."
+ . += span_notice("Its vital tracker and tracking beacon appear to be enabled.")
if(accessories.len)
for(var/obj/item/clothing/accessory/A in accessories)
. += A.attached_examine()
+
/obj/item/clothing/under/verb/rollsuit()
set name = "Roll Down Jumpsuit"
set category = "Object"
set src in usr
+
if(!ishuman(usr))
return
+
var/mob/living/carbon/human/owner = usr
- if(owner.stat != CONSCIOUS)
- return
- if(!owner.incapacitated())
+ if(!owner.incapacitated() && !HAS_TRAIT(owner, TRAIT_HANDS_BLOCKED))
if(copytext(item_color,-2) != "_d")
basecolor = item_color
var/icon/file = onmob_sheets[ITEM_SLOT_CLOTH_INNER_STRING]
@@ -1014,45 +1015,43 @@ BLIND // can't see anything
item_color = item_color == "[basecolor]" ? "[basecolor]_d" : "[basecolor]"
owner.update_inv_w_uniform()
else
- to_chat(owner, "You cannot roll down this uniform!")
+ to_chat(owner, span_notice("You cannot roll down this uniform!"))
else
- to_chat(owner, "You cannot roll down the uniform!")
+ to_chat(owner, span_notice("You cannot roll down the uniform right now!"))
+
/obj/item/clothing/under/verb/removetie()
set name = "Remove Accessory"
set category = "Object"
set src in usr
- handle_accessories_removal()
+ handle_accessories_removal(usr)
-/obj/item/clothing/under/proc/handle_accessories_removal()
- if(!isliving(usr))
- return
- if(usr.incapacitated())
+
+/obj/item/clothing/under/proc/handle_accessories_removal(mob/user)
+ if(!isliving(user))
return
- if(!Adjacent(usr))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(!accessories.len)
return
- var/obj/item/clothing/accessory/A
+ var/obj/item/clothing/accessory/accessory
if(accessories.len > 1)
- A = input("Select an accessory to remove from [src]") as null|anything in accessories
+ accessory = input("Select an accessory to remove from [src]") as null|anything in accessories
else
- A = accessories[1]
- remove_accessory(usr,A)
-
-/obj/item/clothing/under/proc/remove_accessory(mob/user, obj/item/clothing/accessory/A)
- if(!(A in accessories))
- return
- if(!isliving(user))
- return
- if(user.incapacitated())
+ accessory = accessories[1]
+ if(!accessory || !Adjacent(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
- if(!Adjacent(user))
+ remove_accessory(user, accessory)
+
+
+/obj/item/clothing/under/proc/remove_accessory(mob/user, obj/item/clothing/accessory/accessory)
+ if(!(accessory in accessories))
return
- A.on_removed(user)
- accessories -= A
- to_chat(user, "You remove [A] from [src].")
- usr.update_inv_w_uniform()
+ accessory.on_removed(user)
+ accessories -= accessory
+ to_chat(user, span_notice("You remove [accessory] from [src]."))
+ user.update_inv_w_uniform()
+
/obj/item/clothing/under/emp_act(severity)
if(accessories.len)
@@ -1060,8 +1059,9 @@ BLIND // can't see anything
A.emp_act(severity)
..()
-/obj/item/clothing/under/AltClick()
- handle_accessories_removal()
+/obj/item/clothing/under/AltClick(mob/user)
+ if(Adjacent(user))
+ handle_accessories_removal(user)
/obj/item/clothing/obj_destruction(damage_flag)
if(damage_flag == "bomb" || damage_flag == "melee")
diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm
index 493ec9a23be..8194d8bddc3 100644
--- a/code/modules/clothing/head/hardhat.dm
+++ b/code/modules/clothing/head/hardhat.dm
@@ -39,7 +39,7 @@
/obj/item/clothing/head/hardhat/update_icon_state()
icon_state = "hardhat[on]_[item_color]"
item_state = "hardhat[on]_[item_color]"
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
/obj/item/clothing/head/hardhat/proc/turn_on()
diff --git a/code/modules/clothing/head/soft_caps.dm b/code/modules/clothing/head/soft_caps.dm
index ae2b4cbe4f5..471646983f9 100644
--- a/code/modules/clothing/head/soft_caps.dm
+++ b/code/modules/clothing/head/soft_caps.dm
@@ -20,7 +20,7 @@
/obj/item/clothing/head/soft/update_icon_state()
icon_state = flipped ? "[item_color]soft_flipped" : "[item_color]soft"
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
/obj/item/clothing/head/soft/dropped(mob/user, slot, silent = FALSE)
diff --git a/code/modules/clothing/masks/breath.dm b/code/modules/clothing/masks/breath.dm
index e6dd0344aa8..60740bcd960 100644
--- a/code/modules/clothing/masks/breath.dm
+++ b/code/modules/clothing/masks/breath.dm
@@ -34,10 +34,10 @@
adjustmask(user)
/obj/item/clothing/mask/breath/AltClick(mob/living/user)
- if(!istype(user) || user.incapacitated() || user.restrained())
- to_chat(user, "You can't do that right now!")
+ if(!istype(user) || !Adjacent(user))
return
- if(!in_range(src, user))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, "You can't do that right now!")
return
adjustmask(user)
diff --git a/code/modules/clothing/neck/ponchos.dm b/code/modules/clothing/neck/ponchos.dm
index faa4b6a5342..2f01c9f1308 100644
--- a/code/modules/clothing/neck/ponchos.dm
+++ b/code/modules/clothing/neck/ponchos.dm
@@ -28,26 +28,21 @@
/obj/item/clothing/neck/poncho/update_icon_state()
icon_state = "[item_color]poncho[flipped ? "_flip" : ""]"
+
/obj/item/clothing/neck/poncho/AltClick(mob/living/carbon/human/user)
- if(!iscarbon(user))
- ..()
- else if(user.neck != src)
- ..()
- else
- flip(user)
+ if(!(src in user))
+ return ..()
+ flip(user)
+
/obj/item/clothing/neck/poncho/verb/flip_poncho()
set name = "Flip poncho"
set category = "Object"
set desc = "Flip poncho behind your back"
+ set src in usr
+
+ flip(usr)
- if(!iscarbon(usr))
- return
- var/mob/living/carbon/human/user = usr
- if(user.neck != src)
- to_chat(user, span_warning("Poncho must be equipped before flipping!"))
- return
- flip(user)
/obj/item/clothing/neck/poncho/dropped(mob/user, slot, silent = FALSE)
. = ..()
@@ -63,10 +58,15 @@
flipped = FALSE
update_icon(UPDATE_ICON_STATE)
-/obj/item/clothing/neck/poncho/proc/flip(mob/user)
- if(user.incapacitated())
+/obj/item/clothing/neck/poncho/proc/flip(mob/living/carbon/human/user)
+ if(!ishuman(user))
+ return
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
to_chat(user, span_warning("You can't do that right now!"))
return
+ if(user.neck != src)
+ to_chat(user, span_warning("Poncho must be equipped before flipping!"))
+ return
flipped = !flipped
update_icon(UPDATE_ICON_STATE)
if(flipped)
diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm
index 2ac00c9c7af..53590979cd7 100644
--- a/code/modules/clothing/shoes/magboots.dm
+++ b/code/modules/clothing/shoes/magboots.dm
@@ -130,7 +130,7 @@
user.RemoveElement(/datum/element/waddling)
/obj/item/clothing/shoes/magboots/clown/CtrlClick(mob/living/user)
- if(!isliving(user))
+ if(!isliving(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(user.get_active_hand() != src)
to_chat(user, "You must hold [src] in your hand to do this.")
diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm
index 3888c7be7e3..9b599ce3128 100644
--- a/code/modules/clothing/shoes/miscellaneous.dm
+++ b/code/modules/clothing/shoes/miscellaneous.dm
@@ -92,7 +92,7 @@
user.RemoveElement(/datum/element/waddling)
/obj/item/clothing/shoes/clown_shoes/CtrlClick(mob/living/user)
- if(!isliving(user))
+ if(!isliving(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(user.get_active_hand() != src)
to_chat(user, "You must hold [src] in your hand to do this.")
@@ -543,7 +543,7 @@
user.RemoveElement(/datum/element/waddling)
/obj/item/clothing/shoes/bhop/clown/CtrlClick(mob/living/user)
- if(!isliving(user))
+ if(!isliving(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(user.get_active_hand() != src)
to_chat(user, "You must hold [src] in your hand to do this.")
diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm
index 74d3eb7caa0..0d2b987def2 100644
--- a/code/modules/clothing/spacesuits/hardsuit.dm
+++ b/code/modules/clothing/spacesuits/hardsuit.dm
@@ -88,6 +88,8 @@
/obj/item/clothing/head/helmet/space/hardsuit/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
+ if(HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ return
if(suit)
suit.RemoveHelmet(usr)
else
@@ -194,6 +196,8 @@
/obj/item/clothing/suit/space/hardsuit/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
+ if(HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ return
RemoveHelmet(usr)
. = ..()
diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm
index fc72db8a350..85967956195 100644
--- a/code/modules/clothing/spacesuits/plasmamen.dm
+++ b/code/modules/clothing/spacesuits/plasmamen.dm
@@ -38,7 +38,7 @@
/obj/item/clothing/head/helmet/space/plasmaman/AltClick(mob/user)
- if(!user.incapacitated() && Adjacent(user))
+ if(!user.incapacitated() && !HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) && Adjacent(user))
toggle_welding_screen(user)
@@ -100,13 +100,12 @@
else
set_light_on(FALSE)
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
/obj/item/clothing/head/helmet/space/plasmaman/extinguish_light(force = FALSE)
if(on)
toggle_light()
- update_equipped_item()
/obj/item/clothing/head/helmet/space/plasmaman/equipped(mob/living/carbon/human/user, slot, initial)
diff --git a/code/modules/clothing/suits/hood.dm b/code/modules/clothing/suits/hood.dm
index b4dbfa10a00..af6a870c79a 100644
--- a/code/modules/clothing/suits/hood.dm
+++ b/code/modules/clothing/suits/hood.dm
@@ -52,6 +52,8 @@
/obj/item/clothing/suit/hooded/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
+ if(HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ return
RemoveHood(usr)
. = ..()
@@ -153,6 +155,8 @@
/obj/item/clothing/head/hooded/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params)
+ if(HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ return
if(suit)
suit.RemoveHood(usr)
else
diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm
index 4bb41790ac0..e876329a56b 100644
--- a/code/modules/clothing/under/accessories/accessory.dm
+++ b/code/modules/clothing/under/accessories/accessory.dm
@@ -423,9 +423,7 @@
set name = "Holobadge"
set category = "Object"
set src in usr
- if(!isliving(usr))
- return
- if(usr.stat)
+ if(!isliving(usr) || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
var/obj/item/clothing/accessory/holobadge/holobadge_ref = null
@@ -442,8 +440,8 @@
if(!holobadge_ref.stored_name)
to_chat(usr, "Waving around a badge before swiping an ID would be pretty pointless.")
return
- if(isliving(usr))
- usr.visible_message("[usr] displays [usr.p_their()] Nanotrasen Internal Security Legal Authorization Badge.\nIt reads: [holobadge_ref.stored_name], NT Security.",
+
+ usr.visible_message("[usr] displays [usr.p_their()] Nanotrasen Internal Security Legal Authorization Badge.\nIt reads: [holobadge_ref.stored_name], NT Security.",
"You display your Nanotrasen Internal Security Legal Authorization Badge.\nIt reads: [holobadge_ref.stored_name], NT Security.")
///////////
diff --git a/code/modules/clothing/under/accessories/holster.dm b/code/modules/clothing/under/accessories/holster.dm
index 2d67ac3b884..c0d46f0141e 100644
--- a/code/modules/clothing/under/accessories/holster.dm
+++ b/code/modules/clothing/under/accessories/holster.dm
@@ -128,8 +128,9 @@
set name = "Holster"
set category = "Object"
set src in usr
- if(!isliving(usr)) return
- if(usr.stat) return
+
+ if(!isliving(usr) || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ return
var/obj/item/clothing/accessory/holster/H = null
if(istype(src, /obj/item/clothing/accessory/holster))
diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm
index 36586779303..5c39b7d81b5 100644
--- a/code/modules/customitems/item_defines.dm
+++ b/code/modules/customitems/item_defines.dm
@@ -858,8 +858,8 @@
set category = "Object"
set src in usr
- if(usr.stat || usr.restrained())
- return 0
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ return FALSE
switch(icon_state)
if("Kluysfluff1")
@@ -967,7 +967,7 @@
return
update_icon(UPDATE_ICON_STATE)
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
to_chat(user, "You turn the [src]'s lighting system [suit_adjusted ? "off" : "on"].")
suit_adjusted = !suit_adjusted
@@ -1146,8 +1146,8 @@
set category = "Object"
set src in usr
- if(usr.stat || usr.restrained())
- return 0
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ return FALSE
if(src.icon_state == "jane_sid_suit_down")
src.item_color = "jane_sid_suit"
@@ -1330,7 +1330,7 @@
/obj/item/clothing/head/fluff/chronx/proc/adjust()
update_icon(UPDATE_ICON_STATE)
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
to_chat(usr, "You untransform [src].")
adjusted = !adjusted
diff --git a/code/modules/detectivework/microscope/dnascanner.dm b/code/modules/detectivework/microscope/dnascanner.dm
index 758dd3d1818..b0f316f7e61 100644
--- a/code/modules/detectivework/microscope/dnascanner.dm
+++ b/code/modules/detectivework/microscope/dnascanner.dm
@@ -78,7 +78,7 @@
return
/obj/machinery/dnaforensics/proc/remove_sample(mob/living/remover)
- if(!istype(remover) || remover.incapacitated() || !Adjacent(remover))
+ if(!istype(remover) || remover.incapacitated() || HAS_TRAIT(remover, TRAIT_HANDS_BLOCKED) || !Adjacent(remover))
return
if(!swab)
to_chat(remover, "Внутри сканера нет образца!.")
@@ -89,8 +89,8 @@
swab = null
update_icon(UPDATE_ICON_STATE)
-/obj/machinery/dnaforensics/AltClick()
- remove_sample(usr)
+/obj/machinery/dnaforensics/AltClick(mob/user)
+ remove_sample(user)
/obj/machinery/dnaforensics/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
if(usr == over_object)
diff --git a/code/modules/detectivework/microscope/microscope.dm b/code/modules/detectivework/microscope/microscope.dm
index 46c3f6f054c..bb5fb9949d5 100644
--- a/code/modules/detectivework/microscope/microscope.dm
+++ b/code/modules/detectivework/microscope/microscope.dm
@@ -100,7 +100,7 @@
return
/obj/machinery/microscope/proc/remove_sample(mob/living/remover)
- if(!istype(remover) || remover.incapacitated() || !Adjacent(remover))
+ if(!istype(remover) || remover.incapacitated() || HAS_TRAIT(remover, TRAIT_HANDS_BLOCKED) || !Adjacent(remover))
return
if(!sample)
to_chat(remover, "Внутри микроскопа нет образца!")
@@ -114,8 +114,8 @@
/obj/machinery/microscope/proc/is_complete_print(print)
return stringpercent(print) <= fingerprint_complete
-/obj/machinery/microscope/AltClick()
- remove_sample(usr)
+/obj/machinery/microscope/AltClick(mob/user)
+ remove_sample(user)
/obj/machinery/microscope/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
if(usr == over_object)
diff --git a/code/modules/detectivework/tools/sample_kits.dm b/code/modules/detectivework/tools/sample_kits.dm
index cb11ca41eb5..5e43be7deca 100644
--- a/code/modules/detectivework/tools/sample_kits.dm
+++ b/code/modules/detectivework/tools/sample_kits.dm
@@ -148,7 +148,7 @@
to_chat(user, "You transfer [S.evidence.len] [S.evidence.len > 1 ? "[evidence_type]s" : "[evidence_type]"] to \the [S].")
/obj/item/forensics/sample_kit/afterattack(atom/A, mob/user, proximity)
- if(!proximity)
+ if(!proximity || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(can_take_sample(user, A))
take_sample(user,A)
@@ -167,7 +167,7 @@
if(istype(over_object, /obj/screen))
return FALSE
- if(loc != user || user.incapacitated() || !ishuman(user))
+ if(loc != user || !ishuman(user))
return FALSE
afterattack(over_object, user, TRUE)
diff --git a/code/modules/economy/EFTPOS.dm b/code/modules/economy/EFTPOS.dm
index 0f7aaa0a90b..a2c84a27467 100644
--- a/code/modules/economy/EFTPOS.dm
+++ b/code/modules/economy/EFTPOS.dm
@@ -42,9 +42,11 @@
/obj/item/paper/check/update_icon_state()
return
-/obj/item/paper/check/AltClick(mob/user, obj/item/I)
- to_chat(user, "Paper is too small! You fail to fold [src] into the shape of a plane!")
- return
+
+/obj/item/paper/check/AltClick(mob/living/carbon/human/user)
+ if(ishuman(user) && user.is_in_hands(src))
+ to_chat(user, span_warning("Paper is too small! You fail to fold [src] into the shape of a plane!"))
+
/obj/item/eftpos/Initialize(mapload)
machine_name = "[station_name()]"
diff --git a/code/modules/fish/fishtank.dm b/code/modules/fish/fishtank.dm
index 1724cd3da03..7766c8c0fc4 100644
--- a/code/modules/fish/fishtank.dm
+++ b/code/modules/fish/fishtank.dm
@@ -112,14 +112,14 @@
/obj/machinery/fishtank/proc/toggle_lid(mob/user)
- if(user.incapacitated() || user.restrained())
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
lid_switch = !lid_switch
update_icon(UPDATE_OVERLAYS)
/obj/machinery/fishtank/proc/toggle_light(mob/user)
- if(user.incapacitated() || user.restrained())
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
light_switch = !light_switch
if(light_switch)
diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm
index 098cf290acc..7e799507316 100644
--- a/code/modules/food_and_drinks/drinks/drinks.dm
+++ b/code/modules/food_and_drinks/drinks/drinks.dm
@@ -79,7 +79,7 @@
return
/obj/item/reagent_containers/food/drinks/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params) //CHUG! CHUG! CHUG!
- if(!iscarbon(over_object))
+ if(!iscarbon(over_object) || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return ..()
var/mob/living/carbon/chugger = over_object
if(!(container_type & DRAINABLE))
diff --git a/code/modules/food_and_drinks/drinks/drinks/cans.dm b/code/modules/food_and_drinks/drinks/drinks/cans.dm
index 31d87778e51..200b9c810f0 100644
--- a/code/modules/food_and_drinks/drinks/drinks/cans.dm
+++ b/code/modules/food_and_drinks/drinks/drinks/cans.dm
@@ -49,11 +49,11 @@
return crushed_can
/obj/item/reagent_containers/food/drinks/cans/CtrlClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, "You can't do that right now!")
- return
if(!can_shake || !ishuman(user))
return ..()
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ to_chat(user, "You can't do that right now!")
+ return ..()
var/mob/living/carbon/human/H = user
if(canopened)
to_chat(H, "You can't shake up an already opened drink!")
diff --git a/code/modules/food_and_drinks/drinks/drinks/shotglass.dm b/code/modules/food_and_drinks/drinks/drinks/shotglass.dm
index 790ddc24e52..1158e9fe294 100644
--- a/code/modules/food_and_drinks/drinks/drinks/shotglass.dm
+++ b/code/modules/food_and_drinks/drinks/drinks/shotglass.dm
@@ -104,7 +104,7 @@
/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass/MouseDrop(mob/living/carbon/human/user, src_location, over_location, src_control, over_control, params)
- if(!ishuman(user))
+ if(!ishuman(user) || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return ..()
if((CLUMSY in user.mutations) && prob(50) && (resistance_flags & ON_FIRE))
diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm
index e7fbf74b9a8..e31dade5577 100644
--- a/code/modules/food_and_drinks/food/snacks.dm
+++ b/code/modules/food_and_drinks/food/snacks.dm
@@ -202,7 +202,9 @@
. += "Alt-click to put something small inside."
/obj/item/reagent_containers/food/snacks/sliceable/AltClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
+ if(!iscarbon(user))
+ return
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
to_chat(user, "You can't do that right now!")
return
var/obj/item/I = user.get_active_hand()
@@ -216,8 +218,6 @@
// Nope, no bluespace slice food
to_chat(user, "You cannot fit [I] in [src]!")
return
- if(!iscarbon(user))
- return
if(!user.drop_transfer_item_to_loc(I, src))
to_chat(user, "You cannot slip [I] inside [src]!")
return
diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
index 82bd725feea..102ca70aa52 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
@@ -121,7 +121,7 @@
return ..()
/obj/machinery/gibber/MouseDrop_T(mob/target, mob/user, params)
- if(user.incapacitated() || !ishuman(user))
+ if(!ishuman(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(!isliving(target))
@@ -168,7 +168,7 @@
set name = "Empty Gibber"
set src in oview(1)
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
go_out()
diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
index 68ffafd8e97..d6091d8f1a0 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
@@ -239,8 +239,10 @@
//Drag pill bottle to fridge to empty it into the fridge
/obj/machinery/smartfridge/MouseDrop_T(obj/over_object, mob/user, params)
+ if(!ishuman(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ return TRUE
if(!istype(over_object, /obj/item/storage/pill_bottle)) //Only pill bottles, please
- return
+ return TRUE
if(stat & (BROKEN|NOPOWER))
to_chat(user, "\The [src] is unpowered and useless.")
return TRUE
diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm
index b924456ec26..9af289684f7 100644
--- a/code/modules/games/cards.dm
+++ b/code/modules/games/cards.dm
@@ -88,7 +88,7 @@
if(length(cardhand.cards) > 1)
var/confirm = alert("Are you sure you want to put your [length(cardhand.cards)] cards back into the deck?", "Return Hand", "Yes", "No")
- if(confirm == "No" || !Adjacent(user) || user.incapacitated())
+ if(confirm == "No" || !Adjacent(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
for(var/datum/playingcard/card in cardhand.cards)
@@ -165,7 +165,7 @@
// Datum actions
/obj/item/deck/proc/draw_card(mob/living/carbon/human/user)
- if(user.incapacitated() || !Adjacent(user))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user))
return
if(!length(cards))
@@ -193,7 +193,7 @@
/obj/item/deck/proc/deal_card(mob/user = usr)
- if(user.incapacitated() || !Adjacent(user))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user))
return
if(!length(cards))
@@ -202,18 +202,18 @@
var/list/players = list()
for(var/mob/living/player in viewers(3))
- if(!player.incapacitated())
+ if(!player.incapacitated() && !HAS_TRAIT(player, TRAIT_HANDS_BLOCKED))
players += player
var/mob/living/target = tgui_input_list(user, "Who do you wish to deal a card to?", "Deal Card", players)
- if(!user || !src || !target)
+ if(!user || !src || !target || target.incapacitated() || HAS_TRAIT(target, TRAIT_HANDS_BLOCKED))
return
deal_at(user, target, 1)
/obj/item/deck/proc/deal_card_multi(mob/user = usr)
- if(user.incapacitated() || !Adjacent(user))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user))
return
if(!length(cards))
@@ -254,21 +254,23 @@
cardhand.throw_at(get_step(target,target.dir), 3, 1, cardhand)
-/obj/item/deck/attack_self()
- deckshuffle()
+/obj/item/deck/attack_self(mob/user)
+ deckshuffle(user)
+
+/obj/item/deck/AltClick(mob/user)
+ if(Adjacent(user))
+ deckshuffle(user)
-/obj/item/deck/AltClick()
- deckshuffle()
+/obj/item/deck/proc/deckshuffle(mob/user)
+ if(cooldown < world.time - 1 SECONDS || !iscarbon(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ return
-/obj/item/deck/proc/deckshuffle()
- var/mob/living/user = usr
- if(cooldown < world.time - 1 SECONDS)
- cards = shuffle(cards)
- user.visible_message("[user] shuffles [src].")
- playsound(user, 'sound/items/cardshuffle.ogg', 50, 1)
- cooldown = world.time
+ cards = shuffle(cards)
+ user.visible_message(span_notice("[user] shuffles [src]."))
+ playsound(user, 'sound/items/cardshuffle.ogg', 50, 1)
+ cooldown = world.time
/obj/item/deck/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
@@ -466,7 +468,7 @@
/obj/item/cardhand/proc/Removecard()
var/mob/living/carbon/user = usr
- if(user.incapacitated() || !Adjacent(user))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user))
return
var/pickablecards = list()
@@ -508,9 +510,12 @@
/obj/item/cardhand/proc/discard()
var/mob/living/carbon/user = usr
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ return
+
var/maxcards = min(length(cards), 5)
var/discards = input("How many cards do you want to discard? You may discard up to [maxcards] card(s)") as num
- if(discards > maxcards)
+ if(discards > maxcards || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
for(var/i in 1 to discards)
diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm
index b4054e17cb5..39dc4998be4 100644
--- a/code/modules/hydroponics/hydroitemdefines.dm
+++ b/code/modules/hydroponics/hydroitemdefines.dm
@@ -202,7 +202,7 @@
playsound(src.loc, 'sound/weapons/blade_sheath.ogg', 50, 1) //Sound credit to Q.K. of Freesound.org
set_sharpness(extend)
update_icon(UPDATE_ICON_STATE)
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
add_fingerprint(user)
diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm
index 91c0dffd946..844bc4ba7d4 100644
--- a/code/modules/hydroponics/hydroponics.dm
+++ b/code/modules/hydroponics/hydroponics.dm
@@ -118,15 +118,15 @@
return connected
+
/obj/machinery/hydroponics/AltClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
- to_chat(user, "You can't do that right now!")
+ if(!istype(user) || !Adjacent(user))
return
- if(wrenchable && !user.incapacitated() && Adjacent(user))
- toggle_lid(user)
+ toggle_lid(user)
+
/obj/machinery/hydroponics/proc/toggle_lid(mob/living/user)
- if(!user || user.stat || user.restrained())
+ if(!wrenchable || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
lid_closed = !lid_closed
diff --git a/code/modules/instruments/objs/items/headphones.dm b/code/modules/instruments/objs/items/headphones.dm
index 47e160012ba..8ca7f4c8b6a 100644
--- a/code/modules/instruments/objs/items/headphones.dm
+++ b/code/modules/instruments/objs/items/headphones.dm
@@ -47,7 +47,7 @@
/obj/item/clothing/ears/headphones/update_icon_state()
icon_state = "headphones[on]"
item_state = "headphones[on]"
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
/obj/item/clothing/ears/headphones/item_action_slot_check(slot)
diff --git a/code/modules/instruments/objs/structures/drumkit.dm b/code/modules/instruments/objs/structures/drumkit.dm
index d00082cceff..77bec99bf63 100644
--- a/code/modules/instruments/objs/structures/drumkit.dm
+++ b/code/modules/instruments/objs/structures/drumkit.dm
@@ -93,17 +93,20 @@
/obj/structure/musician/drumkit/AltClick(mob/living/user)
rotate(user)
+
/obj/structure/musician/drumkit/proc/rotate(mob/living/user)
- if(anchored)
- to_chat(user, span_warning("The musical instrument is anchored to the floor!"))
- return FALSE
if(user)
if(isobserver(user))
if(!CONFIG_GET(flag/ghost_interaction))
return FALSE
- else if(!isliving(user) || user.incapacitated() || !Adjacent(user))
+ else if(!isliving(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user))
return FALSE
+ if(anchored)
+ if(user)
+ to_chat(user, span_warning("The musical instrument is anchored to the floor!"))
+ return FALSE
+
setDir(turn(dir, 90))
handle_layer()
handle_offsets()
diff --git a/code/modules/mining/equipment/marker_beacons.dm b/code/modules/mining/equipment/marker_beacons.dm
index e991065f495..ad77e375d51 100644
--- a/code/modules/mining/equipment/marker_beacons.dm
+++ b/code/modules/mining/equipment/marker_beacons.dm
@@ -58,10 +58,10 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list(
transfer_fingerprints_to(M)
/obj/item/stack/marker_beacon/AltClick(mob/living/user)
- if(!istype(user) || ui_status(user, GLOB.physical_state) != STATUS_INTERACTIVE)
+ if(!istype(user) || !Adjacent(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || ui_status(user, GLOB.physical_state) != STATUS_INTERACTIVE)
return
var/input_color = tgui_input_list(user, "Choose a color.", "Beacon Color", GLOB.marker_beacon_colors)
- if(!istype(user) || ui_status(user, GLOB.physical_state) != STATUS_INTERACTIVE)
+ if(!Adjacent(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || ui_status(user, GLOB.physical_state) != STATUS_INTERACTIVE)
return
if(input_color)
picked_color = input_color
@@ -139,10 +139,10 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list(
/obj/structure/marker_beacon/AltClick(mob/living/user)
..()
- if(!istype(user) || ui_status(user, GLOB.physical_state) != STATUS_INTERACTIVE)
+ if(!istype(user) || !Adjacent(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || ui_status(user, GLOB.physical_state) != STATUS_INTERACTIVE)
return
var/input_color = tgui_input_list(user, "Choose a color.", "Beacon Color", GLOB.marker_beacon_colors)
- if(!istype(user) || ui_status(user, GLOB.physical_state) != STATUS_INTERACTIVE)
+ if(!Adjacent(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || ui_status(user, GLOB.physical_state) != STATUS_INTERACTIVE)
return
if(input_color)
picked_color = input_color
diff --git a/code/modules/mining/equipment/mineral_scanner.dm b/code/modules/mining/equipment/mineral_scanner.dm
index cac03abd754..dc846a8a45b 100644
--- a/code/modules/mining/equipment/mineral_scanner.dm
+++ b/code/modules/mining/equipment/mineral_scanner.dm
@@ -17,6 +17,8 @@
origin_tech = "engineering=1;magnets=1"
/obj/item/mining_scanner/AltClick(mob/user)
+ if(!Adjacent(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ return
speaker = !speaker
to_chat(user, "You toggle [src]'s speaker to [speaker ? "ON" : "OFF"].")
@@ -58,6 +60,8 @@
origin_tech = "engineering=3;magnets=3"
/obj/item/t_scanner/adv_mining_scanner/AltClick(mob/user)
+ if(!Adjacent(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ return
speaker = !speaker
to_chat(user, "You toggle [src]'s speaker to [speaker ? "ON" : "OFF"].")
diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm
index 55b6755d285..43c871c7958 100644
--- a/code/modules/mining/fulton.dm
+++ b/code/modules/mining/fulton.dm
@@ -43,7 +43,7 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons)
return FALSE
if(!(loc == usr && loc.Adjacent(over_object)))
return FALSE
- if(!ishuman(usr) || usr.incapacitated())
+ if(!ishuman(usr) || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return FALSE
over_object.add_fingerprint(usr)
afterattack(over_object, usr, TRUE, params)
diff --git a/code/modules/mining/lavaland/loot/hierophant_loot.dm b/code/modules/mining/lavaland/loot/hierophant_loot.dm
index 57e631098f8..650e791d146 100644
--- a/code/modules/mining/lavaland/loot/hierophant_loot.dm
+++ b/code/modules/mining/lavaland/loot/hierophant_loot.dm
@@ -113,7 +113,7 @@
/obj/item/hierophant_club/update_icon_state()
icon_state = "hierophant_club[timer <= world.time ? "_ready":""][(beacon && !QDELETED(beacon)) ? "":"_beacon"]"
item_state = icon_state
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
/obj/item/hierophant_club/proc/prepare_icon_update()
diff --git a/code/modules/mining/lavaland/loot/tendril_loot.dm b/code/modules/mining/lavaland/loot/tendril_loot.dm
index 43c7cadf644..3820ed3a79b 100644
--- a/code/modules/mining/lavaland/loot/tendril_loot.dm
+++ b/code/modules/mining/lavaland/loot/tendril_loot.dm
@@ -52,7 +52,7 @@
/obj/item/shared_storage/AltClick(mob/user)
- if(!bag || !iscarbon(user) || !Adjacent(user))
+ if(!bag || !iscarbon(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user))
return ..()
open_bag(user)
diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm
index 7123d8b7ba0..b3bf3f71a25 100644
--- a/code/modules/mining/satchel_ore_boxdm.dm
+++ b/code/modules/mining/satchel_ore_boxdm.dm
@@ -88,7 +88,7 @@
set category = "Object"
set src in view(1)
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(!Adjacent(usr))
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 1236e948303..ec5d0e4c457 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -269,7 +269,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
Moved(oldloc, direct)
-/mob/dead/observer/can_use_hands() return 0
/mob/dead/observer/Stat()
..()
@@ -484,20 +483,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return
to_chat(A, "This mob is not located in the game world.")
-/* Now a spell. See spells.dm
-/mob/dead/observer/verb/boo()
- set category = "Ghost"
- set name = "Boo!"
- set desc= "Scare your crew members because of boredom!"
-
- if(bootime > world.time) return
- bootime = world.time + 600
- var/obj/machinery/light/L = locate(/obj/machinery/light) in view(1, src)
- if(L)
- L.flicker()
- //Maybe in the future we can add more spooky code here!
- return
-*/
/mob/dead/observer/memory()
set hidden = 1
diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm
index 312a0d0dcb3..ae184cac5f7 100644
--- a/code/modules/mob/holder.dm
+++ b/code/modules/mob/holder.dm
@@ -78,7 +78,7 @@
/mob/living/simple_animal/MouseDrop(atom/over_object)
var/mob/living/carbon/human/human_to_ask = over_object //changed to human to avoid stupid issues like xenos holding animals.
- if(!istype(human_to_ask) || !Adjacent(human_to_ask) || !holder_type)
+ if(!istype(human_to_ask) || human_to_ask.incapacitated() || HAS_TRAIT(human_to_ask, TRAIT_HANDS_BLOCKED) || !Adjacent(human_to_ask) || !holder_type)
return ..()
if(usr == src)
switch(alert(human_to_ask, "[src] wants you to pick [p_them()] up. Do it?",,"Yes","No"))
diff --git a/code/modules/mob/holder_pet_carrier.dm b/code/modules/mob/holder_pet_carrier.dm
index fd345f992c2..1040c0b450f 100644
--- a/code/modules/mob/holder_pet_carrier.dm
+++ b/code/modules/mob/holder_pet_carrier.dm
@@ -65,7 +65,7 @@
/obj/item/pet_carrier/AltClick(mob/user)
- if(ishuman(user) && Adjacent(user) && !user.incapacitated(FALSE, TRUE, TRUE))
+ if(ishuman(user) && Adjacent(user) && !user.incapacitated(FALSE, TRUE, TRUE) && !HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
try_free_content(null, user)
@@ -212,7 +212,7 @@
set desc = "Меняет состояние дверцы переноски, блокируя или разблокируя возможность достать содержимое."
set category = "Object"
- if(usr.stat || !ishuman(usr) || !usr.canmove || usr.restrained())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
change_state()
@@ -223,7 +223,7 @@
set desc = "Вытаскивает животное из переноски."
set category = "Object"
- if(usr.stat || !ishuman(usr) || !usr.canmove || usr.restrained())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
try_free_content(null, usr)
@@ -237,7 +237,7 @@
var/mob/living/carbon/human/user = usr
// Stops inventory actions in a mech, while ventcrawling and while being incapacitated
- if(ismecha(user.loc) || is_ventcrawling(user) || user.incapacitated(FALSE, TRUE, TRUE))
+ if(ismecha(user.loc) || is_ventcrawling(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return FALSE
if(over_object == user && user.Adjacent(src)) // this must come before the screen objects only block
@@ -245,7 +245,7 @@
return FALSE
if(opened && (istype(over_object, /obj/structure/table) || isfloorturf(over_object) \
- && length(contents) && loc == user && !user.incapacitated() && user.Adjacent(over_object)))
+ && length(contents) && loc == user && !user.incapacitated() && !HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) && user.Adjacent(over_object)))
if(alert(user, "Вытащить питомца из [name] на [over_object.name]?", "Подтверждение", "Да", "Нет") != "Да")
return FALSE
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index 068a07f55d8..97365b617a7 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -279,10 +279,18 @@
/**
* Nonliving mobs don't have hands
*/
-/mob/proc/put_in_hand_check(obj/item/I)
+/mob/proc/put_in_hand_check(obj/item/I, hand_id)
return FALSE
+/*
+/mob/living/put_in_hand_check(obj/item/I, hand_id)
+ if(istype(I) && ((mobility_flags & MOBILITY_PICKUP) || (I.flags & ABSTRACT)))
+ return TRUE
+ return FALSE
+*/
+
+
/**
* Specal proc for special mobs that use "hands" in weird ways.
*/
diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm
index ebee128ead1..2b541243e28 100644
--- a/code/modules/mob/living/carbon/alien/alien.dm
+++ b/code/modules/mob/living/carbon/alien/alien.dm
@@ -278,10 +278,6 @@ Des: Removes all infected images from the alien.
return
-/mob/living/carbon/alien/canBeHandcuffed()
- return TRUE
-
-
/mob/living/carbon/proc/get_plasma()
var/obj/item/organ/internal/xenos/plasmavessel/vessel = get_int_organ(/obj/item/organ/internal/xenos/plasmavessel)
if(!vessel)
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
index ed1f16d622a..888fc95c788 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
@@ -67,11 +67,6 @@
take_overall_damage(b_loss, f_loss)
-/mob/living/carbon/alien/humanoid/restrained()
- if(handcuffed)
- return 1
- return 0
-
/mob/living/carbon/alien/humanoid/var/temperature_resistance = T0C+75
@@ -116,12 +111,11 @@
popup.set_content(dat)
popup.open()
-/mob/living/carbon/alien/humanoid/canBeHandcuffed()
- return 1
-/mob/living/carbon/alien/humanoid/cuff_resist(obj/item/I)
- playsound(src, 'sound/voice/hiss5.ogg', 40, 1, 1) //Alien roars when starting to break free
- ..(I, cuff_break = TRUE)
+/mob/living/carbon/alien/humanoid/cuff_resist(obj/item/I, cuff_break = FALSE)
+ playsound(src, 'sound/voice/hiss5.ogg', 40, TRUE, 1) //Alien roars when starting to break free
+ return ..(I, cuff_break = TRUE)
+
/mob/living/carbon/alien/humanoid/get_standard_pixel_y_offset(lying = 0)
if(leaping)
diff --git a/code/modules/mob/living/carbon/alien/humanoid/inventory.dm b/code/modules/mob/living/carbon/alien/humanoid/inventory.dm
index dacb20483c7..348a6b93da8 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/inventory.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/inventory.dm
@@ -55,11 +55,11 @@
update_inv_pockets()
if(ITEM_SLOT_HANDCUFFED)
- handcuffed = I
+ set_handcuffed(I)
update_handcuffed_status()
if(ITEM_SLOT_LEGCUFFED)
- legcuffed = I
+ set_legcuffed(I)
update_legcuffed_status()
return I.equipped(src, slot, initial)
diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm
index 621170ba2b9..db958840788 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva.dm
@@ -79,8 +79,6 @@
/mob/living/carbon/alien/larva/attack_ui(slot_id)
return
-/mob/living/carbon/alien/larva/restrained()
- return 0
/mob/living/carbon/alien/larva/var/temperature_resistance = T0C+75
@@ -88,17 +86,13 @@
// now constructs damage icon for each organ from mask * damage field
-/mob/living/carbon/alien/larva/show_inv(mob/user as mob)
+/mob/living/carbon/alien/larva/show_inv(mob/user)
return
/mob/living/carbon/alien/larva/start_pulling(atom/movable/AM, force = pull_force, show_message = FALSE)
return FALSE
-/* Commented out because it's duplicated in life.dm
-/mob/living/carbon/alien/larva/proc/grow() // Larvae can grow into full fledged Xenos if they survive long enough -- TLE
- if(icon_state == "larva_l" && !canmove) // This is a shit death check. It is made of shit and death. Fix later.
- return
- else
- var/mob/living/carbon/alien/humanoid/A = new(loc)
- A.key = key
- qdel(src) */
+
+/mob/living/carbon/alien/larva/can_unarmed_attack() //We bite stuff, and our head is always free.
+ return TRUE
+
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 03718100038..b53fd2c351c 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -599,23 +599,27 @@
/mob/living/carbon/resist_buckle()
- spawn(0)
- resist_muzzle()
- var/obj/item/I
- if((I = get_restraining_item())) // If there is nothing to restrain him then he is not restrained
- var/breakouttime = I.breakouttime
- var/displaytime = breakouttime / 10
- visible_message("[src.name] пыта[pluralize_ru(src.gender,"ет","ют")]ся себя отстегнуть!", \
- "Вы пытаетесь себя отстегнуть... (Это займет около [displaytime] секунд и вам не нужно двигаться.)")
+ INVOKE_ASYNC(src, PROC_REF(resist_muzzle))
+ if(HAS_TRAIT(src, TRAIT_RESTRAINED))
+ var/breakouttime = 60 SECONDS
+ var/obj/item/restraints = handcuffed
+ if(wear_suit?.breakouttime)
+ restraints = wear_suit
+ if(restraints)
+ breakouttime = restraints.breakouttime
+ visible_message(
+ span_warning("[name] пыта[pluralize_ru(gender,"ет","ют")]ся себя отстегнуть!"),
+ span_notice("Вы пытаетесь себя отстегнуть... (Это займет [breakouttime / 10] секунд и Вам нельзя двигаться."),
+ )
if(do_after(src, breakouttime, src, DEFAULT_DOAFTER_IGNORE|IGNORE_HELD_ITEM))
if(!buckled)
return
- buckled.user_unbuckle_mob(src,src)
+ buckled.user_unbuckle_mob(src, src)
else
if(src && buckled)
- to_chat(src, "Вам не удалось себя отстегнуть!")
+ to_chat(src, span_warning("Вам не удалось себя отстегнуть!"))
else
- buckled.user_unbuckle_mob(src,src)
+ buckled.user_unbuckle_mob(src, src)
/mob/living/carbon/resist_fire()
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index 462e6eff793..a45fbd45e92 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -19,17 +19,17 @@
/obj/item/proc/carbon_skip_catch_check(mob/living/carbon/user)
. = TRUE
if(!isturf(loc))
- return
+ return .
if(!user.in_throw_mode)
- return
+ return .
if(!user.canmove)
- return
- if(user.restrained())
- return
+ return .
+ if(HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ return .
if(user.get_active_hand())
- return
+ return .
if(GetComponent(/datum/component/two_handed) && user.get_inactive_hand())
- return
+ return .
. = FALSE
diff --git a/code/modules/mob/living/carbon/give.dm b/code/modules/mob/living/carbon/give.dm
index a38f73c87ae..0654be6ceab 100644
--- a/code/modules/mob/living/carbon/give.dm
+++ b/code/modules/mob/living/carbon/give.dm
@@ -6,7 +6,7 @@
to_chat(usr, "Wait a second... \the [target] HAS NO HANDS! AHH!")//cheesy messages ftw
return
- if(target.incapacitated() || usr.incapacitated() || target.client == null)
+ if(target.incapacitated() || HAS_TRAIT(target, TRAIT_HANDS_BLOCKED) || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || target.client == null)
return
var/obj/item/I = get_active_hand()
@@ -23,7 +23,7 @@
return
switch(ans)
if("Yes")
- if(target.incapacitated() || usr.incapacitated())
+ if(target.incapacitated() || HAS_TRAIT(target, TRAIT_HANDS_BLOCKED) || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(!Adjacent(target))
to_chat(usr, " You need to stay in reaching distance while giving an object.")
@@ -58,6 +58,8 @@
set name = "Give Item (Toggle)"
set category = "IC"
+ if(incapacitated() || HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
+ return
if(has_status_effect(STATUS_EFFECT_OFFERING_ITEM))
to_chat(src, "You're already offering an item to someone!")
return
@@ -126,7 +128,7 @@
holder.mouse_pointer_icon = 'icons/misc/mouse_icons/give_item.dmi'
to_chat(holder, span_info("You can now left click on someone to give them your held item."))
RegisterSignal(holder.mob.get_active_hand(), list(COMSIG_PARENT_QDELETING, COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED), PROC_REF(signal_qdel))
- RegisterSignal(holder.mob, COMSIG_MOB_SWAP_HANDS, PROC_REF(signal_qdel))
+ RegisterSignal(holder.mob, list(COMSIG_MOB_SWAP_HANDS, SIGNAL_ADDTRAIT(TRAIT_HANDS_BLOCKED)), PROC_REF(signal_qdel))
/datum/click_intercept/give/Destroy(force = FALSE, ...)
holder.mouse_pointer_icon = initial(holder.mouse_pointer_icon)
@@ -190,7 +192,7 @@
add_overlay("alert_flash")
// If either of these atoms are deleted, we need to cancel everything. Also saves having to do null checks before interacting with these atoms.
RegisterSignal(I, list(COMSIG_PARENT_QDELETING, COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED), PROC_REF(cancel_give))
- RegisterSignal(giver, list(COMSIG_PARENT_QDELETING, COMSIG_MOB_SWAP_HANDS), PROC_REF(cancel_give))
+ RegisterSignal(giver, list(COMSIG_PARENT_QDELETING, COMSIG_MOB_SWAP_HANDS, SIGNAL_ADDTRAIT(TRAIT_HANDS_BLOCKED)), PROC_REF(cancel_give))
/obj/screen/alert/take_item/Destroy()
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 2a58af8747f..ced4dc49fc9 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -344,13 +344,6 @@
var/obj/item/organ/external/affecting = get_organ(ran_zone(dam_zone))
apply_damage(5, BRUTE, affecting, run_armor_check(affecting, "melee"))
-/mob/living/carbon/human/get_restraining_item()
- . = ..()
- if(!. && istype(wear_suit, /obj/item/clothing/suit/straight_jacket))
- . = wear_suit
-
-/mob/living/carbon/human/var/temperature_resistance = T0C+75
-
/mob/living/carbon/human/show_inv(mob/user)
user.set_machine(src)
@@ -618,7 +611,7 @@
. = ..(shock_damage, source, siemens_coeff, safety, override, tesla_shock, illusion, stun)
/mob/living/carbon/human/Topic(href, href_list)
- if(!usr.stat && usr.canmove && !usr.restrained() && in_range(src, usr))
+ if(in_range(src, usr) && !usr.incapacitated() && !HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
var/thief_mode = 0
if(ishuman(usr))
var/mob/living/carbon/human/H = usr
@@ -823,11 +816,11 @@
to_chat(usr, "Unable to locate a data core entry for this person.")
if(href_list["secrecordadd"])
- if(usr.incapacitated() || !hasHUD(usr, EXAMINE_HUD_SECURITY_WRITE))
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || !hasHUD(usr, EXAMINE_HUD_SECURITY_WRITE))
return
var/raw_input = input("Add Comment:", "Security records", null, null) as message
var/sanitized = copytext(trim(sanitize(raw_input)), 1, MAX_MESSAGE_LEN)
- if(!sanitized || usr.stat || usr.restrained() || !hasHUD(usr, EXAMINE_HUD_SECURITY_WRITE))
+ if(!sanitized || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || !hasHUD(usr, EXAMINE_HUD_SECURITY_WRITE))
return
add_comment(usr, "security", sanitized)
@@ -906,11 +899,11 @@
to_chat(usr, "Unable to locate a data core entry for this person.")
if(href_list["medrecordadd"])
- if(usr.incapacitated() || !hasHUD(usr, EXAMINE_HUD_MEDICAL))
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || !hasHUD(usr, EXAMINE_HUD_MEDICAL))
return
var/raw_input = input("Add Comment:", "Medical records", null, null) as message
var/sanitized = copytext(trim(sanitize(raw_input)), 1, MAX_MESSAGE_LEN)
- if(!sanitized || usr.stat || usr.restrained() || !hasHUD(usr, EXAMINE_HUD_MEDICAL))
+ if(!sanitized || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || !hasHUD(usr, EXAMINE_HUD_MEDICAL))
return
add_comment(usr, "medical", sanitized)
@@ -1149,20 +1142,13 @@
custom_pain("You feel a stabbing pain in your chest!")
L.damage = L.min_bruised_damage
-/mob/living/carbon/human/cuff_resist(obj/item/I)
+
+/mob/living/carbon/human/cuff_resist(obj/item/I, cuff_break = FALSE)
if(HULK in mutations)
say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
- if(..(I, cuff_break = TRUE))
- drop_item_ground(I, force = TRUE)
- else
- if(..())
- drop_item_ground(I, force = TRUE)
+ return ..(I, cuff_break = TRUE)
+ return ..()
-/mob/living/carbon/human/resist_restraints()
- if(wear_suit && wear_suit.breakouttime)
- cuff_resist(wear_suit)
- else
- ..()
/mob/living/carbon/human/generate_name()
name = dna.species.get_random_name(gender)
@@ -1178,7 +1164,8 @@
set src in view(1)
var/self = 0
- if(usr.stat == 1 || usr.restrained() || !isliving(usr) || usr.is_dead()) return
+ if(!isliving(usr) || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ return
if(usr == src)
self = 1
@@ -1715,8 +1702,6 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
H.receiving_cpr = FALSE
to_chat(src, "You need to stay still while performing CPR!")
-/mob/living/carbon/human/canBeHandcuffed()
- return num_hands >= 2
/mob/living/carbon/human/has_mutated_organs()
for(var/obj/item/organ/external/E as anything in bodyparts)
diff --git a/code/modules/mob/living/carbon/human/human_emote.dm b/code/modules/mob/living/carbon/human/human_emote.dm
index e8212bec94c..59e13db1084 100644
--- a/code/modules/mob/living/carbon/human/human_emote.dm
+++ b/code/modules/mob/living/carbon/human/human_emote.dm
@@ -460,7 +460,7 @@
/datum/emote/living/carbon/human/highfive/can_run_emote(mob/living/carbon/user, status_check, intentional)
. = ..()
- if(!. || user.restrained())
+ if(HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return FALSE
diff --git a/code/modules/mob/living/carbon/human/human_interaction.dm b/code/modules/mob/living/carbon/human/human_interaction.dm
index 7c9c997ca67..78678622e6d 100644
--- a/code/modules/mob/living/carbon/human/human_interaction.dm
+++ b/code/modules/mob/living/carbon/human/human_interaction.dm
@@ -1,7 +1,7 @@
/mob/living/carbon/human/Topic(href, href_list)
///////Interactions!!///////
if(href_list["interaction"])
- if (usr.stat == DEAD || usr.stat == UNCONSCIOUS || usr.restrained())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
//CONDITIONS
@@ -179,7 +179,7 @@
P.custom_emote(message = "показыва[pluralize_ru(H.gender,"ет","ют")] [P] язык!")
else if (href_list["interaction"] == "pullwing")
- if(((H.Adjacent(P) && !istype(P.loc, /obj/structure/closet)) || (H.loc == P.loc)) && hashands && !H.restrained())
+ if(((H.Adjacent(P) && !istype(P.loc, /obj/structure/closet)) || (H.loc == P.loc)) && hashands && !HAS_TRAIT(H, TRAIT_HANDS_BLOCKED))
if(!P.bodyparts_by_name[BODY_ZONE_WING])
H.custom_emote(message = "пыта[pluralize_ru(H.gender,"ет","ют")]ся поймать [P] за крылья КОТОРЫХ НЕТ!!!")
if (istype(P.loc, /obj/structure/closet))
@@ -204,7 +204,7 @@
P.custom_emote(message = "пыта[pluralize_ru(H.gender,"ет","ют")]ся поймать [P] за крылья!")
else if (href_list["interaction"] == "pull")
- if(((H.Adjacent(P) && !istype(P.loc, /obj/structure/closet)) || (H.loc == P.loc)) && hashands && !H.restrained())
+ if(((H.Adjacent(P) && !istype(P.loc, /obj/structure/closet)) || (H.loc == P.loc)) && hashands && !HAS_TRAIT(H, TRAIT_HANDS_BLOCKED))
if(!P.bodyparts_by_name[BODY_ZONE_TAIL])
H.custom_emote(message = "пыта[pluralize_ru(H.gender,"ет","ют")]ся поймать [P] за хвост КОТОРОГО НЕТ!!!")
if (istype(P.loc, /obj/structure/closet))
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index d86ec1ba2b9..0a05029c233 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -111,16 +111,17 @@
. = ..()
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)
+ //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 && 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)
- */
+ //if(!usable_legs && !(movement_type & (FLYING|FLOATING)))
+ // ADD_TRAIT(src, TRAIT_IMMOBILIZED, LACKING_LOCOMOTION_APPENDAGES_TRAIT)
+
+ update_hands_HUD()
/mob/living/carbon/human/on_movement_type_flag_enabled(datum/source, flag, old_movement_type)
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index 81407b4083c..9fa3ae1c324 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -142,6 +142,8 @@
wear_suit = null
if(!QDELETED(src))
wear_suit_update(I)
+ if(I.breakouttime) //when unequipping a straightjacket
+ REMOVE_TRAIT(src, TRAIT_RESTRAINED, SUIT_TRAIT)
else if(I == w_uniform)
if(invdrop && !dna.species.nojumpsuit)
@@ -299,11 +301,11 @@
update_inv_neck()
if(ITEM_SLOT_HANDCUFFED)
- handcuffed = I
+ set_handcuffed(I)
update_handcuffed_status()
if(ITEM_SLOT_LEGCUFFED)
- legcuffed = I
+ set_legcuffed(I)
update_legcuffed_status()
if(ITEM_SLOT_HAND_LEFT)
@@ -359,6 +361,8 @@
if(ITEM_SLOT_CLOTH_OUTER)
wear_suit = I
wear_suit_update(I)
+ if(I.breakouttime) //when equipping a straightjacket
+ ADD_TRAIT(src, TRAIT_RESTRAINED, SUIT_TRAIT)
if(ITEM_SLOT_CLOTH_INNER)
w_uniform = I
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index afd0d206fc3..5b73643389b 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -51,7 +51,7 @@
if(life_tick == 1)
regenerate_icons() // Make sure the inventory updates
- if(player_ghosted > 0 && stat == CONSCIOUS && job && !restrained())
+ if(player_ghosted > 0 && stat == CONSCIOUS && job && !HAS_TRAIT(src, TRAIT_RESTRAINED))
handle_ghosted()
if(player_logged > 0 && stat != DEAD && job)
handle_ssd()
diff --git a/code/modules/mob/living/carbon/human/species/wryn.dm b/code/modules/mob/living/carbon/human/species/wryn.dm
index 27b52962ee8..200b2f98a28 100644
--- a/code/modules/mob/living/carbon/human/species/wryn.dm
+++ b/code/modules/mob/living/carbon/human/species/wryn.dm
@@ -96,7 +96,7 @@
if(!..())
return
var/mob/living/carbon/user = owner
- if((user.restrained() && user.pulledby) || user.buckled) //Is your Wryn restrained, pulled, or buckled? No stinging!
+ if((HAS_TRAIT(user, TRAIT_RESTRAINED) && user.pulledby) || user.buckled) //Is your Wryn restrained, pulled, or buckled? No stinging!
to_chat(user, "Вам нужна свобода передвижения, чтобы ужалить кого-то!")
return
if(user.wear_suit) //Is your Wryn wearing a Hardsuit or a Laboat that's blocking their Stinger?
@@ -156,7 +156,7 @@
target.apply_damage(dam, BRUTE, organ)
playsound(user.loc, 'sound/weapons/bladeslice.ogg', 50, 0)
add_attack_logs(user, target, "Stung by Wryn Stinger - [dam] Brute damage to [organ].")
- if(target.restrained()) //Apply tiny BURN damage if target is restrained
+ if(HAS_TRAIT(target, TRAIT_RESTRAINED)) //Apply tiny BURN damage if target is restrained
if(prob(50))
user.apply_damage(2, BURN, target)
to_chat(target, "Вы ощущаете небольшое жжение! Ауч!")
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 0f4ee38b12f..dab0df35380 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -185,7 +185,6 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
qdel(stand_icon)
update_misc_effects()
- update_hands_HUD()
stand_icon = new (dna.species.icon_template ? dna.species.icon_template : 'icons/mob/human.dmi', "blank")
var/list/standing = list()
var/icon_key = generate_icon_render_key()
diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm
index eacd5f24289..e3629a9aaca 100644
--- a/code/modules/mob/living/carbon/inventory.dm
+++ b/code/modules/mob/living/carbon/inventory.dm
@@ -24,55 +24,70 @@
swap_hand()
-/mob/living/carbon/can_use_hands()
- if(handcuffed)
- return FALSE
- if(buckled && !istype(buckled, /obj/structure/chair)) // buckling does not restrict hands
- return FALSE
- return TRUE
-
+/mob/living/carbon/resist_restraints()
+ INVOKE_ASYNC(src, PROC_REF(resist_muzzle))
+ var/obj/item/restraints
+ if(wear_suit?.breakouttime)
+ restraints = wear_suit
+ else if(handcuffed)
+ restraints = handcuffed
+ else if(legcuffed)
+ restraints = legcuffed
+ if(restraints)
+ cuff_resist(restraints)
-/mob/living/carbon/proc/canBeHandcuffed()
- return FALSE
+/// Simple helper used to equip passed item to the predefined slots.
+/mob/living/carbon/proc/apply_restraints(cuffs, slot_flag, qdel_on_fail = FALSE, silent = FALSE)
+ if(!isitem(cuffs))
+ CRASH("Wrong object ([cuffs]) passed as argument")
+ switch(slot_flag)
+ if(ITEM_SLOT_HANDCUFFED)
+ return equip_to_slot_if_possible(cuffs, ITEM_SLOT_HANDCUFFED, qdel_on_fail = qdel_on_fail, disable_warning = silent, initial = silent)
+ if(ITEM_SLOT_LEGCUFFED)
+ return equip_to_slot_if_possible(cuffs, ITEM_SLOT_LEGCUFFED, qdel_on_fail = qdel_on_fail, disable_warning = silent, initial = silent)
+ else
+ CRASH("Wrong slot passed as argument")
-/mob/living/carbon/restrained()
- if(get_restraining_item())
- return TRUE
- return FALSE
+/// Forcefully removes legcuffs and handcuffs.
+/mob/living/carbon/proc/uncuff()
+ if(handcuffed)
+ drop_item_ground(handcuffed, TRUE)
-/mob/living/carbon/get_restraining_item()
- return handcuffed
+ if(legcuffed)
+ drop_item_ground(legcuffed, TRUE)
-/mob/living/carbon/resist_restraints()
- spawn(0)
- resist_muzzle()
- var/obj/item/I = null
- if(handcuffed)
- I = handcuffed
- else if(legcuffed)
- I = legcuffed
- if(I)
- cuff_resist(I)
+/// 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)
+ else if(handcuffed)
+ ADD_TRAIT(src, TRAIT_RESTRAINED, HANDCUFFED_TRAIT)
-//called when we get cuffed/uncuffed
+/// Called when we get cuffed/uncuffed
/mob/living/carbon/proc/update_handcuffed_status()
if(handcuffed)
- drop_from_active_hand()
- drop_from_inactive_hand()
+ drop_from_hands()
stop_pulling()
- throw_alert("handcuffed", /obj/screen/alert/restrained/handcuffed, new_master = src.handcuffed)
+ throw_alert(ALERT_HANDCUFFED, /obj/screen/alert/restrained/handcuffed, new_master = handcuffed)
else
- clear_alert("handcuffed")
+ clear_alert(ALERT_HANDCUFFED)
update_action_buttons_icon() //some of our action buttons might be unusable when we're handcuffed.
update_inv_handcuffed()
update_hands_HUD()
+/// Updates hands HUD element.
/mob/living/carbon/proc/update_hands_HUD()
if(!hud_used)
return
@@ -80,116 +95,68 @@
hand_box.update_appearance()
+/// Modifies the legcuffed value if a different value is passed, returning FALSE otherwise.
+/// The variable should only be changed through this proc.
+/mob/living/carbon/proc/set_legcuffed(new_value)
+ if(legcuffed == new_value)
+ return FALSE
+ . = legcuffed
+ legcuffed = new_value
-/**
- * Updates move intent, popup alert and human legcuffed overlay.
- */
+
+/// Updates move intent, popup alert and human legcuffed overlay.
/mob/living/carbon/proc/update_legcuffed_status()
if(legcuffed)
- throw_alert("legcuffed", /obj/screen/alert/restrained/legcuffed, new_master = legcuffed)
+ throw_alert(ALERT_LEGCUFFED, /obj/screen/alert/restrained/legcuffed, new_master = legcuffed)
if(m_intent == MOVE_INTENT_RUN)
toggle_move_intent()
else
- clear_alert("legcuffed")
+ clear_alert(ALERT_LEGCUFFED)
if(m_intent == MOVE_INTENT_WALK)
toggle_move_intent()
update_inv_legcuffed()
-/mob/living/carbon/proc/cuff_resist(obj/item/I, breakouttime = 600, cuff_break = FALSE)
- breakouttime = I.breakouttime
-
- var/displaytime = breakouttime / 10
- if(!cuff_break)
- visible_message("[src.name] пыта[pluralize_ru(src.gender,"ет","ют")]ся снять [I]!")
- to_chat(src, "Вы пытаетесь снять [I]... (Это займет около [displaytime] секунд и вам не нужно двигаться.)")
+/// General proc to resist passed item.
+/mob/living/carbon/proc/cuff_resist(obj/item/I, cuff_break = FALSE)
+ . = FALSE
+ var/breakouttime = I.breakouttime
+ if(cuff_break)
+ breakouttime = 5 SECONDS // very fast!
+ visible_message(
+ span_warning("[name] пыта[pluralize_ru(gender,"ет","ют")]ся сломать [I.name]!"),
+ span_notice("Вы пытаетесь сломать [I.name]... (Процесс займёт 5 секунд и Вам нельзя двигаться.)"),
+ )
if(do_after(src, breakouttime, src, DEFAULT_DOAFTER_IGNORE|IGNORE_HELD_ITEM))
- if(I.loc != src || buckled)
- return
- visible_message("[src.name] удалось снять [I]!")
- to_chat(src, "Вы успешно сняли [I].")
-
- if(I == handcuffed)
- drop_item_ground(I, TRUE)
- return
- if(I == legcuffed)
- drop_item_ground(I, TRUE)
- return
- else
- drop_item_ground(I, TRUE)
- return
+ . = clear_cuffs(I, cuff_break)
else
- to_chat(src, "Вам не удалось снять [I]!")
-
+ to_chat(src, span_warning("Вам не удалось сломать [I.name]!"))
else
- breakouttime = 50
- visible_message("[src.name] пыта[pluralize_ru(src.gender,"ет","ют")]ся сломать [I]!")
- to_chat(src, "Вы пытаетесь сломать [I]... (Это займет у вас приблизительно 5 секунд и вам не нужно двигаться)")
+ visible_message(
+ span_warning("[name] пыта[pluralize_ru(gender,"ет","ют")]ся снять [I.name]!"),
+ span_notice("Вы пытаетесь снять [I.name]... (Процесс займёт [breakouttime / 10] секунд и Вам нельзя двигаться.)"),
+ )
if(do_after(src, breakouttime, src, DEFAULT_DOAFTER_IGNORE|IGNORE_HELD_ITEM))
- if(!I.loc || buckled)
- return
- visible_message("[src.name] успешно сломал[genderize_ru(src.gender,"","а","о","и")] [I]!")
- to_chat(src, "Вы успешно сломали [I].")
- temporarily_remove_item_from_inventory(I, TRUE)
- qdel(I)
- else
- to_chat(src, "Вам не удалось сломать [I]!")
-
-
-/**
- * Pass any type of handcuffs as 'new type()'
- */
-/mob/living/carbon/proc/set_handcuffed(new_value)
- . = FALSE
-
- if(!istype(new_value, /obj/item/restraints/handcuffs))
- stack_trace("[new_value] is not a valid handcuffs!")
- qdel(new_value)
- return
-
- if(handcuffed || handcuffed == new_value || !has_organ_for_slot(ITEM_SLOT_HANDCUFFED))
- drop_item_ground(new_value)
- return
-
- equip_to_slot(new_value, ITEM_SLOT_HANDCUFFED)
- . = TRUE
-
-
-/mob/living/carbon/proc/set_legcuffed(new_value, qdel_if_cuffed = TRUE)
- . = FALSE
-
- if(!new_value)
- stack_trace("No legcuffs passed!")
- return
-
- var/obj/item/restraints/legcuffs/legcuffs = new_value
- if(ispath(new_value))
- legcuffs = new new_value
-
- if(!istype(legcuffs, /obj/item/restraints/legcuffs))
- stack_trace("[new_value] is not a valid legcuffs!")
- qdel(legcuffs)
- return
-
- if(legcuffed || legcuffed == legcuffs || !has_organ_for_slot(ITEM_SLOT_LEGCUFFED))
- if(qdel_if_cuffed)
- qdel(legcuffs)
+ . = clear_cuffs(I, cuff_break)
else
- drop_item_ground(legcuffs)
- return
-
- equip_to_slot(legcuffs, ITEM_SLOT_LEGCUFFED)
- . = TRUE
-
+ to_chat(src, span_warning("Вам не удалось снять [I.name]!"))
-/mob/living/carbon/proc/uncuff()
- if(handcuffed)
- drop_item_ground(handcuffed, TRUE)
- if(legcuffed)
- drop_item_ground(legcuffed, TRUE)
+/mob/living/carbon/proc/clear_cuffs(obj/item/I, cuff_break)
+ if(!I.loc || buckled)
+ return FALSE
+ if(I != handcuffed && I != legcuffed && I != wear_suit)
+ return FALSE
+ visible_message(
+ span_danger("[name] удалось [cuff_break ? "сломать" : "снять"] [I.name]!"),
+ span_notice("Вы успешно [cuff_break ? "сломали" : "сняли"] [I.name]."),
+ )
+ if(cuff_break)
+ qdel(I)
+ return TRUE
+ return drop_item_ground(I)
/mob/living/carbon/is_muzzled()
@@ -205,17 +172,25 @@
return
var/obj/item/clothing/mask/muzzle/I = wear_mask
var/time = I.resist_time
- if(I.resist_time == 0)//if it's 0, you can't get out of it
- to_chat(src, "[I] слишком хорошо зафиксирован, для него вам понадобятся руки!")
- else
- visible_message("[src.name] грыз[pluralize_ru(src.gender,"ет","ут")] [I], пытаясь избавиться от него!")
- to_chat(src, "Вы пытаетесь избавиться от [I]... (Это займет около [time/10] секунд и вам не нужно двигаться.)")
- if(do_after(src, time, src, DEFAULT_DOAFTER_IGNORE|IGNORE_HELD_ITEM))
- visible_message("[src.name] избавил[genderize_ru(src.gender,"ся","ась","ось","ись")] от [I]!")
- to_chat(src, "Вы избавились от [I]!")
- if(I.security_lock)
- I.do_break()
- drop_item_ground(I, TRUE)
+ if(!time) //if it's 0, you can't get out of it
+ to_chat(src, "[capitalize(I.name)] слишком хорошо зафиксирован!")
+ return
+
+ visible_message(
+ span_warning("[name] грыз[pluralize_ru(gender,"ёт","ут")] [I.name], пытаясь освободиться!"),
+ span_notice("Вы пытаетесь избавиться от [I.name]... (Это займет [time / 10] секунд и вам нельзя двигаться.)"),
+ )
+
+ if(!do_after(src, time, src, DEFAULT_DOAFTER_IGNORE|IGNORE_HELD_ITEM) || QDELETED(I) || I != wear_mask)
+ return
+
+ visible_message(
+ span_danger("[name] избавил[genderize_ru(gender,"ся","ась","ось","ись")] от [I.name]!"),
+ span_notice("Вы успешно избавились от [I.name]."),
+ )
+ if(I.security_lock)
+ I.do_break()
+ drop_item_ground(I, TRUE)
/mob/living/carbon/show_inv(mob/user)
@@ -265,7 +240,7 @@
/mob/living/carbon/Topic(href, href_list)
..()
//strip panel
- if(usr.incapacitated() || !Adjacent(usr))
+ if(usr.incapacitated() || !Adjacent(usr) || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(href_list["internal"])
@@ -351,14 +326,14 @@
update_inv_wear_mask()
else if(I == handcuffed)
- handcuffed = null
- if(buckled && buckled.buckle_requires_restraints)
+ set_handcuffed(null)
+ if(buckled?.buckle_requires_restraints)
buckled.unbuckle_mob(src)
if(!QDELETED(src))
update_handcuffed_status()
else if(I == legcuffed)
- legcuffed = null
+ set_legcuffed(null)
if(!QDELETED(src))
update_legcuffed_status()
@@ -373,7 +348,7 @@
if(I.item_flags & NOPICKUP)
return FALSE
- if(incapacitated(ignore_lying = TRUE))
+ if(!(mobility_flags & MOBILITY_PICKUP) && !(I.flags & ABSTRACT))
return FALSE
if(lying_angle && !(I.item_flags & ABSTRACT))
diff --git a/code/modules/mob/living/init_signals.dm b/code/modules/mob/living/init_signals.dm
index ff29cf332bc..760880b9802 100644
--- a/code/modules/mob/living/init_signals.dm
+++ b/code/modules/mob/living/init_signals.dm
@@ -1,5 +1,12 @@
/// Called on [/mob/living/Initialize(mapload)], for the mob to register to relevant signals.
/mob/living/proc/register_init_signals()
+ RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_HANDS_BLOCKED), PROC_REF(on_handsblocked_trait_gain))
+ RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_HANDS_BLOCKED), PROC_REF(on_handsblocked_trait_loss))
+
+ RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_RESTRAINED), PROC_REF(on_restrained_trait_gain))
+ RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_RESTRAINED), PROC_REF(on_restrained_trait_loss))
+
+
RegisterSignal(src, COMSIG_MOVETYPE_FLAG_ENABLED, PROC_REF(on_movement_type_flag_enabled))
RegisterSignal(src, COMSIG_MOVETYPE_FLAG_DISABLED, PROC_REF(on_movement_type_flag_disabled))
@@ -16,6 +23,32 @@
AddElement(/datum/element/connect_loc, loc_connections)
+/// Called when [TRAIT_HANDS_BLOCKED] is added to the mob.
+/mob/living/proc/on_handsblocked_trait_gain(datum/source)
+ SIGNAL_HANDLER
+ mobility_flags &= ~(MOBILITY_USE|MOBILITY_PICKUP|MOBILITY_STORAGE)
+ on_handsblocked_start()
+
+
+/// Called when [TRAIT_HANDS_BLOCKED] is removed from the mob.
+/mob/living/proc/on_handsblocked_trait_loss(datum/source)
+ SIGNAL_HANDLER
+ mobility_flags |= (MOBILITY_USE|MOBILITY_PICKUP|MOBILITY_STORAGE)
+ on_handsblocked_end()
+
+
+/// Called when [TRAIT_RESTRAINED] is added to the mob.
+/mob/living/proc/on_restrained_trait_gain(datum/source)
+ SIGNAL_HANDLER
+ ADD_TRAIT(src, TRAIT_HANDS_BLOCKED, TRAIT_RESTRAINED)
+
+
+/// Called when [TRAIT_RESTRAINED] is removed from the mob.
+/mob/living/proc/on_restrained_trait_loss(datum/source)
+ SIGNAL_HANDLER
+ REMOVE_TRAIT(src, TRAIT_HANDS_BLOCKED, TRAIT_RESTRAINED)
+
+
///From [element/movetype_handler/on_movement_type_trait_gain()]
/mob/living/proc/on_movement_type_flag_enabled(datum/source, flag, old_movement_type)
SIGNAL_HANDLER
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index e3ce13bb1ad..69a08d81181 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -197,7 +197,7 @@
//Should stop you pushing a restrained person out of the way
if(isliving(M))
var/mob/living/L = M
- 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
@@ -205,7 +205,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 restrained, you cannot push past.")
return TRUE
@@ -223,7 +223,7 @@
if(M.pulledby == src && a_intent == INTENT_GRAB)
mob_swap = TRUE
//restrained people act if they were on 'help' intent to prevent a person being pulled from being seperated from their puller
- else if((M.restrained() || M.a_intent == INTENT_HELP) && (restrained() || a_intent == INTENT_HELP))
+ else if((HAS_TRAIT(M, TRAIT_RESTRAINED) || M.a_intent == INTENT_HELP) && (HAS_TRAIT(src, TRAIT_RESTRAINED) || a_intent == INTENT_HELP))
mob_swap = TRUE
if(mob_swap)
//switch our position with M
@@ -780,7 +780,7 @@
if(pulling && !isturf(pulling.loc) && pulling.loc != loc)
log_debug("[src]'s pull on [pulling] was broken despite [pulling] being in [pulling.loc]. Pull stopped manually.")
stop_pulling()
- if(restrained())
+ if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
stop_pulling()
var/turf/old_loc = loc
@@ -986,9 +986,8 @@
SEND_SIGNAL(src, COMSIG_LIVING_RESIST, src)
- if(!restrained())
- if(resist_grab())
- return
+ if(!HAS_TRAIT(src, TRAIT_RESTRAINED) && resist_grab())
+ return
//unbuckling yourself
if(buckled && last_special <= world.time)
@@ -1042,9 +1041,7 @@
return modifier
/mob/living/proc/resist_buckle()
- spawn(0)
- resist_muzzle()
- buckled.user_unbuckle_mob(src,src)
+ buckled.user_unbuckle_mob(src, src)
/mob/living/proc/resist_muzzle()
return
@@ -1053,10 +1050,9 @@
return
/mob/living/proc/resist_restraints()
- spawn(0)
- resist_muzzle()
return
+
/*//////////////////////
END RESIST PROCS
*///////////////////////
@@ -1657,3 +1653,15 @@
else
set_density(TRUE)
+
+/// Proc to append behavior to the condition of being handsblocked. Called when the condition starts.
+/mob/living/proc/on_handsblocked_start()
+ drop_from_hands()
+ stop_pulling()
+ add_traits(list(TRAIT_UI_BLOCKED, TRAIT_PULL_BLOCKED), TRAIT_HANDS_BLOCKED)
+
+
+/// Proc to append behavior to the condition of being handsblocked. Called when the condition ends.
+/mob/living/proc/on_handsblocked_end()
+ remove_traits(list(TRAIT_UI_BLOCKED, TRAIT_PULL_BLOCKED), TRAIT_HANDS_BLOCKED)
+
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index da4ab07089d..1f6739612f0 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -398,7 +398,7 @@
/mob/living/RangedAttack(atom/A, params) //Player firing
if(GLOB.pacifism_after_gt)
return
- else if(dirslash_enabled && a_intent != INTENT_HELP)
+ if(dirslash_enabled && a_intent != INTENT_HELP)
var/turf/turf_attacking = get_step(src, get_compass_dir(src, A))
if(turf_attacking)
var/mob/living/target = locate() in turf_attacking
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 7becdd37448..630b5d33035 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -648,8 +648,6 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
return 1
return 0
-/mob/living/silicon/ai/restrained()
- return FALSE
/mob/living/silicon/ai/emp_act(severity)
..()
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index d404017c19d..62fbc65ab2e 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -198,13 +198,6 @@
return 1
return 0
-/mob/living/silicon/pai/restrained()
- if(istype(loc,/obj/item/paicard))
- return 0
- ..()
-
-/mob/living/silicon/pai/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
- return
/mob/living/silicon/pai/emp_act(severity)
// Silence for 2 minutes
@@ -598,7 +591,7 @@
return H
/mob/living/silicon/pai/MouseDrop(mob/living/carbon/human/user, src_location, over_location, src_control, over_control, params)
- if(!ishuman(user) || !Adjacent(user))
+ if(!ishuman(user) || !Adjacent(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return ..()
if(usr == src)
switch(alert(user, "[src] wants you to pick [p_them()] up. Do it?",,"Yes","No"))
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm
index ebdf3a5cc62..16a16059021 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm
@@ -123,7 +123,8 @@
set name = "Drop Gripped Item"
set desc = "Release an item from your magnetic gripper."
set category = "Drone"
-
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ return
drop_gripped_item()
/obj/item/gripper/attack_self(mob/user)
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 64433c704cb..788dd512774 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -717,8 +717,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
for(var/datum/robot_energy_storage/st in module.storages)
stat("[st.name]:", "[st.energy]/[st.max_energy]")
-/mob/living/silicon/robot/restrained()
- return 0
/mob/living/silicon/robot/InCritical()
return low_power_mode
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 44f468468b2..632d3b75a4c 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -400,3 +400,16 @@
/////////////////////////////////// EAR DAMAGE ////////////////////////////////////
/mob/living/silicon/can_hear()
return TRUE
+
+
+/mob/living/silicon/put_in_hand_check() // This check is for borgs being able to receive items, not put them in others' hands.
+ return FALSE
+
+
+/mob/living/silicon/on_handsblocked_start()
+ return // AIs and borgs have no hands
+
+
+/mob/living/silicon/on_handsblocked_end()
+ return // AIs and borgs have no hands
+
diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
index f0105b8b566..864e98ebeb3 100644
--- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
@@ -276,6 +276,8 @@
/mob/living/simple_animal/bot/cleanbot/UnarmedAttack(atom/A)
+ if(!can_unarmed_attack())
+ return
if(istype(A,/obj/effect/decal/cleanable))
start_clean(A)
else
diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm
index 4ce662598e8..5a0ea77acea 100644
--- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm
@@ -325,7 +325,7 @@
back_to_hunt()
return
- if(iscarbon(target) && target.canBeHandcuffed())
+ if(iscarbon(target) && target.has_organ_for_slot(ITEM_SLOT_HANDCUFFED))
if(!arrest_type)
if(!target.handcuffed) //he's not cuffed? Try to cuff him!
start_cuffing(target)
@@ -589,13 +589,13 @@
/mob/living/simple_animal/bot/ed209/UnarmedAttack(atom/A)
- if(!on)
+ if(!on || !can_unarmed_attack())
return
if(iscarbon(A))
var/mob/living/carbon/C = A
if(C.staminaloss < 110 || arrest_type && !baton_delayed)
stun_attack(A)
- else if(C.canBeHandcuffed() && !C.handcuffed)
+ else if(C.has_organ_for_slot(ITEM_SLOT_HANDCUFFED) && !C.handcuffed)
start_cuffing(A)
else
..()
@@ -653,7 +653,7 @@
if(!Adjacent(C) || !isturf(C.loc) || C.handcuffed)
return
- C.set_handcuffed(new /obj/item/restraints/handcuffs/cable/zipties/used(C))
+ C.apply_restraints(new /obj/item/restraints/handcuffs/cable/zipties/used(null), ITEM_SLOT_HANDCUFFED, TRUE)
back_to_idle()
diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm
index 41efd278234..8d886ecf9c3 100644
--- a/code/modules/mob/living/simple_animal/bot/floorbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm
@@ -461,6 +461,8 @@
/mob/living/simple_animal/bot/floorbot/UnarmedAttack(atom/A)
+ if(!can_unarmed_attack())
+ return
if(isturf(A))
repair(A)
else if(istype(A,/obj/item/stack/tile/plasteel))
diff --git a/code/modules/mob/living/simple_animal/bot/griefsky.dm b/code/modules/mob/living/simple_animal/bot/griefsky.dm
index 3493c236d7a..e556f5b2085 100644
--- a/code/modules/mob/living/simple_animal/bot/griefsky.dm
+++ b/code/modules/mob/living/simple_animal/bot/griefsky.dm
@@ -95,7 +95,7 @@
/mob/living/simple_animal/bot/secbot/griefsky/UnarmedAttack(atom/A) //like secbots its only possible with admin intervention
- if(!on)
+ if(!on || !can_unarmed_attack())
return
if(iscarbon(A))
var/mob/living/carbon/C = A
diff --git a/code/modules/mob/living/simple_animal/bot/honkbot.dm b/code/modules/mob/living/simple_animal/bot/honkbot.dm
index 8e69a759c4d..f260427721f 100644
--- a/code/modules/mob/living/simple_animal/bot/honkbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/honkbot.dm
@@ -127,7 +127,7 @@
/mob/living/simple_animal/bot/honkbot/UnarmedAttack(atom/A)
- if(!on)
+ if(!on || !can_unarmed_attack())
return
if(iscarbon(A))
var/mob/living/carbon/C = A
diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm
index a1bdb645f1c..f88226da579 100644
--- a/code/modules/mob/living/simple_animal/bot/medbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/medbot.dm
@@ -459,6 +459,8 @@
/mob/living/simple_animal/bot/medbot/UnarmedAttack(atom/A)
+ if(!can_unarmed_attack())
+ return
if(iscarbon(A))
var/mob/living/carbon/C = A
patient = C
diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm
index 6a382e36c65..5c07f827789 100644
--- a/code/modules/mob/living/simple_animal/bot/mulebot.dm
+++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm
@@ -208,6 +208,9 @@
if(..())
return TRUE
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ return
+
switch(href_list["op"])
if("lock")
toggle_lock(usr)
@@ -375,7 +378,7 @@
// can load anything if hacked
/mob/living/simple_animal/bot/mulebot/MouseDrop_T(atom/movable/AM, mob/user, params)
- if(!istype(AM) || user.incapacitated() || !in_range(user, src))
+ if(!istype(AM) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !in_range(user, src))
return FALSE
load(AM)
@@ -914,6 +917,8 @@
/mob/living/simple_animal/bot/mulebot/UnarmedAttack(atom/A)
+ if(!can_unarmed_attack())
+ return
if(isturf(A) && isturf(loc) && loc.Adjacent(A) && load)
unload(get_dir(loc, A))
else
diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm
index fa5b98ee2fa..226d44a3ba3 100644
--- a/code/modules/mob/living/simple_animal/bot/secbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/secbot.dm
@@ -259,13 +259,13 @@
/mob/living/simple_animal/bot/secbot/UnarmedAttack(atom/A)
- if(!on)
+ if(!on || !can_unarmed_attack())
return
if(iscarbon(A))
var/mob/living/carbon/C = A
if((C.staminaloss < 110 || arrest_type) && !baton_delayed)
stun_attack(A)
- else if(C.canBeHandcuffed() && !C.handcuffed)
+ else if(C.has_organ_for_slot(ITEM_SLOT_HANDCUFFED) && !C.handcuffed)
cuff(A)
else
..()
@@ -295,7 +295,7 @@
if(!Adjacent(C) || !isturf(C.loc) || C.handcuffed)
return
- C.set_handcuffed(new /obj/item/restraints/handcuffs/cable/zipties/used(C))
+ C.apply_restraints(new /obj/item/restraints/handcuffs/cable/zipties/used(null), ITEM_SLOT_HANDCUFFED, TRUE)
playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0)
back_to_idle()
@@ -401,7 +401,7 @@
back_to_hunt()
return
- if(iscarbon(target) && target.canBeHandcuffed())
+ if(iscarbon(target) && target.has_organ_for_slot(ITEM_SLOT_HANDCUFFED))
if(!arrest_type)
if(!target.handcuffed) //he's not cuffed? Try to cuff him!
cuff(target)
diff --git a/code/modules/mob/living/simple_animal/bot/syndicate.dm b/code/modules/mob/living/simple_animal/bot/syndicate.dm
index 55040e170e0..60674386ac4 100644
--- a/code/modules/mob/living/simple_animal/bot/syndicate.dm
+++ b/code/modules/mob/living/simple_animal/bot/syndicate.dm
@@ -203,7 +203,7 @@
/mob/living/simple_animal/bot/ed209/syndicate/UnarmedAttack(atom/A)
- if(!on)
+ if(!on || !can_unarmed_attack())
return
shootAt(A)
diff --git a/code/modules/mob/living/simple_animal/friendly/diona.dm b/code/modules/mob/living/simple_animal/friendly/diona.dm
index a7b0afcb097..4a0ade9fd66 100644
--- a/code/modules/mob/living/simple_animal/friendly/diona.dm
+++ b/code/modules/mob/living/simple_animal/friendly/diona.dm
@@ -90,7 +90,9 @@
evolve_action.Grant(src)
steal_blood_action.Grant(src)
-/mob/living/simple_animal/diona/UnarmedAttack(var/atom/A)
+/mob/living/simple_animal/diona/UnarmedAttack(atom/A)
+ if(!can_unarmed_attack())
+ return
if(isdiona(A) && (src in A.contents)) //can't attack your gestalt
visible_message("[src] wiggles around a bit.")
else
diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm
index 70cd855dcb0..339f55d0d15 100644
--- a/code/modules/mob/living/simple_animal/hostile/statue.dm
+++ b/code/modules/mob/living/simple_animal/hostile/statue.dm
@@ -208,7 +208,4 @@
/mob/living/simple_animal/hostile/statue/sentience_act()
faction -= "neutral"
-/mob/living/simple_animal/hostile/statue/restrained()
- . = ..()
- if(can_be_seen(loc))
- return 1
+
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index e0e18ee3649..f1001edbb48 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -170,7 +170,7 @@
/mob/living/simple_animal/parrot/Topic(href, href_list)
//Can the usr physically do this?
- if(!usr.canmove || usr.stat || usr.restrained() || !usr.Adjacent(src))
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || !usr.Adjacent(src))
return
//Is the usr's mob type able to do this?
diff --git a/code/modules/mob/living/update_status.dm b/code/modules/mob/living/update_status.dm
index 3b63f8e991b..fa02c92e9fe 100644
--- a/code/modules/mob/living/update_status.dm
+++ b/code/modules/mob/living/update_status.dm
@@ -76,7 +76,7 @@
extra_checks += CALLBACK(src, TYPE_PROC_REF(/mob/living, IsWeakened))
extra_checks += CALLBACK(src, TYPE_PROC_REF(/mob/living, IsStunned))
- if(stat || IsParalyzed() || (!ignore_restraints && restrained()) || (!ignore_lying && lying_angle) || check_for_true_callbacks(extra_checks))
+ if(stat || IsParalyzed() || (!ignore_restraints && HAS_TRAIT(src, TRAIT_RESTRAINED)) || (!ignore_lying && lying_angle) || check_for_true_callbacks(extra_checks))
return TRUE
//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 38abaccd2de..79d271d6817 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -668,9 +668,6 @@
show_inv(user)
-/mob/proc/can_use_hands()
- return
-
/mob/proc/is_mechanical()
return mind && (mind.assigned_role == JOB_TITLE_CYBORG || mind.assigned_role == JOB_TITLE_AI)
@@ -837,7 +834,7 @@
return FALSE
if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM))
return FALSE
- if(restrained())
+ if(HAS_TRAIT(src, TRAIT_RESTRAINED))
return FALSE
return TRUE
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index ca811030178..deca4e46442 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -87,9 +87,9 @@
if(SEND_SIGNAL(mob, COMSIG_MOB_CLIENT_PRE_MOVE, args) & COMSIG_MOB_CLIENT_BLOCK_PRE_MOVE)
return FALSE
- if(mob.restrained() && mob.pulledby) // Why being pulled while cuffed prevents you from moving
+ if(HAS_TRAIT(mob, TRAIT_RESTRAINED) && mob.pulledby) // Why being pulled while cuffed prevents you from moving
var/mob/puller = mob.pulledby
- if(!puller.incapacitated() && mob.Adjacent(puller))
+ if(!puller.incapacitated() && !HAS_TRAIT(puller, TRAIT_HANDS_BLOCKED) && mob.Adjacent(puller))
to_chat(src, span_warning("Вы скованы и не можете пошевелиться!"))
move_delay = world.time + 1 SECONDS
return FALSE
@@ -336,7 +336,7 @@
/mob/proc/Move_Pulled(atom/target)
- if(!canmove || restrained() || !pulling)
+ if(!canmove || HAS_TRAIT(src, TRAIT_RESTRAINED) || !pulling)
return
if(pulling.anchored || pulling.move_resist > move_force || !pulling.Adjacent(src))
stop_pulling()
diff --git a/code/modules/mob/update_status.dm b/code/modules/mob/update_status.dm
index a8510077617..97a67e491e7 100644
--- a/code/modules/mob/update_status.dm
+++ b/code/modules/mob/update_status.dm
@@ -46,13 +46,6 @@
/mob/proc/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, ignore_lying = FALSE)
return FALSE
-/mob/proc/restrained(ignore_grab)
- // All are created free
- return FALSE
-
-/mob/proc/get_restraining_item()
- return null
-
// Procs that update other things about the mob
/mob/proc/update_stat()
diff --git a/code/modules/newscaster/obj/newscaster.dm b/code/modules/newscaster/obj/newscaster.dm
index feab12e2b4d..a2ba71ec4d3 100644
--- a/code/modules/newscaster/obj/newscaster.dm
+++ b/code/modules/newscaster/obj/newscaster.dm
@@ -718,7 +718,7 @@
set category = "Object"
set src in oview(1)
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
eject_photo(usr)
diff --git a/code/modules/newscaster/obj/newspaper.dm b/code/modules/newscaster/obj/newspaper.dm
index d0e7aa8f09d..e1a097dd57b 100644
--- a/code/modules/newscaster/obj/newspaper.dm
+++ b/code/modules/newscaster/obj/newspaper.dm
@@ -182,7 +182,7 @@
return ..()
/obj/item/newspaper/AltClick(mob/user)
- if(ishuman(user) && Adjacent(user) && !user.incapacitated())
+ if(ishuman(user) && Adjacent(user) && !user.incapacitated() && !HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
rolled = !rolled
icon_state = "newspaper[rolled ? "_rolled" : ""]"
update_icon()
diff --git a/code/modules/paperwork/carbonpaper.dm b/code/modules/paperwork/carbonpaper.dm
index 30d9aadbf3e..f549f1e1b72 100644
--- a/code/modules/paperwork/carbonpaper.dm
+++ b/code/modules/paperwork/carbonpaper.dm
@@ -29,6 +29,9 @@
set category = "Object"
set src in usr
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ return
+
if(copied == 0)
var/obj/item/paper/carbon/c = src
var/copycontents = html_decode(c.info)
diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm
index b28b1d6948b..78bb656e966 100644
--- a/code/modules/paperwork/clipboard.dm
+++ b/code/modules/paperwork/clipboard.dm
@@ -20,7 +20,7 @@
/obj/item/clipboard/AltClick(mob/user)
- if(Adjacent(user) && !user.incapacitated())
+ if(Adjacent(user) && !user.incapacitated() && !HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
if(is_pen(user.get_active_hand()))
penPlacement(user, user.get_active_hand(), TRUE)
else
@@ -29,12 +29,12 @@
. = ..()
-/obj/item/clipboard/verb/removePen(mob/user)
+/obj/item/clipboard/verb/removePen()
set category = "Object"
set name = "Remove clipboard pen"
- if(!ishuman(user) || user.incapacitated())
+ if(!ishuman(usr) || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
- penPlacement(user, containedpen, FALSE)
+ penPlacement(usr, containedpen, FALSE)
/obj/item/clipboard/proc/isPaperwork(obj/item/W) //This could probably do with being somewhere else but for now it's fine here.
if(istype(W, /obj/item/paper) || istype(W, /obj/item/paper_bundle))
diff --git a/code/modules/paperwork/desk_bell.dm b/code/modules/paperwork/desk_bell.dm
index 78f6863a298..1dce3dadd41 100644
--- a/code/modules/paperwork/desk_bell.dm
+++ b/code/modules/paperwork/desk_bell.dm
@@ -35,7 +35,7 @@
return FALSE
var/mob/user = usr
- if(over_object != user || user.incapacitated() || !ishuman(user))
+ if(over_object != user || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !ishuman(user))
return FALSE
set_anchored(FALSE)
diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm
index 10280ad2c55..cc926a37bf3 100644
--- a/code/modules/paperwork/faxmachine.dm
+++ b/code/modules/paperwork/faxmachine.dm
@@ -290,7 +290,7 @@ GLOBAL_LIST_EMPTY(fax_blacklist)
set name = "Eject ID Card"
set src in oview(1)
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(scan)
diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm
index 9750f328a24..b59fe379d12 100644
--- a/code/modules/paperwork/folders.dm
+++ b/code/modules/paperwork/folders.dm
@@ -64,7 +64,7 @@
/obj/item/folder/Topic(href, href_list)
..()
- if((usr.stat || usr.restrained()))
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(src.loc == usr)
diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm
index 8ec78f84cb5..5e2fd0ff1e2 100644
--- a/code/modules/paperwork/paper.dm
+++ b/code/modules/paperwork/paper.dm
@@ -116,7 +116,7 @@
/obj/item/paper/AltClick(mob/living/carbon/human/user)
- if(!ishuman(user) || user.incapacitated() || !Adjacent(user))
+ if(!ishuman(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user))
return
if(is_pen(user.get_active_hand()))
rename(user)
@@ -362,7 +362,7 @@
/obj/item/paper/Topic(href, href_list)
..()
- if(!usr || (usr.stat || usr.restrained()))
+ if(!usr || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(href_list["auto_write"])
diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm
index b8001e18b8a..620a8796a69 100644
--- a/code/modules/paperwork/paper_bundle.dm
+++ b/code/modules/paperwork/paper_bundle.dm
@@ -113,7 +113,7 @@
if(resistance_flags & FIRE_PROOF)
return
- if(P.lit && !user.restrained())
+ if(P.lit && !user.incapacitated() && !HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
if(istype(P, /obj/item/lighter/zippo))
class = ""
diff --git a/code/modules/paperwork/papershredder.dm b/code/modules/paperwork/papershredder.dm
index af24101ecc5..f015826e485 100644
--- a/code/modules/paperwork/papershredder.dm
+++ b/code/modules/paperwork/papershredder.dm
@@ -65,7 +65,7 @@
set category = "Object"
set src in range(1)
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(!paperamount)
diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm
index 1dec141b45f..69cdb484e30 100644
--- a/code/modules/paperwork/photocopier.dm
+++ b/code/modules/paperwork/photocopier.dm
@@ -426,14 +426,14 @@
/obj/machinery/photocopier/MouseDrop_T(mob/target, mob/living/user, params)
check_ass() //Just to make sure that you can re-drag somebody onto it after they moved off.
- if(!istype(target) || target.buckled || get_dist(user, src) > 1 || get_dist(user, target) > 1 || user.stat || istype(user, /mob/living/silicon/ai) || target == ass)
+ if(!istype(target) || target.buckled || get_dist(user, src) > 1 || get_dist(user, target) > 1 || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || isAI(user) || target == ass)
return
add_fingerprint(user)
- if(target == user && !user.incapacitated())
+ if(target == user)
visible_message("[usr] jumps onto [src]!")
- else if(target != user && !user.restrained() && !user.stat && !user.IsWeakened() && !user.IsStunned() && !user.IsParalyzed())
- if(target.anchored) return
- if(!ishuman(user)) return
+ else if(target != user)
+ if(target.anchored || !ishuman(user))
+ return
visible_message("[usr] drags [target.name] onto [src]!")
target.forceMove(get_turf(src))
ass = target
diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm
index e98ff0c88a1..da7041d985d 100644
--- a/code/modules/paperwork/photography.dm
+++ b/code/modules/paperwork/photography.dm
@@ -53,7 +53,7 @@
/obj/item/photo/proc/burnphoto(obj/item/lighter/P, mob/user)
var/class = ""
- if(P.lit && !user.restrained())
+ if(P.lit && !user.incapacitated() && !HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
if(istype(P, /obj/item/lighter/zippo))
class = ""
@@ -105,12 +105,14 @@
set category = "Object"
set src in usr
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ return
+
var/n_name = sanitize(copytext_char(input(usr, "What would you like to label the photo?", "Photo Labelling", name) as text, 1, MAX_NAME_LEN))
//loc.loc check is for making possible renaming photos in clipboards
- if(( (loc == usr || (loc.loc && loc.loc == usr)) && usr.stat == 0))
+ if((loc == usr || (loc.loc && loc.loc == usr)) && !usr.incapacitated() && !HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
name = "[(n_name ? text("[n_name]") : "photo")]"
- add_fingerprint(usr)
- return
+ add_fingerprint(usr)
/**************
@@ -169,6 +171,10 @@ GLOBAL_LIST_INIT(SpookyGhosts, list("ghost","shade","shade2","ghost-narsie","hor
/obj/item/camera/verb/change_size()
set name = "Set Photo Focus"
set category = "Object"
+
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ return
+
var/nsize = tgui_input_list(usr, "Photo Size", "Pick a size of resulting photo.", list(1,3,5,7))
if(nsize)
size = nsize
diff --git a/code/modules/pda/PDA.dm b/code/modules/pda/PDA.dm
index 071dd979de6..41f37ea45fe 100755
--- a/code/modules/pda/PDA.dm
+++ b/code/modules/pda/PDA.dm
@@ -82,17 +82,16 @@ GLOBAL_LIST_EMPTY(PDAs)
new /obj/item/pen(src)
start_program(find_program(/datum/data/pda/app/main_menu))
-/obj/item/pda/proc/can_use()
- if(!ismob(loc))
- return 0
-
- var/mob/M = loc
- if(M.incapacitated(ignore_lying = TRUE))
- return 0
- if((src in M.contents) || ( istype(loc, /turf) && in_range(src, M) ))
- return 1
- else
- return 0
+
+/obj/item/pda/proc/can_use(mob/user)
+ if(loc != user)
+ return FALSE
+
+ if(user.incapacitated(ignore_lying = TRUE) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ return FALSE
+
+ return TRUE
+
/obj/item/pda/GetAccess()
if(id)
@@ -108,7 +107,7 @@ GLOBAL_LIST_EMPTY(PDAs)
. = ..()
var/mob/user = usr
- if(!ishuman(user) || !Adjacent(user) || user.incapacitated())
+ if(!ishuman(user) || !Adjacent(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return FALSE
attack_self(user)
@@ -166,10 +165,7 @@ GLOBAL_LIST_EMPTY(PDAs)
to_chat(usr, "You cannot do this while restrained.")
/obj/item/pda/AltClick(mob/living/user)
- if(issilicon(user))
- return
- if(!istype(user) || user.incapacitated())
- to_chat(user, "You can't do that right now!")
+ if(!iscarbon(user))
return
if(can_use(user))
if(id)
@@ -177,6 +173,7 @@ GLOBAL_LIST_EMPTY(PDAs)
else
to_chat(user, "This PDA does not have an ID in it!")
+
/obj/item/pda/CtrlClick(mob/user)
..()
if(issilicon(user))
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index f6dc531653f..07601bf243f 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -737,7 +737,7 @@
/obj/machinery/power/apc/AltClick(mob/user)
var/mob/living/carbon/human/human = user
- if(!istype(human))
+ if(!istype(human) || human.incapacitated() || HAS_TRAIT(human, TRAIT_HANDS_BLOCKED))
return
if(!Adjacent(human) || (get_turf(user) != user.loc))
@@ -752,7 +752,7 @@
/obj/machinery/power/apc/CtrlClick(mob/user)
SEND_SIGNAL(src, COMSIG_CLICK_CTRL, user)
- if(!can_use(usr) || (is_locked(usr)))
+ if(!can_use(user) || is_locked(user))
return
toggle_breaker(user)
@@ -1135,6 +1135,8 @@
var/mob/living/carbon/human/h_user = user
if(ishuman(h_user))
+ if(h_user.incapacitated() || HAS_TRAIT(h_user, TRAIT_HANDS_BLOCKED))
+ return FALSE
if(h_user.getBrainLoss() >= 60)
h_user.visible_message(span_danger("[h_user] stares cluelessly at [src] and drools."))
return FALSE
diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm
index 29b45878530..0fbc2745243 100644
--- a/code/modules/power/singularity/emitter.dm
+++ b/code/modules/power/singularity/emitter.dm
@@ -59,20 +59,23 @@
set category = "Object"
set src in oview(1)
- if(src.anchored || usr:stat)
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ to_chat(usr, "You can't do that right now!")
+ return FALSE
+
+ if(anchored)
to_chat(usr, "It is fastened to the floor!")
- return 0
+ return FALSE
+
add_fingerprint(usr)
- src.dir = turn(src.dir, 90)
- return 1
+ dir = turn(dir, 90)
+ return TRUE
+
/obj/machinery/power/emitter/AltClick(mob/user)
- if(user.incapacitated())
- to_chat(user, "You can't do that right now!")
- return
- if(!Adjacent(user))
- return
- rotate()
+ if(Adjacent(user))
+ rotate()
+
/obj/machinery/power/emitter/Destroy()
message_admins("Emitter deleted at [ADMIN_COORDJMP(src)] [usr ? "Broken by [ADMIN_LOOKUPFLW(usr)]" : ""]")
diff --git a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm
index 0b273823d6a..1017925916a 100644
--- a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm
+++ b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm
@@ -99,7 +99,7 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin
rotate_accelerator(user)
/obj/structure/particle_accelerator/proc/rotate_accelerator(mob/user)
- if(user.incapacitated() || user.restrained() || !Adjacent(user))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user))
return
if(anchored)
to_chat(user, "It is fastened to the floor!")
@@ -267,7 +267,7 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin
/obj/machinery/particle_accelerator/proc/rotate_accelerator(mob/user)
- if(user.incapacitated() || user.restrained() || !Adjacent(user))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user))
return
if(anchored)
to_chat(user, "It is fastened to the floor!")
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index ab305d28628..0efda007726 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -482,7 +482,7 @@
gun_light.set_light_on(FALSE)
update_icon(UPDATE_OVERLAYS)
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
/obj/item/gun/proc/clear_bayonet()
@@ -511,7 +511,7 @@
/obj/item/gun/AltClick(mob/user)
if(!unique_reskin || current_skin || loc != user)
return ..()
- if(user.incapacitated())
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
to_chat(user, span_warning("You can't do that right now!"))
return ..()
reskin_gun(user)
@@ -530,7 +530,7 @@
current_skin = skin_options[choice]
to_chat(user, "Your gun is now skinned as [choice]. Say hello to your new friend.")
update_icon()
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
/obj/item/gun/proc/reskin_radial_check(mob/living/carbon/human/user)
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index 1d42e218097..f9ff8db434a 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -246,8 +246,8 @@
/obj/item/gun/energy/update_icon(updates = ALL)
- ..()
- update_equipped_item()
+ . = ..()
+ update_equipped_item(update_speedmods = FALSE)
/obj/item/gun/energy/update_icon_state()
diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm
index b1077af3445..2f87d50647e 100644
--- a/code/modules/projectiles/guns/projectile/revolver.dm
+++ b/code/modules/projectiles/guns/projectile/revolver.dm
@@ -60,10 +60,9 @@
set name = "Spin Chamber"
set category = "Object"
set desc = "Click to spin your revolver's chamber."
+ set src in usr
- var/mob/M = usr
-
- if(M.stat || !in_range(M, src))
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(istype(magazine, /obj/item/ammo_box/magazine/internal/cylinder))
diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm
index 924f015f1eb..d4c08510ab6 100644
--- a/code/modules/projectiles/guns/projectile/shotgun.dm
+++ b/code/modules/projectiles/guns/projectile/shotgun.dm
@@ -356,7 +356,7 @@
/obj/item/gun/projectile/shotgun/automatic/dual_tube/AltClick(mob/living/user)
. = ..()
- if(user.incapacitated() || !Adjacent(user) || !istype(user))
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user) || !istype(user))
return
pump()
diff --git a/code/modules/projectiles/guns/throw/crossbow.dm b/code/modules/projectiles/guns/throw/crossbow.dm
index 2d66f7a7c60..5915f7ea066 100644
--- a/code/modules/projectiles/guns/throw/crossbow.dm
+++ b/code/modules/projectiles/guns/throw/crossbow.dm
@@ -61,6 +61,8 @@
. += span_notice("\A [cell] is mounted onto [src]. Battery cell charge: [cell.charge]/[cell.maxcharge]")
else
. += span_notice("It has an empty mount for a battery cell.")
+ if(src in user)
+ . += span_info("You can Alt-Click to change the draw tension.")
/obj/item/gun/throw/crossbow/modify_projectile(obj/item/I, on_chamber = 0)
if(cell && on_chamber && istype(I, /obj/item/arrow/rod))
@@ -137,16 +139,21 @@
to_chat(user, span_notice("You jimmy [cell] out of [src] with [I]."))
cell = null
+
+/obj/item/gun/throw/crossbow/AltClick(mob/user)
+ if(src in user)
+ set_tension()
+
+
/obj/item/gun/throw/crossbow/verb/set_tension()
set name = "Adjust Tension"
set category = "Object"
- set src in range(0)
+ set src in usr
- var/mob/user = usr
- if(user.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
var/choice = input("Select tension to draw to:", "[src]", XBOW_TENSION_FULL) as null|anything in possible_tensions
- if(!choice)
+ if(!choice || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
switch(choice)
@@ -161,10 +168,15 @@
if(XBOW_TENSION_FULL)
drawtension = maxtension
+ to_chat(usr, span_notice("You set the draw tension to [choice]."))
+
+
/obj/item/gun/throw/crossbow/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override)
..()
tension = 0
update_icon()
+
+
/obj/item/gun/throw/crossbow/french
name = "french powered crossbow"
icon_state = "fcrossbow"
diff --git a/code/modules/reagents/chemistry/machinery/chem_heater.dm b/code/modules/reagents/chemistry/machinery/chem_heater.dm
index c63bbea8df8..84a297ca76e 100644
--- a/code/modules/reagents/chemistry/machinery/chem_heater.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_heater.dm
@@ -132,7 +132,7 @@
add_fingerprint(usr)
/obj/machinery/chem_heater/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
- if(user.stat || user.restrained())
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
diff --git a/code/modules/reagents/chemistry/reagents/drugs.dm b/code/modules/reagents/chemistry/reagents/drugs.dm
index dd4f963ba39..a54a678a813 100644
--- a/code/modules/reagents/chemistry/reagents/drugs.dm
+++ b/code/modules/reagents/chemistry/reagents/drugs.dm
@@ -8,7 +8,7 @@
/datum/reagent/lithium/on_mob_life(mob/living/M)
if(isturf(M.loc) && !isspaceturf(M.loc))
- if(M.canmove && !M.restrained())
+ if(M.canmove && !HAS_TRAIT(M, TRAIT_RESTRAINED))
step(M, pick(GLOB.cardinal))
if(prob(5))
M.emote(pick("twitch","drool","moan"))
@@ -45,7 +45,7 @@
var/update_flags = STATUS_UPDATE_NONE
M.Druggy(30 SECONDS)
if(isturf(M.loc) && !isspaceturf(M.loc))
- if(M.canmove && !M.restrained())
+ if(M.canmove && !HAS_TRAIT(M, TRAIT_RESTRAINED))
step(M, pick(GLOB.cardinal))
if(prob(7))
M.emote(pick("twitch","drool","moan","giggle"))
diff --git a/code/modules/reagents/chemistry/reagents/misc.dm b/code/modules/reagents/chemistry/reagents/misc.dm
index a90b89015e5..73b50c5eed2 100644
--- a/code/modules/reagents/chemistry/reagents/misc.dm
+++ b/code/modules/reagents/chemistry/reagents/misc.dm
@@ -424,7 +424,7 @@
var/lovely_phrase = pick("appreciated", "loved", "pretty good", "really nice", "pretty happy with yourself, even though things haven't always gone as well as they could")
to_chat(M, "You feel [lovely_phrase].")
- else if(!M.restrained())
+ else if(!M.incapacitated() && !HAS_TRAIT(M, TRAIT_HANDS_BLOCKED))
for(var/mob/living/carbon/C in orange(1, M))
if(C)
if(C == M)
diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm
index d00a4e0c6a4..4b644418cd1 100644
--- a/code/modules/reagents/reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers.dm
@@ -21,7 +21,7 @@
set category = "Object"
set src in usr
- if(!usr.Adjacent(src) || !(ishuman(usr) || isrobot(usr)) || usr.incapacitated())
+ if(!ishuman(usr) || !isrobot(usr) || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
var/default = null
if(amount_per_transfer_from_this in possible_transfer_amounts)
@@ -30,19 +30,20 @@
if(!N)
return
- if(!usr.Adjacent(src))
+ if(!Adjacent(usr))
to_chat(usr, "You have moved too far away!")
return
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
to_chat(usr, "You can't use your hands!")
return
amount_per_transfer_from_this = N
to_chat(usr, "[src] will now transfer [N] units at a time.")
-/obj/item/reagent_containers/AltClick()
- set_APTFT()
+/obj/item/reagent_containers/AltClick(mob/user)
+ if(Adjacent(user))
+ set_APTFT()
/obj/item/reagent_containers/verb/empty()
@@ -50,11 +51,11 @@
set category = "Object"
set src in usr
- if(!usr.Adjacent(src) || usr.stat || !usr.canmove || usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(alert(usr, "Are you sure you want to empty that?", "Empty Container:", "Yes", "No") != "Yes")
return
- if(!usr.Adjacent(src) || usr.stat || !usr.canmove || usr.incapacitated())
+ if(!usr.Adjacent(src) || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(isturf(usr.loc) && loc == usr)
if(!is_open_container() && !pass_open_check)
diff --git a/code/modules/reagents/reagent_containers/glass_containers.dm b/code/modules/reagents/reagent_containers/glass_containers.dm
index c73ce6e12c7..3704510dde1 100644
--- a/code/modules/reagents/reagent_containers/glass_containers.dm
+++ b/code/modules/reagents/reagent_containers/glass_containers.dm
@@ -184,7 +184,7 @@
set name = "Remove Assembly"
set category = "Object"
set src in usr
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(assembly)
to_chat(usr, "You detach [assembly] from [src]")
diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm
index c400d8ebcf8..e555de77921 100644
--- a/code/modules/reagents/reagent_containers/syringes.dm
+++ b/code/modules/reagents/reagent_containers/syringes.dm
@@ -175,7 +175,7 @@
if(SYRINGE_INJECT)
injoverlay = "inject"
. += injoverlay
- update_equipped_item()
+ update_equipped_item(update_speedmods = FALSE)
/obj/item/reagent_containers/syringe/antiviral
diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm
index ef0728199a8..d7a8a37d056 100644
--- a/code/modules/recycling/disposal.dm
+++ b/code/modules/recycling/disposal.dm
@@ -224,7 +224,7 @@
// mouse drop another mob or self
//
/obj/machinery/disposal/MouseDrop_T(mob/living/target, mob/living/user, params)
- if(!istype(target) || target.buckled || target.has_buckled_mobs() || !in_range(user, src) || !in_range(user, target) || user.incapacitated() || isAI(user))
+ if(!istype(target) || target.buckled || target.has_buckled_mobs() || !in_range(user, src) || !in_range(user, target) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || isAI(user))
return
if(isanimal(user) && target != user)
return //animals cannot put mobs other than themselves into disposal
@@ -251,7 +251,7 @@
// must be awake, not stunned or whatever
msg = "[user.name] climbs into [src]."
to_chat(user, "You climb into [src].")
- else if(target != user && !user.restrained() && !user.incapacitated())
+ else if(target != user && !user.incapacitated() && !HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
msg = "[user.name] stuffs [target.name] into [src]!"
to_chat(user, "You stuff [target.name] into [src]!")
if(!iscarbon(user))
@@ -377,7 +377,7 @@
/obj/machinery/disposal/AltClick(mob/user)
- if(!Adjacent(user) || !ishuman(user) || user.incapacitated())
+ if(!Adjacent(user) || !ishuman(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return ..()
user.visible_message(
"[user] tries to eject the contents of [src] manually.",
diff --git a/code/modules/recycling/disposal/construction.dm b/code/modules/recycling/disposal/construction.dm
index 98c987e3b68..ae7fde6ddef 100644
--- a/code/modules/recycling/disposal/construction.dm
+++ b/code/modules/recycling/disposal/construction.dm
@@ -91,7 +91,8 @@
set name = "Rotate Pipe"
set src in view(1)
- if(usr.stat)
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ to_chat(usr, "You can't do that right now!")
return
if(anchored)
@@ -103,12 +104,8 @@
update()
/obj/structure/disposalconstruct/AltClick(mob/user)
- if(user.incapacitated())
- to_chat(user, "You can't do that right now!")
- return
- if(!Adjacent(user))
- return
- rotate()
+ if(Adjacent(user))
+ rotate()
/obj/structure/disposalconstruct/verb/flip()
set category = "Object"
diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm
index ac5ea7f90eb..d4afdfa3e3a 100644
--- a/code/modules/research/xenobiology/xenobiology.dm
+++ b/code/modules/research/xenobiology/xenobiology.dm
@@ -127,7 +127,7 @@
origin_tech = "biotech=4"
/obj/item/slimepotion/afterattack(obj/item/reagent_containers/target, mob/user, proximity_flag)
- if(!proximity_flag)
+ if(!proximity_flag || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(istype(target))
to_chat(user, "You cannot transfer [src] to [target]! It appears the potion must be given directly to a slime to absorb.") // le fluff faec
@@ -181,7 +181,7 @@
var/sentience_type = SENTIENCE_ORGANIC
/obj/item/slimepotion/sentience/afterattack(mob/living/M, mob/user, proximity_flag)
- if(!proximity_flag)
+ if(!proximity_flag || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(being_used || !ismob(M))
return
@@ -354,7 +354,7 @@
var/animal_type = SENTIENCE_ORGANIC
/obj/item/slimepotion/transference/afterattack(mob/living/M, mob/user, proximity_flag)
- if(!proximity_flag)
+ if(!proximity_flag || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(prompted || !ismob(M))
return
@@ -482,7 +482,7 @@
origin_tech = "biotech=5"
/obj/item/slimepotion/speed/afterattack(obj/O, mob/user, proximity_flag, drop = FALSE)
- if(!proximity_flag)
+ if(!proximity_flag || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
..()
if(!istype(O))
@@ -526,11 +526,10 @@
if(istype(over_object, /obj/screen))
return FALSE
- if(over_object == user || loc != user || user.incapacitated() || !ishuman(user))
+ if(over_object == user || loc != user || !ishuman(user))
return FALSE
afterattack(over_object, user, TRUE, drop = TRUE)
- return TRUE
/obj/item/slimepotion/clothing
@@ -556,7 +555,7 @@
C.armor = C.armor.detachArmor(armor)
/obj/item/slimepotion/clothing/afterattack(obj/item/clothing/C, mob/user, proximity_flag)
- if(!proximity_flag)
+ if(!proximity_flag || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(!uses)
qdel(src)
@@ -593,7 +592,7 @@
if(istype(over_object, /obj/screen))
return FALSE
- if(over_object == user || loc != user || user.incapacitated() || !ishuman(user))
+ if(over_object == user || loc != user || !ishuman(user))
return FALSE
afterattack(over_object, user, TRUE)
diff --git a/code/modules/spacepods/parts.dm b/code/modules/spacepods/parts.dm
index df8fb9440e3..c04cb29483e 100644
--- a/code/modules/spacepods/parts.dm
+++ b/code/modules/spacepods/parts.dm
@@ -55,7 +55,7 @@
return 0
return connectedparts
-/obj/item/pod_parts/pod_frame/attackby(var/obj/item/O, mob/user)
+/obj/item/pod_parts/pod_frame/attackby(obj/item/O, mob/user)
if(istype(O, /obj/item/stack/rods))
var/obj/item/stack/rods/R = O
var/list/linkedparts = find_square()
@@ -80,18 +80,36 @@
set_density(anchored)
playsound(get_turf(src), O.usesound, 50, 1)
+
+/obj/item/pod_parts/pod_frame/examine(mob/user)
+ . = ..()
+ . += span_info("Alt-Click to rotate it.")
+
+
/obj/item/pod_parts/pod_frame/verb/rotate()
set name = "Rotate Frame"
set category = "Object"
set src in oview(1)
+
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
+ return FALSE
+
if(anchored)
to_chat(usr, "\The [src] is securely bolted!")
- return 0
- src.dir = turn(src.dir, -90)
- return 1
+ return FALSE
+
+ dir = turn(dir, -90)
+ return TRUE
+
+
+/obj/item/pod_parts/pod_frame/AltClick(mob/user)
+ if(Adjacent(user))
+ rotate()
+
/obj/item/pod_parts/pod_frame/attack_hand()
- src.rotate()
+ return
+
/obj/item/pod_parts/pod_frame/fore_port
name = "fore port pod frame"
diff --git a/code/modules/spacepods/spacepod.dm b/code/modules/spacepods/spacepod.dm
index 83c37ff43f1..732cf82b347 100644
--- a/code/modules/spacepods/spacepod.dm
+++ b/code/modules/spacepods/spacepod.dm
@@ -666,7 +666,7 @@
set src = usr.loc
set popup_menu = 0
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(usr != src.pilot)
@@ -733,82 +733,80 @@
playsound(src, 'sound/machines/windowdoor.ogg', 50, 1)
return 1
-/obj/spacepod/MouseDrop_T(atom/A, mob/user, params)
- if(user == pilot || (user in passengers))
- return
-
- if(istype(A,/mob))
- var/mob/M = A
- if(!isliving(M))
- return
+/obj/spacepod/MouseDrop_T(mob/living/dropping, mob/living/user, params)
+ if(user == pilot || (user in passengers) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ return FALSE
+ . = TRUE
+ if(isliving(dropping))
occupant_sanity_check()
- if(M != user && unlocked && (M.stat == DEAD || M.incapacitated()))
+ if(dropping != user && unlocked && (dropping.stat == DEAD || dropping.incapacitated()))
if(passengers.len >= max_passengers && !pilot)
- to_chat(usr, "That person can't fly the pod!")
- return 0
+ to_chat(user, "That person can't fly the pod!")
+ return .
if(passengers.len < max_passengers)
- visible_message("[user.name] starts loading [M.name] into the pod!")
- if(do_after(user, 5 SECONDS, M))
- moved_other_inside(M)
- return
+ visible_message("[user.name] starts loading [dropping.name] into the pod!")
+ if(do_after(user, 5 SECONDS, dropping))
+ moved_other_inside(dropping)
+ return .
- if(M == user)
+ if(dropping == user)
enter_pod(user)
- return
- if(istype(A, /obj/structure/ore_box) && equipment_system.cargo_system && istype(equipment_system.cargo_system,/obj/item/spacepod_equipment/cargo/ore)) // For loading ore boxes
- load_cargo(user, A)
- return
+ else if(isobj(dropping))
+ load_cargo(user, dropping)
- if(istype(A, /obj/structure/closet/crate) && equipment_system.cargo_system && istype(equipment_system.cargo_system, /obj/item/spacepod_equipment/cargo/crate)) // For loading crates
- load_cargo(user, A)
-/obj/spacepod/proc/load_cargo(mob/user, var/obj/O)
- var/obj/item/spacepod_equipment/cargo/ore/C = equipment_system.cargo_system
- if(!C.storage)
- to_chat(user, "You begin loading [O] into [src]'s [equipment_system.cargo_system]")
+/obj/spacepod/proc/load_cargo(mob/user, obj/object)
+ var/obj/item/spacepod_equipment/cargo/cargo = equipment_system.cargo_system
+ if(!cargo)
+ return
+ var/valid_cargo = FALSE
+ if(istype(cargo, /obj/item/spacepod_equipment/cargo/ore))
+ if(istype(object, /obj/structure/ore_box))
+ valid_cargo = TRUE
+ else if(istype(cargo, /obj/item/spacepod_equipment/cargo/crate))
+ if(istype(object, /obj/structure/closet/crate))
+ valid_cargo = TRUE
+ if(!valid_cargo)
+ return
+ if(!cargo.storage)
+ to_chat(user, "You begin loading [object] into [src]'s [cargo]")
if(do_after(user, 4 SECONDS, src))
- C.storage = O
- O.forceMove(C)
- to_chat(user, "You load [O] into [src]'s [equipment_system.cargo_system]!")
+ cargo.storage = object
+ object.forceMove(cargo)
+ to_chat(user, "You load [object] into [src]'s [cargo]!")
else
- to_chat(user, "You fail to load [O] into [src]'s [equipment_system.cargo_system]")
+ to_chat(user, "You fail to load [object] into [src]'s [cargo]")
else
- to_chat(user, "[src] already has \an [C.storage]")
+ to_chat(user, "[src] already has \an [cargo.storage]")
+
/obj/spacepod/proc/enter_pod(mob/user)
- if(usr.stat != CONSCIOUS)
- return 0
+ if(!ishuman(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ return FALSE
if(equipment_system.lock_system && !unlocked)
to_chat(user, "[src]'s doors are locked!")
- return 0
-
- if(get_dist(src, user) > 2 || get_dist(usr, user) > 1)
- to_chat(usr, "They are too far away to put inside")
- return 0
+ return FALSE
- if(!istype(user))
- return 0
+ if(get_dist(src, user) > 2)
+ to_chat(user, "They are too far away to put inside")
+ return FALSE
var/fukkendisk = user.GetTypeInAllContents(/obj/item/disk/nuclear)
-
- if(user.incapacitated()) //are you cuffed, dying, lying, stunned or other
- return 0
- if(!ishuman(user))
- return 0
-
if(fukkendisk)
to_chat(user, "The nuke-disk is locking the door every time you try to open it. You get the feeling that it doesn't want to go into the spacepod.")
- return 0
+ return FALSE
if(user.has_buckled_mobs()) //mob attached to us
to_chat(user, "[user] will not fit into [src] because [user.p_they()] [user.p_have()] creatures attached to [user.p_them()]!")
- return
+ return FALSE
move_inside(user)
+ return TRUE
+
/obj/spacepod/proc/move_inside(mob/living/user)
if(!istype(user))
@@ -861,35 +859,31 @@
set category = "Spacepod"
set src = usr.loc
- var/mob/user = usr
- if(!istype(user))
- return
-
if(usr.stat != CONSCIOUS) // unconscious people can't let themselves out
return
occupant_sanity_check()
- if(usr.restrained())
+ if(HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
to_chat(usr, "You attempt to stumble out of the [src]. This will take two minutes.")
- if(pilot)
+ if(pilot && pilot != usr)
to_chat(pilot, "[usr] is trying to escape the [src].")
if(!do_after(usr, 2 MINUTES, src))
return
- if(user == pilot)
+ if(usr == pilot)
eject_pilot()
- to_chat(user, "You climb out of [src].")
- else if(user in passengers)
- eject_passenger(user)
- to_chat(user, "You climb out of [src].")
+ to_chat(usr, "You climb out of [src].")
+ else if(usr in passengers)
+ eject_passenger(usr)
+ to_chat(usr, "You climb out of [src].")
/obj/spacepod/verb/lock_pod()
set name = "Lock Doors"
set category = "Spacepod"
set src = usr.loc
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(usr in passengers && usr != src.pilot)
@@ -909,7 +903,7 @@
set category = "Spacepod"
set src = usr.loc
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(usr != src.pilot)
@@ -944,7 +938,7 @@
set category = "Spacepod"
set src = usr.loc
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(usr != src.pilot)
@@ -961,7 +955,7 @@
set category = "Spacepod"
set src = usr.loc
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(usr != src.pilot)
@@ -977,7 +971,7 @@
set category = "Spacepod"
set src = usr.loc
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(usr != src.pilot)
@@ -1001,7 +995,7 @@
set src = usr.loc
var/mob/user = usr
- if(usr.incapacitated())
+ if(usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
to_chat(user, "You start rooting around under the seat for lost items")
@@ -1020,17 +1014,6 @@
else
to_chat(user, "You decide against searching the [src]")
-/obj/spacepod/proc/enter_after(delay as num, var/mob/user as mob, var/numticks = 5)
- var/delayfraction = delay/numticks
-
- var/turf/T = user.loc
-
- for(var/i = 0, iYou can't do that right now!")
return
toggle_gps(user)
@@ -129,7 +129,7 @@ GLOBAL_LIST_EMPTY(GPS_list)
. = ..()
var/mob/user = usr
- if(!ishuman(user) || !Adjacent(user) || user.incapacitated())
+ if(!ishuman(user) || !Adjacent(user) || user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return FALSE
attack_self(user)
diff --git a/code/modules/tgui/modules/item_pixel_shift.dm b/code/modules/tgui/modules/item_pixel_shift.dm
index 894ef8f646a..5f8b106923c 100644
--- a/code/modules/tgui/modules/item_pixel_shift.dm
+++ b/code/modules/tgui/modules/item_pixel_shift.dm
@@ -3,7 +3,7 @@
set category = null
set src in oview(1)
- if(!isturf(src.loc) || usr.incapacitated() || src.anchored || src.density)
+ if(!isturf(src.loc) || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || src.anchored || src.density)
return
if(!item_pixel_shift)
diff --git a/code/modules/vehicle/ambulance.dm b/code/modules/vehicle/ambulance.dm
index 4b0c4773bfd..2903d6efcc4 100644
--- a/code/modules/vehicle/ambulance.dm
+++ b/code/modules/vehicle/ambulance.dm
@@ -118,7 +118,7 @@
/obj/structure/bed/amb_trolley/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params)
. = ..()
- if(!. || !istype(over_object, /obj/vehicle/ambulance))
+ if(!istype(over_object, /obj/vehicle/ambulance) || usr.incapacitated() || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return FALSE
var/obj/vehicle/ambulance/amb = over_object
diff --git a/code/modules/vehicle/vehicle.dm b/code/modules/vehicle/vehicle.dm
index 38cd22f5fce..eb459a39d97 100644
--- a/code/modules/vehicle/vehicle.dm
+++ b/code/modules/vehicle/vehicle.dm
@@ -65,7 +65,9 @@
return ..()
/obj/vehicle/AltClick(mob/living/user)
- if(!istype(user) || user.incapacitated())
+ if(!istype(user))
+ return
+ if(user.incapacitated() || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
to_chat(user, "You can't do that right now!")
return
if(inserted_key && user.Adjacent(user))