From 353e9371668ec015835eba90ddd7773930f9445b Mon Sep 17 00:00:00 2001
From: ATH1909 <42606352+ATH1909@users.noreply.github.com>
Date: Mon, 21 Sep 2020 16:59:15 -0500
Subject: [PATCH 01/13] shapeshift at will
---
code/modules/antagonists/morph/morph.dm | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/code/modules/antagonists/morph/morph.dm b/code/modules/antagonists/morph/morph.dm
index f2afc164eb1..f98068ae37c 100644
--- a/code/modules/antagonists/morph/morph.dm
+++ b/code/modules/antagonists/morph/morph.dm
@@ -1,5 +1,3 @@
-#define MORPH_COOLDOWN 50
-
/mob/living/simple_animal/hostile/morph
name = "morph"
real_name = "morph"
@@ -37,7 +35,6 @@
var/melee_damage_disguised = 0
var/eat_while_disguised = FALSE
var/atom/movable/form = null
- var/morph_time = 0
var/static/list/blacklist_typecache = typecacheof(list(
/obj/screen,
/obj/singularity,
@@ -87,7 +84,7 @@
return FALSE
/mob/living/simple_animal/hostile/morph/ShiftClickOn(atom/movable/A)
- if(morph_time <= world.time && !stat)
+ if(!stat)
if(A == src)
restore()
return
@@ -118,7 +115,6 @@
melee_damage_upper = melee_damage_disguised
set_varspeed(0)
- morph_time = world.time + MORPH_COOLDOWN
med_hud_set_health()
med_hud_set_status() //we're an object honest
return
@@ -147,7 +143,6 @@
melee_damage_upper = initial(melee_damage_upper)
set_varspeed(initial(speed))
- morph_time = world.time + MORPH_COOLDOWN
med_hud_set_health()
med_hud_set_status() //we are not an object
From f01fc650de664841e1043233d5f5fd25c1998643 Mon Sep 17 00:00:00 2001
From: ATH1909 <42606352+ATH1909@users.noreply.github.com>
Date: Mon, 21 Sep 2020 17:12:57 -0500
Subject: [PATCH 02/13] testing, testing...
---
code/modules/antagonists/morph/morph.dm | 3 ---
1 file changed, 3 deletions(-)
diff --git a/code/modules/antagonists/morph/morph.dm b/code/modules/antagonists/morph/morph.dm
index f98068ae37c..df34b2fe889 100644
--- a/code/modules/antagonists/morph/morph.dm
+++ b/code/modules/antagonists/morph/morph.dm
@@ -95,9 +95,6 @@
..()
/mob/living/simple_animal/hostile/morph/proc/assume(atom/movable/target)
- if(morphed)
- to_chat(src, "You must restore to your original form first!")
- return
morphed = TRUE
form = target
From 8d7c8e1911cc95ce47d2f1e6419a7b2c051f17c7 Mon Sep 17 00:00:00 2001
From: ATH1909 <42606352+ATH1909@users.noreply.github.com>
Date: Mon, 21 Sep 2020 17:18:32 -0500
Subject: [PATCH 03/13] playstyle string update
---
code/modules/antagonists/morph/morph.dm | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/code/modules/antagonists/morph/morph.dm b/code/modules/antagonists/morph/morph.dm
index df34b2fe889..3b7b45d3056 100644
--- a/code/modules/antagonists/morph/morph.dm
+++ b/code/modules/antagonists/morph/morph.dm
@@ -42,9 +42,9 @@
/obj/effect))
var/playstyle_string = "You are a morph, an abomination of science created primarily with changeling cells. \
- You may take the form of anything nearby by shift-clicking it. This process will alert any nearby \
- observers, and can only be performed once every five seconds. While morphed, you move faster, but do \
- less damage. In addition, anyone within three tiles will note an uncanny wrongness if examining you. \
+ You may take the form of anything you can see by shift-clicking it. This process will alert any nearby \
+ observers. While morphed, you move faster, but deal [melee_damage_disguised <= 0 ? "no" : "less"] damage to living creatures.\
+ In addition, anyone within three tiles will note an uncanny wrongness if examining you. \
You can attack any item or dead creature to consume it - creatures will restore your health. \
Finally, you can restore yourself to your original form while morphed by shift-clicking yourself."
From e2586bf8a8bc2cb9fbb5ff42e7180cf55bb551ce Mon Sep 17 00:00:00 2001
From: ATH1909 <42606352+ATH1909@users.noreply.github.com>
Date: Mon, 21 Sep 2020 17:22:59 -0500
Subject: [PATCH 04/13] oops
---
code/modules/antagonists/morph/morph.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/antagonists/morph/morph.dm b/code/modules/antagonists/morph/morph.dm
index 3b7b45d3056..8c4681f88a8 100644
--- a/code/modules/antagonists/morph/morph.dm
+++ b/code/modules/antagonists/morph/morph.dm
@@ -43,7 +43,7 @@
var/playstyle_string = "You are a morph, an abomination of science created primarily with changeling cells. \
You may take the form of anything you can see by shift-clicking it. This process will alert any nearby \
- observers. While morphed, you move faster, but deal [melee_damage_disguised <= 0 ? "no" : "less"] damage to living creatures.\
+ observers. While morphed, you move faster, but deal no damage to living creatures.\
In addition, anyone within three tiles will note an uncanny wrongness if examining you. \
You can attack any item or dead creature to consume it - creatures will restore your health. \
Finally, you can restore yourself to your original form while morphed by shift-clicking yourself."
From e00d5a9f6fdb5b5f26542cbd587fd247f8bfc2b9 Mon Sep 17 00:00:00 2001
From: ATH1909 <42606352+ATH1909@users.noreply.github.com>
Date: Mon, 21 Sep 2020 18:02:04 -0500
Subject: [PATCH 05/13] now morphs get a helpful paragraph!
---
code/modules/antagonists/morph/morph.dm | 12 ++----------
code/modules/antagonists/morph/morph_antag.dm | 12 +++++++++++-
2 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/code/modules/antagonists/morph/morph.dm b/code/modules/antagonists/morph/morph.dm
index 8c4681f88a8..f4c9d408c6f 100644
--- a/code/modules/antagonists/morph/morph.dm
+++ b/code/modules/antagonists/morph/morph.dm
@@ -41,13 +41,6 @@
/mob/living/simple_animal/hostile/morph,
/obj/effect))
- var/playstyle_string = "You are a morph, an abomination of science created primarily with changeling cells. \
- You may take the form of anything you can see by shift-clicking it. This process will alert any nearby \
- observers. While morphed, you move faster, but deal no damage to living creatures.\
- In addition, anyone within three tiles will note an uncanny wrongness if examining you. \
- You can attack any item or dead creature to consume it - creatures will restore your health. \
- Finally, you can restore yourself to your original form while morphed by shift-clicking yourself."
-
/mob/living/simple_animal/hostile/morph/examine(mob/user)
if(morphed)
. = form.examine(user)
@@ -75,7 +68,7 @@
/mob/living/simple_animal/hostile/morph/proc/eat(atom/movable/A)
if(morphed && !eat_while_disguised)
- to_chat(src, "You can not eat anything while you are disguised!")
+ to_chat(src, "You cannot eat anything while you are disguised!")
return FALSE
if(A && A.loc != src)
visible_message("[src] swallows [A] whole!")
@@ -91,7 +84,7 @@
if(istype(A) && allowed(A))
assume(A)
else
- to_chat(src, "Your chameleon skin is still repairing itself!")
+ to_chat(src, "You need to be conscious to transform!")
..()
/mob/living/simple_animal/hostile/morph/proc/assume(atom/movable/target)
@@ -230,7 +223,6 @@
player_mind.assigned_role = "Morph"
player_mind.special_role = "Morph"
player_mind.add_antag_datum(/datum/antagonist/morph)
- to_chat(S, S.playstyle_string)
SEND_SOUND(S, sound('sound/magic/mutate.ogg'))
message_admins("[ADMIN_LOOKUPFLW(S)] has been made into a morph by an event.")
log_game("[key_name(S)] was spawned as a morph by an event.")
diff --git a/code/modules/antagonists/morph/morph_antag.dm b/code/modules/antagonists/morph/morph_antag.dm
index 7b0491e5de5..969374fdaae 100644
--- a/code/modules/antagonists/morph/morph_antag.dm
+++ b/code/modules/antagonists/morph/morph_antag.dm
@@ -2,5 +2,15 @@
name = "Morph"
show_name_in_check_antagonists = TRUE
show_in_antagpanel = FALSE
+ var/playstyle_string = "You are a morph, a shapeshifting abomination that can eat almost anything. \
+ You may take the form of anything you can see by shift-clicking it. This process will alert any nearby \
+ observers. While morphed, you move faster, but are unable to attack creatures or eat anything.\
+ In addition, anyone within three tiles will note an uncanny wrongness if examining you. \
+ You can attack any item or dead creature to consume it - creatures will restore your health. \
+ Finally, you can restore yourself to your original form while morphed by shift-clicking yourself."
+
+/datum/antagonist/morph/on_gain()
+ to_chat(owner.current, playstyle_string)
+ antag_memory += playstyle_string
+ ..()
-//It does nothing! (Besides tracking)
From 8d9abae0a131623ae09a95fe755b83c438434dc9 Mon Sep 17 00:00:00 2001
From: MIC
Date: Sun, 27 Sep 2020 21:30:15 +0200
Subject: [PATCH 06/13] Fixes supermatter shutters on pubby
Fixes supermatter shutters on pubby having the wrong ID, which made them not work.
---
_maps/map_files/PubbyStation/PubbyStation.dmm | 22 +++++++++----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm
index bd295302d22..bbcc89108d9 100644
--- a/_maps/map_files/PubbyStation/PubbyStation.dmm
+++ b/_maps/map_files/PubbyStation/PubbyStation.dmm
@@ -5570,8 +5570,8 @@
pixel_x = -32
},
/obj/structure/cable,
-/mob/living/simple_animal/pet/dog/pug/mcgriff,
/obj/structure/bed/dogbed/mcgriff,
+/mob/living/simple_animal/pet/dog/pug/mcgriff,
/turf/open/floor/plasteel/showroomfloor,
/area/security/warden)
"aoq" = (
@@ -29208,13 +29208,13 @@
/obj/machinery/door/window/eastleft{
name = "Petting Garden"
},
-/mob/living/simple_animal/pet/dog/corgi/puppy,
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer4{
dir = 5
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer2{
dir = 8
},
+/mob/living/simple_animal/pet/dog/corgi/puppy,
/turf/open/floor/grass,
/area/medical/medbay/zone2)
"bzG" = (
@@ -32067,8 +32067,8 @@
/obj/machinery/light{
dir = 1
},
-/mob/living/carbon/monkey,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
+/mob/living/carbon/monkey,
/turf/open/floor/plasteel/freezer,
/area/medical/virology)
"bFL" = (
@@ -32614,8 +32614,8 @@
/area/medical/virology)
"bGP" = (
/obj/structure/window/reinforced,
-/mob/living/carbon/monkey,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
+/mob/living/carbon/monkey,
/turf/open/floor/plasteel/freezer,
/area/medical/virology)
"bGQ" = (
@@ -49388,10 +49388,10 @@
/turf/open/floor/plating,
/area/maintenance/department/chapel/monastery)
"gOV" = (
-/mob/living/carbon/monkey,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 8
},
+/mob/living/carbon/monkey,
/turf/open/floor/grass,
/area/science/genetics)
"gPV" = (
@@ -51439,8 +51439,8 @@
/turf/open/floor/plasteel/dark,
/area/library/artgallery)
"kHO" = (
-/mob/living/simple_animal/pet/fox/renault,
/obj/structure/bed/dogbed/renault,
+/mob/living/simple_animal/pet/fox/renault,
/turf/open/floor/plasteel/dark,
/area/crew_quarters/heads/captain)
"kHP" = (
@@ -51752,11 +51752,11 @@
/obj/structure/window/reinforced{
dir = 1
},
-/mob/living/simple_animal/butterfly,
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer2{
dir = 5
},
+/mob/living/simple_animal/butterfly,
/turf/open/floor/grass,
/area/science/genetics)
"lhu" = (
@@ -51934,7 +51934,7 @@
/obj/item/wrench,
/obj/structure/cable,
/obj/machinery/door/poddoor/shutters/radiation/preopen{
- id = "supermatter";
+ id = "Supermatter";
name = "supermatter shielding"
},
/turf/open/floor/plating,
@@ -52838,7 +52838,7 @@
"nmp" = (
/obj/structure/cable,
/obj/machinery/door/poddoor/shutters/radiation/preopen{
- id = "supermatter";
+ id = "Supermatter";
name = "supermatter shielding"
},
/turf/open/floor/plating,
@@ -53813,7 +53813,7 @@
"oEN" = (
/obj/effect/landmark/event_spawn,
/obj/machinery/door/poddoor/shutters/radiation/preopen{
- id = "supermatter";
+ id = "Supermatter";
name = "supermatter shielding"
},
/turf/open/floor/plating,
@@ -56247,7 +56247,7 @@
/area/science/xenobiology)
"tbC" = (
/obj/machinery/door/poddoor/shutters/radiation/preopen{
- id = "supermatter";
+ id = "Supermatter";
name = "supermatter shielding"
},
/turf/open/floor/plating,
From dab8fb8b6b9648f989ed00ca21a02be047b2c747 Mon Sep 17 00:00:00 2001
From: Timberpoes
Date: Tue, 29 Sep 2020 10:54:32 +0100
Subject: [PATCH 07/13] Airlock painter runtime fix (#53742)
Painting airlocks creates a new airlock in nullspace or something. Somewhere that doesn't have an area. Doors get their wire layout from the area they're built in. Do the math. The answer is null.
There's no getting around this as a concept. At some point a door is going to built where there's no area. Wire assignment logic made more robust. If there's no area or wire assignments available, it just returns a generic door wire assignment.
---
code/game/machinery/doors/airlock.dm | 25 +++++++++++--------------
1 file changed, 11 insertions(+), 14 deletions(-)
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 23d6dfe9bb8..bb0517353b4 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -1210,22 +1210,19 @@
return
var/airlock_type = painter.available_paint_jobs["[current_paintjob]"] // get the airlock type path associated with the airlock name the user just chose
- var/obj/machinery/door/airlock/airlock = new airlock_type // we need to create a new instance of the airlock and assembly to read vars from them
- var/obj/structure/door_assembly/assembly = new airlock.assemblytype
+ var/obj/machinery/door/airlock/airlock = airlock_type // we need to create a new instance of the airlock and assembly to read vars from them
+ var/obj/structure/door_assembly/assembly = initial(airlock.assemblytype)
- if(airlock_material == "glass" && assembly.noglass) // prevents painting glass airlocks with a paint job that doesn't have a glass version, such as the freezer
+ if(airlock_material == "glass" && initial(assembly.noglass)) // prevents painting glass airlocks with a paint job that doesn't have a glass version, such as the freezer
to_chat(user, "This paint job can only be applied to non-glass airlocks.")
- else
- // applies the user-chosen airlock's icon, overlays and assemblytype to the src airlock
- painter.use_paint(user)
- icon = airlock.icon
- overlays_file = airlock.overlays_file
- assemblytype = airlock.assemblytype
- update_icon()
+ return
- // these are just hanging around but are never placed, we need to delete them
- qdel(airlock)
- qdel(assembly)
+ // applies the user-chosen airlock's icon, overlays and assemblytype to the src airlock
+ painter.use_paint(user)
+ icon = initial(airlock.icon)
+ overlays_file = initial(airlock.overlays_file)
+ assemblytype = initial(airlock.assemblytype)
+ update_icon()
/obj/machinery/door/airlock/CanAStarPass(obj/item/card/id/ID)
//Airlock is passable if it is open (!density), bot has access, and is not bolted shut or powered off)
@@ -1565,7 +1562,7 @@
*/
/obj/machinery/door/airlock/proc/set_wires()
var/area/source_area = get_area(src)
- return new source_area.airlock_wires(src)
+ return source_area?.airlock_wires ? new source_area.airlock_wires(src) : new /datum/wires/airlock(src)
#undef AIRLOCK_CLOSED
#undef AIRLOCK_CLOSING
From 94d1dda78da64ce8ed0bbb5b908ce247e2cf3876 Mon Sep 17 00:00:00 2001
From: tgstation-server
Date: Tue, 29 Sep 2020 02:54:36 -0700
Subject: [PATCH 08/13] Automatic changelog generation for PR #53742 [ci skip]
---
html/changelogs/AutoChangeLog-pr-53742.yml | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 html/changelogs/AutoChangeLog-pr-53742.yml
diff --git a/html/changelogs/AutoChangeLog-pr-53742.yml b/html/changelogs/AutoChangeLog-pr-53742.yml
new file mode 100644
index 00000000000..46c4ab728c6
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-53742.yml
@@ -0,0 +1,4 @@
+author: "Timberpoes"
+delete-after: True
+changes:
+ - bugfix: "The Airlock Painter should now paint airlocks in all appropriate scenarios where it failed to do so before."
From 3035fbfc3af1ec7a760d3389dcb4fc949c4b6c1b Mon Sep 17 00:00:00 2001
From: Bobbahbrown
Date: Tue, 29 Sep 2020 07:07:39 -0300
Subject: [PATCH 09/13] SQL Schema Version 5.11 / Add indices for ticket table
to support Statbus operations (#53541)
* I hope you're proud of yourselves. You've driven away another customer! It's baffling, I tell you! Your deep rooted lack of self-control only fosters failure in every endeavor we undertake! I mean, it's always one step forward and two steps back! Why? Don't you see the example I try to set for you?
* thanks jordie
---
SQL/database_changelog.txt | 17 ++++++++++++++---
SQL/tgstation_schema.sql | 6 +++++-
SQL/tgstation_schema_prefixed.sql | 6 +++++-
code/__DEFINES/subsystems.dm | 2 +-
4 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/SQL/database_changelog.txt b/SQL/database_changelog.txt
index 27d6cd3190c..a0b087d9355 100644
--- a/SQL/database_changelog.txt
+++ b/SQL/database_changelog.txt
@@ -1,15 +1,26 @@
Any time you make a change to the schema files, remember to increment the database schema version. Generally increment the minor number, major should be reserved for significant changes to the schema. Both values go up to 255.
-The latest database version is 5.10; The query to update the schema revision table is:
+The latest database version is 5.11; The query to update the schema revision table is:
-INSERT INTO `schema_revision` (`major`, `minor`) VALUES (5, 10);
+INSERT INTO `schema_revision` (`major`, `minor`) VALUES (5, 11);
or
-INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (5, 10);
+INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (5, 11);
In any query remember to add a prefix to the table names if you use one.
-----------------------------------------------------
+Version 5.11, 7 September 2020, by bobbahbrown, MrStonedOne, and Jordie0608
+
+Adds indices to support search operations on the adminhelp ticket tables. This is to support improved performance on Atlanta Ned's Statbus.
+
+CREATE INDEX `idx_ticket_act_recip` (`action`, `recipient`)
+CREATE INDEX `idx_ticket_act_send` (`action`, `sender`)
+CREATE INDEX `idx_ticket_tic_rid` (`ticket`, `round_id`)
+CREATE INDEX `idx_ticket_act_time_rid` (`action`, `timestamp`, `round_id`)
+
+-----------------------------------------------------
+
Version 5.10, 7 August 2020, by oranges
Changes how the discord verification process works.
diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql
index a01787e395b..64f29f98e2e 100644
--- a/SQL/tgstation_schema.sql
+++ b/SQL/tgstation_schema.sql
@@ -547,7 +547,11 @@ CREATE TABLE `ticket` (
`timestamp` datetime NOT NULL,
`recipient` varchar(32) DEFAULT NULL,
`sender` varchar(32) DEFAULT NULL,
- PRIMARY KEY (`id`)
+ PRIMARY KEY (`id`),
+ KEY `idx_ticket_act_recip` (`action`, `recipient`),
+ KEY `idx_ticket_act_send` (`action`, `sender`),
+ KEY `idx_ticket_tic_rid` (`ticket`, `round_id`),
+ KEY `idx_ticket_act_time_rid` (`action`, `timestamp`, `round_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
DELIMITER $$
diff --git a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql
index 03521308c3f..d1f73dd99a0 100644
--- a/SQL/tgstation_schema_prefixed.sql
+++ b/SQL/tgstation_schema_prefixed.sql
@@ -547,7 +547,11 @@ CREATE TABLE `SS13_ticket` (
`timestamp` datetime NOT NULL,
`recipient` varchar(32) DEFAULT NULL,
`sender` varchar(32) DEFAULT NULL,
- PRIMARY KEY (`id`)
+ PRIMARY KEY (`id`),
+ KEY `idx_ticket_act_recip` (`action`, `recipient`),
+ KEY `idx_ticket_act_send` (`action`, `sender`),
+ KEY `idx_ticket_tic_rid` (`ticket`, `round_id`),
+ KEY `idx_ticket_act_time_rid` (`action`, `timestamp`, `round_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
DELIMITER $$
diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index 395169abf0e..d8a1cb313c2 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -20,7 +20,7 @@
*
* make sure you add an update to the schema_version stable in the db changelog
*/
-#define DB_MINOR_VERSION 10
+#define DB_MINOR_VERSION 11
//! ## Timing subsystem
From 16baa2779469e8e7fb668322397d651f6edec65e Mon Sep 17 00:00:00 2001
From: tgstation-server
Date: Tue, 29 Sep 2020 03:07:43 -0700
Subject: [PATCH 10/13] Automatic changelog generation for PR #53541 [ci skip]
---
html/changelogs/AutoChangeLog-pr-53541.yml | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 html/changelogs/AutoChangeLog-pr-53541.yml
diff --git a/html/changelogs/AutoChangeLog-pr-53541.yml b/html/changelogs/AutoChangeLog-pr-53541.yml
new file mode 100644
index 00000000000..3dc7727158a
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-53541.yml
@@ -0,0 +1,4 @@
+author: "bobbahbrown, MrStonedOne, Jordie0608"
+delete-after: True
+changes:
+ - server: "Added indices to improve support of searching through the tickets table, updated schema to 5.11."
From ac29d3603ef196c3acc79da87bca23006d4680e3 Mon Sep 17 00:00:00 2001
From: tgstation-server
Date: Tue, 29 Sep 2020 03:17:10 -0700
Subject: [PATCH 11/13] Automatic changelog generation for PR #54016 [ci skip]
---
html/changelogs/AutoChangeLog-pr-54016.yml | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 html/changelogs/AutoChangeLog-pr-54016.yml
diff --git a/html/changelogs/AutoChangeLog-pr-54016.yml b/html/changelogs/AutoChangeLog-pr-54016.yml
new file mode 100644
index 00000000000..fee16d756c7
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-54016.yml
@@ -0,0 +1,4 @@
+author: "MIC132"
+delete-after: True
+changes:
+ - bugfix: "fixed supermatter shutters on pubby"
From 3cc7733f34c3fe7cb97ab41437fee4a494119127 Mon Sep 17 00:00:00 2001
From: Rohesie
Date: Tue, 29 Sep 2020 07:23:43 -0300
Subject: [PATCH 12/13] Moblity refactor: hands blocked and restrained edition.
(#53981)
Splits the restrained() proc into component traits: TRAIT_HANDS_BLOCKED for the general inability to use hands and TRAIT_RESTRAINED for the more specific condition that permits arrests.
Code moved away from the update_mobility() proc so it doesn't have to wait for an update, instead changing based on events. The idea is to eventually kill that proc.
Wrapper proc added for setting the handcuffed value so we can react to the event of it changing.
Kills the RestrainedClickOn() proc. That is now just an UnarmedAttack(), in where the ability to use hands can be checked. Monkeys keep their bite attack and humans their self-examine.
---
code/__DEFINES/traits.dm | 8 ++
code/_globalvars/traits.dm | 2 +
code/_onclick/ai.dm | 3 -
code/_onclick/click.dm | 13 +--
code/_onclick/cyborg.dm | 6 --
code/_onclick/other_mobs.dm | 87 ++++++++-----------
code/datums/action.dm | 38 ++++----
code/datums/components/riding.dm | 4 +-
code/datums/components/tackle.dm | 2 +-
code/datums/emotes.dm | 15 +---
code/datums/status_effects/debuffs.dm | 4 +
code/game/atoms_movable.dm | 2 +
code/game/machinery/PDApainter.dm | 2 +-
code/game/machinery/doors/door.dm | 2 +-
code/game/machinery/doors/windowdoor.dm | 2 +-
code/game/machinery/pipe/pipe_dispenser.dm | 2 +-
code/game/objects/buckling.dm | 4 +-
code/game/objects/items.dm | 2 +-
code/game/objects/items/handcuffs.dm | 15 ++--
code/game/objects/items/paint.dm | 2 +-
code/game/objects/items/scrolls.dm | 2 +-
code/game/objects/items/storage/secure.dm | 2 +-
code/game/objects/structures.dm | 2 +-
code/game/objects/structures/noticeboard.dm | 4 +-
code/game/objects/structures/spirit_board.dm | 2 +-
.../objects/structures/windoor_assembly.dm | 2 +-
.../antagonists/_common/antag_spawner.dm | 10 +--
.../abductor/equipment/abduction_gear.dm | 2 +-
.../changeling/powers/biodegrade.dm | 2 +-
code/modules/antagonists/cult/blood_magic.dm | 2 +-
code/modules/antagonists/cult/cult_comms.dm | 2 +-
.../eldritch_cult/eldritch_items.dm | 2 +-
.../antagonists/revolution/revolution.dm | 2 +-
.../antagonists/wizard/equipment/spellbook.dm | 8 +-
.../awaymissions/bluespaceartillery.dm | 2 +-
code/modules/clothing/shoes/miscellaneous.dm | 2 +-
.../kitchen_machinery/processor.dm | 2 +-
code/modules/instruments/items.dm | 2 +-
code/modules/library/lib_items.dm | 2 +-
code/modules/mob/emote.dm | 4 +-
.../living/carbon/alien/humanoid/humanoid.dm | 2 -
.../mob/living/carbon/alien/larva/larva.dm | 2 -
code/modules/mob/living/carbon/carbon.dm | 26 ++++--
.../mob/living/carbon/carbon_defense.dm | 8 +-
.../mob/living/carbon/carbon_movement.dm | 4 +-
code/modules/mob/living/carbon/emote.dm | 16 ++--
code/modules/mob/living/carbon/human/emote.dm | 10 +--
.../mob/living/carbon/human/human_defense.dm | 4 -
.../mob/living/carbon/human/human_helpers.dm | 4 -
.../mob/living/carbon/human/inventory.dm | 4 +
.../mob/living/carbon/human/species.dm | 2 +-
code/modules/mob/living/carbon/inventory.dm | 4 +-
.../mob/living/carbon/monkey/combat.dm | 2 +-
code/modules/mob/living/carbon/monkey/life.dm | 2 +-
code/modules/mob/living/emote.dm | 14 +--
code/modules/mob/living/init_signals.dm | 27 ++++++
code/modules/mob/living/living.dm | 51 +++++------
code/modules/mob/living/silicon/ai/ai.dm | 2 -
code/modules/mob/living/silicon/pai/pai.dm | 2 -
.../modules/mob/living/silicon/robot/robot.dm | 2 -
.../mob/living/simple_animal/bot/secbot.dm | 2 +-
.../mob/living/simple_animal/hostile/ooze.dm | 6 +-
.../living/simple_animal/hostile/statue.dm | 5 --
code/modules/mob/living/ventcrawling.dm | 8 +-
code/modules/mob/mob.dm | 18 +---
code/modules/mob/mob_movement.dm | 2 +-
.../computers/item/laptop.dm | 12 +--
code/modules/paperwork/clipboard.dm | 2 +-
code/modules/paperwork/folders.dm | 2 +-
code/modules/power/singularity/emitter.dm | 2 +-
code/modules/projectiles/gun.dm | 2 +-
.../nanites/nanite_programs/utility.dm | 2 +-
.../xenobiology/crossbreeding/prismatic.dm | 2 +-
.../crossbreeding/selfsustaining.dm | 2 +-
.../surgery/bodyparts/dismemberment.dm | 4 +-
code/modules/swarmers/swarmer.dm | 2 +-
code/modules/vehicles/cars/car.dm | 2 +-
code/modules/vehicles/vehicle_actions.dm | 2 +-
78 files changed, 258 insertions(+), 280 deletions(-)
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 24a984c73d4..8ef16dbe482 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -79,6 +79,10 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_KNOCKEDOUT "knockedout" //Forces the user to stay unconscious.
#define TRAIT_IMMOBILIZED "immobilized" //Prevents voluntary movement.
#define TRAIT_FLOORED "floored" //Prevents standing or staying up on its own.
+/// Prevents usage of manipulation appendages (picking, holding or using items, manipulating storage).
+#define TRAIT_HANDS_BLOCKED "handsblocked"
+/// Abstract condition that prevents movement if being pulled and might be resisted against. Handcuffs and straight jackets, basically.
+#define TRAIT_RESTRAINED "restrained"
#define TRAIT_INCAPACITATED "incapacitated"
#define TRAIT_CRITICAL_CONDITION "critical-condition" //In some kind of critical condition. Is able to succumb.
#define TRAIT_BLIND "blind"
@@ -286,6 +290,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define RESTING_TRAIT "resting" //trait associated to resting
#define STAT_TRAIT "stat" //trait associated to a stat value or range of
#define MAPPING_HELPER_TRAIT "mapping-helper" //obtained from mapping helper
+/// Trait associated to wearing a suit
+#define SUIT_TRAIT "suit"
// unique trait sources, still defines
#define CLONING_POD_TRAIT "cloning-pod"
@@ -331,3 +337,5 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define PULLED_WHILE_SOFTCRIT_TRAIT "pulled-while-softcrit"
#define LOCKED_BORG_TRAIT "locked-borg"
#define LACKING_LOCOMOTION_APPENDAGES_TRAIT "lacking-locomotion-appengades" //trait associated to not having locomotion appendages nor the ability to fly or float
+#define LACKING_MANIPULATION_APPENDAGES_TRAIT "lacking-manipulation-appengades" //trait associated to not having fine manipulation appendages such as hands
+#define HANDCUFFED_TRAIT "handcuffed"
diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm
index f196a136317..8d803f1cfbf 100644
--- a/code/_globalvars/traits.dm
+++ b/code/_globalvars/traits.dm
@@ -8,6 +8,8 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_KNOCKEDOUT" = TRAIT_KNOCKEDOUT,
"TRAIT_IMMOBILIZED" = TRAIT_IMMOBILIZED,
"TRAIT_FLOORED" = TRAIT_FLOORED,
+ "TRAIT_HANDS_BLOCKED" = TRAIT_HANDS_BLOCKED,
+ "TRAIT_RESTRAINED" = TRAIT_RESTRAINED,
"TRAIT_INCAPACITATED" = TRAIT_INCAPACITATED,
"TRAIT_CRITICAL_CONDITION" = TRAIT_CRITICAL_CONDITION,
"TRAIT_BLIND" = TRAIT_BLIND,
diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm
index 14733e1881c..3ed75494289 100644
--- a/code/_onclick/ai.dm
+++ b/code/_onclick/ai.dm
@@ -1,9 +1,6 @@
/*
AI ClickOn()
- Note currently ai restrained() returns 0 in all cases,
- therefore restrained code has been removed
-
The AI can double click to move the camera (this was already true but is cleaner),
or double click a mob to track them.
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index 28841f3d5ba..51c8135bd6d 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -109,9 +109,9 @@
if(!modifiers["catcher"] && A.IsObscured())
return
- if(restrained())
+ if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
changeNext_move(CLICK_CD_HANDCUFFED) //Doing shit in cuffs shall be vey slow
- RestrainedClickOn(A)
+ UnarmedAttack(A)
return
if(in_throw_mode)
@@ -273,14 +273,7 @@
*/
/mob/proc/RangedAttack(atom/A, params)
SEND_SIGNAL(src, COMSIG_MOB_ATTACK_RANGED, A, params)
-/**
- * Restrained ClickOn
- *
- * Used when you are handcuffed and click things.
- * Not currently used by anything but could easily be.
- */
-/mob/proc/RestrainedClickOn(atom/A)
- return
+
/**
* Middle click
diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm
index dd10d5d2791..ba02c8dd3b3 100644
--- a/code/_onclick/cyborg.dm
+++ b/code/_onclick/cyborg.dm
@@ -42,12 +42,6 @@
face_atom(A) // change direction to face what you clicked on
- /*
- cyborg restrained() currently does nothing
- if(restrained())
- RestrainedClickOn(A)
- return
- */
if(aicamera.in_camera_mode) //Cyborg picture taking
aicamera.camera_mode_off()
aicamera.captureimage(A, usr)
diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm
index d3e8f3d39ad..35db4a23252 100644
--- a/code/_onclick/other_mobs.dm
+++ b/code/_onclick/other_mobs.dm
@@ -5,6 +5,10 @@
Otherwise pretty standard.
*/
/mob/living/carbon/human/UnarmedAttack(atom/A, proximity)
+ if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
+ if(src == A)
+ check_self_for_injuries()
+ return
if(!has_active_hand()) //can't attack without a hand.
var/obj/item/bodypart/check_arm = get_active_hand()
if(check_arm?.bodypart_disabled)
@@ -75,13 +79,6 @@
return ui_interact(user)
return FALSE
-/*
-/mob/living/carbon/human/RestrainedClickOn(atom/A) ---carbons will handle this
- return
-*/
-
-/mob/living/carbon/RestrainedClickOn(atom/A)
- return
/mob/living/carbon/human/RangedAttack(atom/A, mouseparams)
. = ..()
@@ -103,74 +100,64 @@
/atom/proc/attack_animal(mob/user)
SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_ANIMAL, user)
-/mob/living/RestrainedClickOn(atom/A)
- return
/*
Monkeys
*/
/mob/living/carbon/monkey/UnarmedAttack(atom/A)
+ if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
+ if(a_intent != INTENT_HARM || is_muzzled())
+ return
+ if(!iscarbon(A))
+ return
+ var/mob/living/carbon/victim = A
+ var/obj/item/bodypart/affecting = null
+ if(ishuman(victim))
+ var/mob/living/carbon/human/human_victim = victim
+ affecting = human_victim.get_bodypart(pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
+ var/armor = victim.run_armor_check(affecting, MELEE)
+ if(prob(25))
+ victim.visible_message("[src]'s bite misses [victim]!",
+ "You avoid [src]'s bite!", "You hear jaws snapping shut!", COMBAT_MESSAGE_RANGE, src)
+ to_chat(src, "Your bite misses [victim]!")
+ return
+ victim.apply_damage(rand(1, 3), BRUTE, affecting, armor)
+ victim.visible_message("[name] bites [victim]!",
+ "[name] bites you!", "You hear a chomp!", COMBAT_MESSAGE_RANGE, name)
+ to_chat(name, "You bite [victim]!")
+ if(armor >= 2)
+ return
+ for(var/d in diseases)
+ var/datum/disease/bite_infection = d
+ victim.ForceContractDisease(bite_infection)
+ return
A.attack_paw(src)
+
/atom/proc/attack_paw(mob/user)
if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_PAW, user) & COMPONENT_NO_ATTACK_HAND)
return TRUE
return FALSE
-/*
- Monkey RestrainedClickOn() was apparently the
- one and only use of all of the restrained click code
- (except to stop you from doing things while handcuffed);
- moving it here instead of various hand_p's has simplified
- things considerably
-*/
-/mob/living/carbon/monkey/RestrainedClickOn(atom/A)
- if(..())
- return
- if(a_intent != INTENT_HARM || !ismob(A))
- return
- if(is_muzzled())
- return
- var/mob/living/carbon/ML = A
- if(istype(ML))
- var/dam_zone = pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
- var/obj/item/bodypart/affecting = null
- if(ishuman(ML))
- var/mob/living/carbon/human/H = ML
- affecting = H.get_bodypart(ran_zone(dam_zone))
- var/armor = ML.run_armor_check(affecting, MELEE)
- if(prob(75))
- ML.apply_damage(rand(1,3), BRUTE, affecting, armor)
- ML.visible_message("[name] bites [ML]!", \
- "[name] bites you!", "You hear a chomp!", COMBAT_MESSAGE_RANGE, name)
- to_chat(name, "You bite [ML]!")
- if(armor >= 2)
- return
- for(var/thing in diseases)
- var/datum/disease/D = thing
- ML.ForceContractDisease(D)
- else
- ML.visible_message("[src]'s bite misses [ML]!", \
- "You avoid [src]'s bite!", "You hear jaws snapping shut!", COMBAT_MESSAGE_RANGE, src)
- to_chat(src, "Your bite misses [ML]!")
/*
Aliens
Defaults to same as monkey in most places
*/
/mob/living/carbon/alien/UnarmedAttack(atom/A)
+ if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
+ return
A.attack_alien(src)
/atom/proc/attack_alien(mob/living/carbon/alien/user)
attack_paw(user)
return
-/mob/living/carbon/alien/RestrainedClickOn(atom/A)
- return
// Babby aliens
/mob/living/carbon/alien/larva/UnarmedAttack(atom/A)
A.attack_larva(src)
+
/atom/proc/attack_larva(mob/user)
return
@@ -187,9 +174,6 @@
/atom/proc/attack_slime(mob/user)
return
-/mob/living/simple_animal/slime/RestrainedClickOn(atom/A)
- return
-
/*
Drones
@@ -200,9 +184,6 @@
/atom/proc/attack_drone(mob/living/simple_animal/drone/user)
attack_hand(user) //defaults to attack_hand. Override it when you don't want drones to do same stuff as humans.
-/mob/living/simple_animal/slime/RestrainedClickOn(atom/A)
- return
-
/*
Brain
diff --git a/code/datums/action.dm b/code/datums/action.dm
index 152aac1065c..57e41babc78 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -1,7 +1,7 @@
-#define AB_CHECK_RESTRAINED 1
-#define AB_CHECK_STUN 2
-#define AB_CHECK_LYING 4
-#define AB_CHECK_CONSCIOUS 8
+#define AB_CHECK_HANDS_BLOCKED (1<<0)
+#define AB_CHECK_IMMOBILE (1<<1)
+#define AB_CHECK_LYING (1<<2)
+#define AB_CHECK_CONSCIOUS (1<<3)
/datum/action
var/name = "Generic Action"
@@ -91,27 +91,23 @@
return FALSE
return TRUE
+
/datum/action/proc/IsAvailable()
if(!owner)
return FALSE
- if(check_flags & AB_CHECK_RESTRAINED)
- if(owner.restrained())
- return FALSE
- if(check_flags & AB_CHECK_STUN)
- if(isliving(owner))
- var/mob/living/L = owner
- if(L.IsParalyzed() || L.IsStun())
- return FALSE
- if(check_flags & AB_CHECK_LYING)
- if(isliving(owner))
- var/mob/living/L = owner
- if(!(L.mobility_flags & MOBILITY_STAND))
- return FALSE
- if(check_flags & AB_CHECK_CONSCIOUS)
- if(owner.stat)
+ if((check_flags & AB_CHECK_HANDS_BLOCKED) && HAS_TRAIT(owner, TRAIT_HANDS_BLOCKED))
+ return FALSE
+ if((check_flags & AB_CHECK_IMMOBILE) && HAS_TRAIT(owner, TRAIT_IMMOBILIZED))
+ return FALSE
+ if((check_flags & AB_CHECK_LYING) && isliving(owner))
+ var/mob/living/action_user = owner
+ if(!(action_user.mobility_flags & MOBILITY_STAND))
return FALSE
+ if((check_flags & AB_CHECK_CONSCIOUS) && owner.stat != CONSCIOUS)
+ return FALSE
return TRUE
+
/datum/action/proc/UpdateButtonIcon(status_only = FALSE, force = FALSE)
if(button)
if(!status_only)
@@ -150,7 +146,7 @@
//Presets for item actions
/datum/action/item_action
- check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_LYING|AB_CHECK_CONSCIOUS
+ check_flags = AB_CHECK_HANDS_BLOCKED|AB_CHECK_IMMOBILE|AB_CHECK_LYING|AB_CHECK_CONSCIOUS
button_icon_state = null
// If you want to override the normal icon being the item
// then change this to an icon state
@@ -499,7 +495,7 @@
/datum/action/item_action/agent_box
name = "Deploy Box"
desc = "Find inner peace, here, in the box."
- check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_CONSCIOUS
+ check_flags = AB_CHECK_HANDS_BLOCKED|AB_CHECK_IMMOBILE|AB_CHECK_CONSCIOUS
background_icon_state = "bg_agent"
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "deploy_box"
diff --git a/code/datums/components/riding.dm b/code/datums/components/riding.dm
index d53b456822b..e8944d1b89b 100644
--- a/code/datums/components/riding.dm
+++ b/code/datums/components/riding.dm
@@ -117,9 +117,9 @@
var/atom/movable/AM = parent
var/mob/AMM = AM
var/kick_us_off
- if((ride_check_rider_restrained && M.restrained(TRUE)) || (ride_check_rider_incapacitated && M.incapacitated(TRUE, TRUE)))
+ if((ride_check_rider_restrained && HAS_TRAIT(M, TRAIT_RESTRAINED)) || (ride_check_rider_incapacitated && M.incapacitated(TRUE, TRUE)))
kick_us_off = TRUE
- if(kick_us_off || (istype(AMM) && ((ride_check_ridden_restrained && AMM.restrained(TRUE)) || (ride_check_ridden_incapacitated && AMM.incapacitated(TRUE, TRUE)))))
+ if(kick_us_off || (istype(AMM) && ((ride_check_ridden_restrained && HAS_TRAIT(AMM, TRAIT_RESTRAINED)) || (ride_check_ridden_incapacitated && AMM.incapacitated(TRUE, TRUE)))))
M.visible_message("[M] falls off of [AM]!", \
"You fall off of [AM]!")
AM.unbuckle_mob(M)
diff --git a/code/datums/components/tackle.dm b/code/datums/components/tackle.dm
index 2c3d60d24bb..5f2acde6955 100644
--- a/code/datums/components/tackle.dm
+++ b/code/datums/components/tackle.dm
@@ -81,7 +81,7 @@
to_chat(user, "You're too angry to remember how to tackle!")
return
- if(user.restrained())
+ if(HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
to_chat(user, "You need free use of your hands to tackle!")
return
diff --git a/code/datums/emotes.dm b/code/datums/emotes.dm
index 9d8090913fe..d343ac51f98 100644
--- a/code/datums/emotes.dm
+++ b/code/datums/emotes.dm
@@ -14,7 +14,8 @@
var/message_simple = "" //Message to display if the user is a simple_animal
var/message_param = "" //Message to display if a param was given
var/emote_type = EMOTE_VISIBLE //Whether the emote is visible or audible
- var/restraint_check = FALSE //Checks if the mob is restrained before performing the emote
+ /// Checks if the mob can use its hands before performing the emote.
+ var/hands_use_check = FALSE
var/muzzle_ignore = FALSE //Will only work if the emote is EMOTE_AUDIBLE
var/list/mob_type_allowed_typecache = /mob //Types that are allowed to use that emote
var/list/mob_type_blacklist_typecache //Types that are NOT allowed to use that emote
@@ -139,18 +140,10 @@
if(DEAD)
to_chat(user, "You cannot [key] while dead!")
return FALSE
- if(restraint_check)
- if(isliving(user))
- var/mob/living/L = user
- if(L.IsParalyzed() || L.IsStun())
- if(!intentional)
- return FALSE
- to_chat(user, "You cannot [key] while stunned!")
- return FALSE
- if(restraint_check && user.restrained())
+ if(hands_use_check && HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
if(!intentional)
return FALSE
- to_chat(user, "You cannot [key] while restrained!")
+ to_chat(user, "You cannot use your hands to [key] right now!")
return FALSE
if(isliving(user))
diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm
index 1991bd8bcf2..ded403262ef 100644
--- a/code/datums/status_effects/debuffs.dm
+++ b/code/datums/status_effects/debuffs.dm
@@ -35,10 +35,12 @@
return
ADD_TRAIT(owner, TRAIT_INCAPACITATED, TRAIT_STATUS_EFFECT(id))
ADD_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
+ ADD_TRAIT(owner, TRAIT_HANDS_BLOCKED, TRAIT_STATUS_EFFECT(id))
/datum/status_effect/incapacitating/stun/on_remove()
REMOVE_TRAIT(owner, TRAIT_INCAPACITATED, TRAIT_STATUS_EFFECT(id))
REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
+ REMOVE_TRAIT(owner, TRAIT_HANDS_BLOCKED, TRAIT_STATUS_EFFECT(id))
return ..()
@@ -83,11 +85,13 @@
ADD_TRAIT(owner, TRAIT_INCAPACITATED, TRAIT_STATUS_EFFECT(id))
ADD_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
ADD_TRAIT(owner, TRAIT_FLOORED, TRAIT_STATUS_EFFECT(id))
+ ADD_TRAIT(owner, TRAIT_HANDS_BLOCKED, TRAIT_STATUS_EFFECT(id))
/datum/status_effect/incapacitating/paralyzed/on_remove()
REMOVE_TRAIT(owner, TRAIT_INCAPACITATED, TRAIT_STATUS_EFFECT(id))
REMOVE_TRAIT(owner, TRAIT_IMMOBILIZED, TRAIT_STATUS_EFFECT(id))
REMOVE_TRAIT(owner, TRAIT_FLOORED, TRAIT_STATUS_EFFECT(id))
+ REMOVE_TRAIT(owner, TRAIT_HANDS_BLOCKED, TRAIT_STATUS_EFFECT(id))
return ..()
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index e3681201cb3..f09166b4172 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -1021,11 +1021,13 @@
if(grab_state >= GRAB_NECK)
ADD_TRAIT(pulling, TRAIT_IMMOBILIZED, CHOKEHOLD_TRAIT)
ADD_TRAIT(pulling, TRAIT_FLOORED, CHOKEHOLD_TRAIT)
+ ADD_TRAIT(pulling, TRAIT_HANDS_BLOCKED, CHOKEHOLD_TRAIT)
switch(grab_state) //Current state.
if(GRAB_PASSIVE, GRAB_AGGRESSIVE)
if(. >= GRAB_NECK)
REMOVE_TRAIT(pulling, TRAIT_IMMOBILIZED, CHOKEHOLD_TRAIT)
REMOVE_TRAIT(pulling, TRAIT_FLOORED, CHOKEHOLD_TRAIT)
+ REMOVE_TRAIT(pulling, TRAIT_HANDS_BLOCKED, CHOKEHOLD_TRAIT)
/obj/item/proc/do_pickup_animation(atom/target)
diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm
index 1234d20c55c..70cb4f06596 100644
--- a/code/game/machinery/PDApainter.dm
+++ b/code/game/machinery/PDApainter.dm
@@ -134,7 +134,7 @@
set category = "Object"
set src in oview(1)
- if(usr.stat || usr.restrained())
+ if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(storedpda)
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index fe92c587e52..3293901299c 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -122,7 +122,7 @@
if(world.time - M.last_bumped <= 10)
return //Can bump-open one airlock per second. This is to prevent shock spam.
M.last_bumped = world.time
- if(M.restrained() && !check_access(null))
+ if(HAS_TRAIT(M, TRAIT_HANDS_BLOCKED) && !check_access(null))
return
if(try_safety_unlock(M))
return
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index 013b43be237..a0165290fd7 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -82,7 +82,7 @@
if(!SSticker)
return
var/mob/M = AM
- if(M.restrained() || ((isdrone(M) || iscyborg(M)) && M.stat))
+ if(HAS_TRAIT(M, TRAIT_HANDS_BLOCKED) || ((isdrone(M) || iscyborg(M)) && M.stat != CONSCIOUS))
return
bumpopen(M)
diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm
index 93a0f7869b6..6db4e547242 100644
--- a/code/game/machinery/pipe/pipe_dispenser.dm
+++ b/code/game/machinery/pipe/pipe_dispenser.dm
@@ -35,7 +35,7 @@
if(..())
return 1
var/mob/living/L = usr
- if(!anchored || (istype(L) && !(L.mobility_flags & MOBILITY_UI)) || usr.stat || usr.restrained() || !in_range(loc, usr))
+ if(!anchored || (istype(L) && !(L.mobility_flags & MOBILITY_UI)) || usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || !in_range(loc, usr))
usr << browse(null, "window=pipedispenser")
return 1
usr.set_machine(src)
diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm
index c3c6ac8e274..28d807459a9 100644
--- a/code/game/objects/buckling.dm
+++ b/code/game/objects/buckling.dm
@@ -167,8 +167,8 @@
if(LAZYLEN(buckled_mobs) >= max_buckled_mobs)
return FALSE
- // If the buckle requires restraints, make sure the target is actually restrained while ignoring grab restraint.
- if(buckle_requires_restraints && !target.restrained(TRUE))
+ // If the buckle requires restraints, make sure the target is actually restrained.
+ if(buckle_requires_restraints && !HAS_TRAIT(target, TRAIT_RESTRAINED))
return FALSE
return TRUE
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 05c1f9a114e..7d59ec8b6c3 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -261,7 +261,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
set category = "Object"
set src in oview(1)
- if(!isturf(loc) || usr.stat || usr.restrained())
+ if(!isturf(loc) || usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(isliving(usr))
diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm
index 7eaa638fc14..2ae89187c5e 100644
--- a/code/game/objects/items/handcuffs.dm
+++ b/code/game/objects/items/handcuffs.dm
@@ -9,7 +9,7 @@
if(iscarbon(loc))
var/mob/living/carbon/M = loc
if(M.handcuffed == src)
- M.handcuffed = null
+ M.set_handcuffed(null)
M.update_handcuffed()
if(M.buckled && M.buckled.buckle_requires_restraints)
M.buckled.unbuckle_mob(M)
@@ -91,7 +91,7 @@
cuffs = new type()
cuffs.forceMove(target)
- target.handcuffed = cuffs
+ target.set_handcuffed(cuffs)
target.update_handcuffed()
if(trashtype && !dispense)
@@ -238,11 +238,12 @@
return (BRUTELOSS)
/obj/item/restraints/legcuffs/beartrap/attack_self(mob/user)
- ..()
- if(ishuman(user) && !user.stat && !user.restrained())
- armed = !armed
- update_icon()
- to_chat(user, "[src] is now [armed ? "armed" : "disarmed"]")
+ . = ..()
+ if(!ishuman(user) || user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ return
+ armed = !armed
+ update_icon()
+ to_chat(user, "[src] is now [armed ? "armed" : "disarmed"]")
/obj/item/restraints/legcuffs/beartrap/proc/close_trap()
armed = FALSE
diff --git a/code/game/objects/items/paint.dm b/code/game/objects/items/paint.dm
index 2ef7da91cb9..cd7ae4bf189 100644
--- a/code/game/objects/items/paint.dm
+++ b/code/game/objects/items/paint.dm
@@ -57,7 +57,7 @@
/obj/item/paint/anycolor/attack_self(mob/user)
var/t1 = input(user, "Please select a color:", "[src]", null) in sortList(list( "red", "blue", "green", "yellow", "violet", "black", "white"))
- if ((user.get_active_held_item() != src || user.stat || user.restrained()))
+ if ((user.get_active_held_item() != src || user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)))
return
switch(t1)
if("red")
diff --git a/code/game/objects/items/scrolls.dm b/code/game/objects/items/scrolls.dm
index 408a3332d40..83d0ec2f210 100644
--- a/code/game/objects/items/scrolls.dm
+++ b/code/game/objects/items/scrolls.dm
@@ -31,7 +31,7 @@
/obj/item/teleportation_scroll/Topic(href, href_list)
..()
- if (usr.stat || usr.restrained() || src.loc != usr)
+ if (usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || src.loc != usr)
return
if (!ishuman(usr))
return 1
diff --git a/code/game/objects/items/storage/secure.dm b/code/game/objects/items/storage/secure.dm
index 67b8000bc05..9dfa343ccab 100644
--- a/code/game/objects/items/storage/secure.dm
+++ b/code/game/objects/items/storage/secure.dm
@@ -80,7 +80,7 @@
/obj/item/storage/secure/Topic(href, href_list)
..()
- if ((usr.stat || usr.restrained()) || (get_dist(src, usr) > 1))
+ if (usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED) || (get_dist(src, usr) > 1))
return
if (href_list["type"])
if (href_list["type"] == "E")
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index 96b7e905c63..6011a426d6b 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -82,7 +82,7 @@
user.visible_message("[user] starts climbing onto [src].", \
"You start climbing onto [src]...")
var/adjusted_climb_time = climb_time
- if(user.restrained()) //climbing takes twice as long when restrained.
+ if(HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //climbing takes twice as long without help from the hands.
adjusted_climb_time *= 2
if(isalien(user))
adjusted_climb_time *= 0.25 //aliens are terrifyingly fast
diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm
index 071d1d0392e..7122f417980 100644
--- a/code/game/objects/structures/noticeboard.dm
+++ b/code/game/objects/structures/noticeboard.dm
@@ -58,7 +58,7 @@
..()
usr.set_machine(src)
if(href_list["remove"])
- if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open
+ if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED)) //For when a player is handcuffed while they have the notice window open
return
var/obj/item/I = locate(href_list["remove"]) in contents
if(istype(I) && I.loc == src)
@@ -68,7 +68,7 @@
icon_state = "nboard0[notices]"
if(href_list["write"])
- if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open
+ if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED)) //For when a player is handcuffed while they have the notice window open
return
var/obj/item/P = locate(href_list["write"]) in contents
if(istype(P) && P.loc == src)
diff --git a/code/game/objects/structures/spirit_board.dm b/code/game/objects/structures/spirit_board.dm
index 095c696640e..d3a75cebf67 100644
--- a/code/game/objects/structures/spirit_board.dm
+++ b/code/game/objects/structures/spirit_board.dm
@@ -67,7 +67,7 @@
var/users_in_range = 0
for(var/mob/living/L in orange(1,src))
if(L.ckey && L.client)
- if((world.time - L.client.inactivity) < (world.time - 300) || L.stat != CONSCIOUS || L.restrained())//no playing with braindeads or corpses or handcuffed dudes.
+ if((world.time - L.client.inactivity) < (world.time - 300) || L.stat != CONSCIOUS || HAS_TRAIT(L, TRAIT_HANDS_BLOCKED))//no playing with braindeads or corpses or handcuffed dudes.
to_chat(M, "[L] doesn't seem to be paying attention...")
else
users_in_range++
diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm
index d630d1dcede..a6312838f20 100644
--- a/code/game/objects/structures/windoor_assembly.dm
+++ b/code/game/objects/structures/windoor_assembly.dm
@@ -338,7 +338,7 @@
set name = "Flip Windoor Assembly"
set category = "Object"
set src in oview(1)
- if(usr.stat || usr.restrained())
+ if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(isliving(usr))
diff --git a/code/modules/antagonists/_common/antag_spawner.dm b/code/modules/antagonists/_common/antag_spawner.dm
index 1adb5840915..c9aef9d3775 100644
--- a/code/modules/antagonists/_common/antag_spawner.dm
+++ b/code/modules/antagonists/_common/antag_spawner.dm
@@ -42,13 +42,13 @@
return
/obj/item/antag_spawner/contract/Topic(href, href_list)
- ..()
- var/mob/living/carbon/human/H = usr
+ . = ..()
- if(H.stat || H.restrained())
+ if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
- if(!ishuman(H))
- return 1
+ if(!ishuman(usr))
+ return TRUE
+ var/mob/living/carbon/human/H = usr
if(loc == H || (in_range(src, H) && isturf(loc)))
H.set_machine(src)
diff --git a/code/modules/antagonists/abductor/equipment/abduction_gear.dm b/code/modules/antagonists/abductor/equipment/abduction_gear.dm
index 067962f3b09..4d600d40cc9 100644
--- a/code/modules/antagonists/abductor/equipment/abduction_gear.dm
+++ b/code/modules/antagonists/abductor/equipment/abduction_gear.dm
@@ -592,7 +592,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
"[user] begins shaping an energy field around your hands!")
if(do_mob(user, C, time_to_cuff) && C.canBeHandcuffed())
if(!C.handcuffed)
- C.handcuffed = new /obj/item/restraints/handcuffs/energy/used(C)
+ C.set_handcuffed(new /obj/item/restraints/handcuffs/energy/used(C))
C.update_handcuffed()
to_chat(user, "You restrain [C].")
log_combat(user, C, "handcuffed")
diff --git a/code/modules/antagonists/changeling/powers/biodegrade.dm b/code/modules/antagonists/changeling/powers/biodegrade.dm
index 6e5112d0429..58ed367a4d9 100644
--- a/code/modules/antagonists/changeling/powers/biodegrade.dm
+++ b/code/modules/antagonists/changeling/powers/biodegrade.dm
@@ -9,7 +9,7 @@
/datum/action/changeling/biodegrade/sting_action(mob/living/carbon/human/user)
var/used = FALSE // only one form of shackles removed per use
- if(!user.restrained() && !user.legcuffed && isopenturf(user.loc))
+ if(!HAS_TRAIT(user, TRAIT_RESTRAINED) && !user.legcuffed && isopenturf(user.loc))
to_chat(user, "We are already free!")
return FALSE
diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm
index 11eda3846d7..79587b0e34b 100644
--- a/code/modules/antagonists/cult/blood_magic.dm
+++ b/code/modules/antagonists/cult/blood_magic.dm
@@ -526,7 +526,7 @@
"[user] begins shaping dark magic shackles around your wrists!")
if(do_mob(user, C, 30))
if(!C.handcuffed)
- C.handcuffed = new /obj/item/restraints/handcuffs/energy/cult/used(C)
+ C.set_handcuffed(new /obj/item/restraints/handcuffs/energy/cult/used(C))
C.update_handcuffed()
C.silent += 5
to_chat(user, "You shackle [C].")
diff --git a/code/modules/antagonists/cult/cult_comms.dm b/code/modules/antagonists/cult/cult_comms.dm
index 7310dc225f5..cdf4db9b8fc 100644
--- a/code/modules/antagonists/cult/cult_comms.dm
+++ b/code/modules/antagonists/cult/cult_comms.dm
@@ -4,7 +4,7 @@
icon_icon = 'icons/mob/actions/actions_cult.dmi'
background_icon_state = "bg_demon"
buttontooltipstyle = "cult"
- check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_CONSCIOUS
+ check_flags = AB_CHECK_HANDS_BLOCKED|AB_CHECK_IMMOBILE|AB_CHECK_CONSCIOUS
/datum/action/innate/cult/IsAvailable()
if(!iscultist(owner))
diff --git a/code/modules/antagonists/eldritch_cult/eldritch_items.dm b/code/modules/antagonists/eldritch_cult/eldritch_items.dm
index 5021282ac98..f512f0a3d99 100644
--- a/code/modules/antagonists/eldritch_cult/eldritch_items.dm
+++ b/code/modules/antagonists/eldritch_cult/eldritch_items.dm
@@ -38,7 +38,7 @@
background_icon_state = "bg_ecult"
button_icon_state = "shatter"
icon_icon = 'icons/mob/actions/actions_ecult.dmi'
- check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN
+ check_flags = AB_CHECK_HANDS_BLOCKED|AB_CHECK_IMMOBILE
var/mob/living/carbon/human/holder
var/obj/item/melee/sickly_blade/sword
diff --git a/code/modules/antagonists/revolution/revolution.dm b/code/modules/antagonists/revolution/revolution.dm
index bfdab56924b..f9e56b0530f 100644
--- a/code/modules/antagonists/revolution/revolution.dm
+++ b/code/modules/antagonists/revolution/revolution.dm
@@ -296,7 +296,7 @@
var/list/datum/mind/promotable = list()
var/list/datum/mind/nonhuman_promotable = list()
for(var/datum/mind/khrushchev in non_heads)
- if(khrushchev.current && !khrushchev.current.incapacitated() && !khrushchev.current.restrained() && khrushchev.current.client && khrushchev.current.stat != DEAD)
+ if(khrushchev.current && !khrushchev.current.incapacitated() && !HAS_TRAIT(khrushchev.current, TRAIT_RESTRAINED) && khrushchev.current.client)
if(ROLE_REV in khrushchev.current.client.prefs.be_special)
if(ishuman(khrushchev.current))
promotable += khrushchev
diff --git a/code/modules/antagonists/wizard/equipment/spellbook.dm b/code/modules/antagonists/wizard/equipment/spellbook.dm
index c2dd89325a1..aee416db91b 100644
--- a/code/modules/antagonists/wizard/equipment/spellbook.dm
+++ b/code/modules/antagonists/wizard/equipment/spellbook.dm
@@ -739,13 +739,13 @@
return
/obj/item/spellbook/Topic(href, href_list)
- ..()
- var/mob/living/carbon/human/H = usr
+ . = ..()
- if(H.stat || H.restrained())
+ if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
- if(!ishuman(H))
+ if(!ishuman(usr))
return TRUE
+ var/mob/living/carbon/human/H = usr
if(H.mind.special_role == "apprentice")
temp = "If you got caught sneaking a peek from your teacher's spellbook, you'd likely be expelled from the Wizard Academy. Better not."
diff --git a/code/modules/awaymissions/bluespaceartillery.dm b/code/modules/awaymissions/bluespaceartillery.dm
index 22473fcac7a..9949840923b 100644
--- a/code/modules/awaymissions/bluespaceartillery.dm
+++ b/code/modules/awaymissions/bluespaceartillery.dm
@@ -40,7 +40,7 @@
var/A
A = input("Area to bombard", "Open Fire", A) in GLOB.teleportlocs
var/area/thearea = GLOB.teleportlocs[A]
- if(usr.stat || usr.restrained())
+ if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(reload < reload_cooldown)
return
diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm
index 9999ac31a5d..d6e337e8d1a 100644
--- a/code/modules/clothing/shoes/miscellaneous.dm
+++ b/code/modules/clothing/shoes/miscellaneous.dm
@@ -445,7 +445,7 @@
/obj/item/clothing/shoes/cowboy/MouseDrop_T(mob/living/target, mob/living/user)
. = ..()
- if(user.stat || !(user.mobility_flags & MOBILITY_USE) || user.restrained() || !Adjacent(user) || !user.Adjacent(target) || target.stat == DEAD)
+ if(!(user.mobility_flags & MOBILITY_USE) || user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user) || !user.Adjacent(target) || target.stat == DEAD)
return
if(occupants.len >= max_occupants)
to_chat(user, "[src] are full!")
diff --git a/code/modules/food_and_drinks/kitchen_machinery/processor.dm b/code/modules/food_and_drinks/kitchen_machinery/processor.dm
index bd0cd5a9dfa..eee6eeb3c67 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/processor.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/processor.dm
@@ -131,7 +131,7 @@
set category = "Object"
set name = "Eject Contents"
set src in oview(1)
- if(usr.stat || usr.restrained())
+ if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(isliving(usr))
var/mob/living/L = usr
diff --git a/code/modules/instruments/items.dm b/code/modules/instruments/items.dm
index d44441ae5ca..ba0d2d5cc93 100644
--- a/code/modules/instruments/items.dm
+++ b/code/modules/instruments/items.dm
@@ -40,7 +40,7 @@
ui_interact(user)
/obj/item/instrument/ui_interact(mob/living/user)
- if(!isliving(user) || user.stat || user.restrained())
+ if(!isliving(user) || user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
user.set_machine(src)
diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm
index 6c8dfaae8dc..1f5b30fac4c 100644
--- a/code/modules/library/lib_items.dm
+++ b/code/modules/library/lib_items.dm
@@ -145,7 +145,7 @@
if(contents.len)
var/obj/item/book/choice = input(user, "Which book would you like to remove from the shelf?") as null|obj in sortNames(contents.Copy())
if(choice)
- if(!(user.mobility_flags & MOBILITY_USE) || user.stat || user.restrained() || !in_range(loc, user))
+ if(!(user.mobility_flags & MOBILITY_USE) || user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !in_range(loc, user))
return
if(ishuman(user))
if(!user.get_active_held_item())
diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm
index 8d5835f1f9f..8cc31dd4e66 100644
--- a/code/modules/mob/emote.dm
+++ b/code/modules/mob/emote.dm
@@ -35,7 +35,7 @@
/datum/emote/flip
key = "flip"
key_third_person = "flips"
- restraint_check = TRUE
+ hands_use_check = TRUE
mob_type_allowed_typecache = list(/mob/living, /mob/dead/observer)
mob_type_ignore_stat_typecache = list(/mob/dead/observer)
@@ -69,7 +69,7 @@
/datum/emote/spin
key = "spin"
key_third_person = "spins"
- restraint_check = TRUE
+ hands_use_check = TRUE
mob_type_allowed_typecache = list(/mob/living, /mob/dead/observer)
mob_type_ignore_stat_typecache = list(/mob/dead/observer)
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
index e6fe7f1346a..ba453facb39 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
@@ -31,8 +31,6 @@
. = ..()
AddComponent(/datum/component/footstep, FOOTSTEP_MOB_CLAW, 0.5, -3)
-/mob/living/carbon/alien/humanoid/restrained(ignore_grab)
- return handcuffed
/mob/living/carbon/alien/humanoid/show_inv(mob/user)
user.set_machine(src)
diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm
index 6b4097e6faf..4bb89e4ede1 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva.dm
@@ -59,8 +59,6 @@
/mob/living/carbon/alien/larva/attack_ui(slot_id)
return
-/mob/living/carbon/alien/larva/restrained(ignore_grab)
- . = 0
// new damage icon system
// now constructs damage icon for each organ from mask * damage field
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 73fa2d7bef2..89419e88441 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -173,9 +173,6 @@
newtonian_move(get_dir(target, src))
thrown_thing.safe_throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed + power_throw, src, null, null, null, move_force)
-/mob/living/carbon/restrained(ignore_grab)
- . = (handcuffed || (!ignore_grab && pulledby && pulledby.grab_state >= GRAB_AGGRESSIVE))
-
/mob/living/carbon/proc/canBeHandcuffed()
return FALSE
@@ -269,7 +266,7 @@
return FALSE
/mob/living/carbon/resist_buckle()
- if(restrained())
+ if(HAS_TRAIT(src, TRAIT_RESTRAINED))
changeNext_move(CLICK_CD_BREAKOUT)
last_special = world.time + CLICK_CD_BREAKOUT
var/buckle_cd = 600
@@ -350,7 +347,7 @@
/mob/living/carbon/proc/uncuff()
if (handcuffed)
var/obj/item/W = handcuffed
- handcuffed = null
+ set_handcuffed(null)
if (buckled && buckled.buckle_requires_restraints)
buckled.unbuckle_mob(src)
update_handcuffed()
@@ -394,7 +391,7 @@
else
if(I == handcuffed)
handcuffed.forceMove(drop_location())
- handcuffed = null
+ set_handcuffed(null)
I.dropped(src)
if(buckled && buckled.buckle_requires_restraints)
buckled.unbuckle_mob(src)
@@ -880,7 +877,7 @@
suiciding = FALSE
regenerate_limbs()
regenerate_organs()
- handcuffed = initial(handcuffed)
+ set_handcuffed(null)
for(var/obj/item/restraints/R in contents) //actually remove cuffs from inventory
qdel(R)
update_handcuffed()
@@ -1278,3 +1275,18 @@
return
brain.update_skillchips()
+
+
+/// Modifies the handcuffed value if a different value is passed, returning FALSE otherwise. The variable should only be changed through this proc.
+/mob/living/carbon/proc/set_handcuffed(new_value)
+ if(handcuffed == new_value)
+ return FALSE
+ . = handcuffed
+ handcuffed = new_value
+ if(.)
+ if(!handcuffed)
+ REMOVE_TRAIT(src, TRAIT_RESTRAINED, HANDCUFFED_TRAIT)
+ REMOVE_TRAIT(src, TRAIT_HANDS_BLOCKED, HANDCUFFED_TRAIT)
+ else if(handcuffed)
+ ADD_TRAIT(src, TRAIT_RESTRAINED, HANDCUFFED_TRAIT)
+ ADD_TRAIT(src, TRAIT_HANDS_BLOCKED, HANDCUFFED_TRAIT)
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index 5f0f1e4b3bf..c0068c429df 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -50,9 +50,7 @@
return
if(get_active_held_item())
return
- if(!(mobility_flags & MOBILITY_MOVE))
- return
- if(restrained())
+ if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
return
return TRUE
@@ -431,11 +429,11 @@
null, "You hear the rustling of clothes.", DEFAULT_MESSAGE_RANGE, list(M, src))
to_chat(M, "You shake [src] trying to pick [p_them()] up!")
to_chat(src, "[M] shakes you to get you up!")
-
+
else if(check_zone(M.zone_selected) == BODY_ZONE_HEAD) //Headpats!
M.visible_message("[M] gives [src] a pat on the head to make [p_them()] feel better!", \
"You give [src] a pat on the head to make [p_them()] feel better!")
-
+
else
M.visible_message("[M] hugs [src] to make [p_them()] feel better!", \
null, "You hear the rustling of clothes.", DEFAULT_MESSAGE_RANGE, list(M, src))
diff --git a/code/modules/mob/living/carbon/carbon_movement.dm b/code/modules/mob/living/carbon/carbon_movement.dm
index 18b18009bda..7367995a613 100644
--- a/code/modules/mob/living/carbon/carbon_movement.dm
+++ b/code/modules/mob/living/carbon/carbon_movement.dm
@@ -51,9 +51,11 @@
if(isnull(.))
return
if(. == 0)
+ REMOVE_TRAIT(src, TRAIT_HANDS_BLOCKED, LACKING_MANIPULATION_APPENDAGES_TRAIT)
if(usable_hands != 0) //From having no usable hands to having some.
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, LACKING_LOCOMOTION_APPENDAGES_TRAIT)
- else if(usable_hands == 0) //From having usable hands to no longer having them.
+ else if(usable_hands == 0 && default_num_hands > 0) //From having usable hands to no longer having them.
+ ADD_TRAIT(src, TRAIT_HANDS_BLOCKED, LACKING_MANIPULATION_APPENDAGES_TRAIT)
if(!usable_legs && !(movement_type & (FLYING | FLOATING)))
ADD_TRAIT(src, TRAIT_IMMOBILIZED, LACKING_LOCOMOTION_APPENDAGES_TRAIT)
diff --git a/code/modules/mob/living/carbon/emote.dm b/code/modules/mob/living/carbon/emote.dm
index 464e47a22a6..af8dad2dc8a 100644
--- a/code/modules/mob/living/carbon/emote.dm
+++ b/code/modules/mob/living/carbon/emote.dm
@@ -4,7 +4,7 @@
/datum/emote/living/carbon/airguitar
key = "airguitar"
message = "is strumming the air and headbanging like a safari chimp."
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/carbon/blink
key = "blink"
@@ -20,7 +20,7 @@
key_third_person = "claps"
message = "claps."
muzzle_ignore = TRUE
- restraint_check = TRUE
+ hands_use_check = TRUE
emote_type = EMOTE_AUDIBLE
vary = TRUE
@@ -64,14 +64,14 @@
key_third_person = "rolls"
message = "rolls."
mob_type_allowed_typecache = list(/mob/living/carbon/monkey, /mob/living/carbon/alien)
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/carbon/scratch
key = "scratch"
key_third_person = "scratches"
message = "scratches."
mob_type_allowed_typecache = list(/mob/living/carbon/monkey, /mob/living/carbon/alien)
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/carbon/screech
key = "screech"
@@ -84,7 +84,7 @@
key_third_person = "signs"
message_param = "signs the number %t."
mob_type_allowed_typecache = list(/mob/living/carbon/monkey, /mob/living/carbon/alien)
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/carbon/sign/select_param(mob/user, params)
. = ..()
@@ -96,7 +96,7 @@
key_third_person = "signals"
message_param = "raises %t fingers."
mob_type_allowed_typecache = list(/mob/living/carbon/human)
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/carbon/tail
key = "tail"
@@ -111,7 +111,7 @@
/datum/emote/living/carbon/circle
key = "circle"
key_third_person = "circles"
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/carbon/circle/run_emote(mob/user, params, type_override, intentional)
. = ..()
@@ -125,7 +125,7 @@
/datum/emote/living/carbon/slap
key = "slap"
key_third_person = "slaps"
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/carbon/slap/run_emote(mob/user, params, type_override, intentional)
. = ..()
diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm
index d12f8d0b44b..17fa970f8ab 100644
--- a/code/modules/mob/living/carbon/human/emote.dm
+++ b/code/modules/mob/living/carbon/human/emote.dm
@@ -12,7 +12,7 @@
key_third_person = "daps"
message = "sadly can't find anybody to give daps to, and daps themself. Shameful."
message_param = "give daps to %t."
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/carbon/human/eyebrow
key = "eyebrow"
@@ -28,7 +28,7 @@
key = "handshake"
message = "shakes their own hands."
message_param = "shakes hands with %t."
- restraint_check = TRUE
+ hands_use_check = TRUE
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/hug
@@ -36,7 +36,7 @@
key_third_person = "hugs"
message = "hugs themself."
message_param = "hugs %t."
- restraint_check = TRUE
+ hands_use_check = TRUE
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/mumble
@@ -78,14 +78,14 @@
key = "raise"
key_third_person = "raises"
message = "raises a hand."
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/carbon/human/salute
key = "salute"
key_third_person = "salutes"
message = "salutes."
message_param = "salutes to %t."
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/carbon/human/shrug
key = "shrug"
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 6a85c5e63b6..255af90baa1 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -656,10 +656,6 @@
..()
-/mob/living/carbon/human/RestrainedClickOn(atom/A)
- . = ..()
- if(src == A)
- check_self_for_injuries()
/mob/living/carbon/human/check_self_for_injuries()
if(stat >= UNCONSCIOUS)
diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm
index 62237843e99..eb85fb2e360 100644
--- a/code/modules/mob/living/carbon/human/human_helpers.dm
+++ b/code/modules/mob/living/carbon/human/human_helpers.dm
@@ -1,8 +1,4 @@
-/mob/living/carbon/human/restrained(ignore_grab)
- . = ((wear_suit && wear_suit.breakouttime) || ..())
-
-
/mob/living/carbon/human/canBeHandcuffed()
if(num_hands < 2)
return FALSE
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index 83cc98ceec8..edf9be57b88 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -148,6 +148,8 @@
if(I.flags_inv & HIDEJUMPSUIT)
update_inv_w_uniform()
if(wear_suit.breakouttime) //when equipping a straightjacket
+ ADD_TRAIT(src, TRAIT_RESTRAINED, SUIT_TRAIT)
+ ADD_TRAIT(src, TRAIT_HANDS_BLOCKED, SUIT_TRAIT)
stop_pulling() //can't pull if restrained
update_action_buttons_icon() //certain action buttons will no longer be usable.
update_inv_wear_suit()
@@ -203,6 +205,8 @@
if(s_store && invdrop)
dropItemToGround(s_store, TRUE) //It makes no sense for your suit storage to stay on you if you drop your suit.
if(wear_suit.breakouttime) //when unequipping a straightjacket
+ REMOVE_TRAIT(src, TRAIT_RESTRAINED, SUIT_TRAIT)
+ REMOVE_TRAIT(src, TRAIT_HANDS_BLOCKED, SUIT_TRAIT)
drop_all_held_items() //suit is restraining
update_action_buttons_icon() //certain action buttons may be usable again.
wear_suit = null
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index f2d0cb0f291..bbec8da6f2b 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -1950,7 +1950,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
/datum/action/innate/flight
name = "Toggle Flight"
- check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_STUN
+ check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_IMMOBILE
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "flight"
diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm
index 2248c225816..3b989e72057 100644
--- a/code/modules/mob/living/carbon/inventory.dm
+++ b/code/modules/mob/living/carbon/inventory.dm
@@ -77,7 +77,7 @@
wear_neck = I
update_inv_neck(I)
if(ITEM_SLOT_HANDCUFFED)
- handcuffed = I
+ set_handcuffed(I)
update_handcuffed()
if(ITEM_SLOT_LEGCUFFED)
legcuffed = I
@@ -125,7 +125,7 @@
if(!QDELETED(src))
update_inv_neck(I)
else if(I == handcuffed)
- handcuffed = null
+ set_handcuffed(null)
if(buckled && buckled.buckle_requires_restraints)
buckled.unbuckle_mob(src)
if(!QDELETED(src))
diff --git a/code/modules/mob/living/carbon/monkey/combat.dm b/code/modules/mob/living/carbon/monkey/combat.dm
index cafc5ab2d5a..add4c5e30f2 100644
--- a/code/modules/mob/living/carbon/monkey/combat.dm
+++ b/code/modules/mob/living/carbon/monkey/combat.dm
@@ -129,7 +129,7 @@
/mob/living/carbon/monkey/proc/handle_combat()
if(pickupTarget)
- if(IsDeadOrIncap() || restrained() || blacklistItems[pickupTarget] || HAS_TRAIT(pickupTarget, TRAIT_NODROP))
+ if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED) || IsDeadOrIncap() || blacklistItems[pickupTarget] || HAS_TRAIT(pickupTarget, TRAIT_NODROP))
pickupTarget = null
else
pickupTimer++
diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm
index 6f11b5872e4..f39903603fd 100644
--- a/code/modules/mob/living/carbon/monkey/life.dm
+++ b/code/modules/mob/living/carbon/monkey/life.dm
@@ -11,7 +11,7 @@
if(!client)
if(stat == CONSCIOUS)
- if(on_fire || buckled || restrained())
+ if(on_fire || buckled || HAS_TRAIT(src, TRAIT_RESTRAINED) || (pulledby && pulledby.grab_state > GRAB_PASSIVE))
if(!resisting && prob(MONKEY_RESIST_PROB))
resisting = TRUE
walk_to(src,0)
diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm
index 33cbe505e6e..8d5a223dca8 100644
--- a/code/modules/mob/living/emote.dm
+++ b/code/modules/mob/living/emote.dm
@@ -14,7 +14,7 @@
key_third_person = "bows"
message = "bows."
message_param = "bows to %t."
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/burp
key = "burp"
@@ -32,7 +32,7 @@
key = "cross"
key_third_person = "crosses"
message = "crosses their arms."
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/chuckle
key = "chuckle"
@@ -67,7 +67,7 @@
key = "dance"
key_third_person = "dances"
message = "dances around happily."
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/deathgasp
key = "deathgasp"
@@ -116,7 +116,7 @@
key = "flap"
key_third_person = "flaps"
message = "flaps their wings."
- restraint_check = TRUE
+ hands_use_check = TRUE
var/wing_time = 20
/datum/emote/living/flap/run_emote(mob/user, params, type_override, intentional)
@@ -136,7 +136,7 @@
key = "aflap"
key_third_person = "aflaps"
message = "flaps their wings ANGRILY!"
- restraint_check = TRUE
+ hands_use_check = TRUE
wing_time = 10
/datum/emote/living/frown
@@ -191,7 +191,7 @@
key = "jump"
key_third_person = "jumps"
message = "jumps!"
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/kiss
key = "kiss"
@@ -240,7 +240,7 @@
key_third_person = "points"
message = "points."
message_param = "points at %t."
- restraint_check = TRUE
+ hands_use_check = TRUE
/datum/emote/living/point/run_emote(mob/user, params, type_override, intentional)
message_param = initial(message_param) // reset
diff --git a/code/modules/mob/living/init_signals.dm b/code/modules/mob/living/init_signals.dm
index 6b688df2ec4..dd4c88b3355 100644
--- a/code/modules/mob/living/init_signals.dm
+++ b/code/modules/mob/living/init_signals.dm
@@ -6,6 +6,12 @@
RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_DEATHCOMA), .proc/on_deathcoma_trait_gain)
RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_DEATHCOMA), .proc/on_deathcoma_trait_loss)
+ RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_IMMOBILIZED), .proc/on_immobilized_trait_gain)
+ RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_IMMOBILIZED), .proc/on_immobilized_trait_loss)
+
+ RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_HANDS_BLOCKED), .proc/on_handsblocked_trait_gain)
+ RegisterSignal(src, SIGNAL_REMOVETRAIT(TRAIT_HANDS_BLOCKED), .proc/on_handsblocked_trait_loss)
+
RegisterSignal(src, list(
SIGNAL_ADDTRAIT(TRAIT_CRITICAL_CONDITION),
SIGNAL_REMOVETRAIT(TRAIT_CRITICAL_CONDITION),
@@ -14,6 +20,7 @@
SIGNAL_REMOVETRAIT(TRAIT_NODEATH),
), .proc/update_succumb_action)
+
///Called when TRAIT_KNOCKEDOUT is added to the mob.
/mob/living/proc/on_knockedout_trait_gain(datum/source)
if(stat < UNCONSCIOUS)
@@ -33,6 +40,26 @@
/mob/living/proc/on_deathcoma_trait_loss(datum/source)
REMOVE_TRAIT(src, TRAIT_KNOCKEDOUT, TRAIT_DEATHCOMA)
+
+///Called when TRAIT_IMMOBILIZED is added to the mob.
+/mob/living/proc/on_immobilized_trait_gain(datum/source)
+ mobility_flags &= ~MOBILITY_MOVE
+
+///Called when TRAIT_IMMOBILIZED is removed from the mob.
+/mob/living/proc/on_immobilized_trait_loss(datum/source)
+ mobility_flags |= MOBILITY_MOVE
+
+
+///Called when TRAIT_HANDS_BLOCKED is added to the mob.
+/mob/living/proc/on_handsblocked_trait_gain(datum/source)
+ mobility_flags &= ~(MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_STORAGE)
+ drop_all_held_items()
+
+///Called when TRAIT_HANDS_BLOCKED is removed from the mob.
+/mob/living/proc/on_handsblocked_trait_loss(datum/source)
+ mobility_flags |= (MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_STORAGE)
+
+
/// Called when traits that alter succumbing are added/removed.
/// Will show or hide the succumb alert prompt.
/mob/living/proc/update_succumb_action()
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index e97b7091015..589c510eb14 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -94,7 +94,7 @@
ContactContractDisease(D)
//Should stop you pushing a restrained person out of the way
- if(L.pulledby && L.pulledby != src && L.restrained())
+ if(L.pulledby && L.pulledby != src && HAS_TRAIT(L, TRAIT_RESTRAINED))
if(!(world.time % 5))
to_chat(src, "[L] is restrained, you cannot push past.")
return TRUE
@@ -102,7 +102,7 @@
if(L.pulling)
if(ismob(L.pulling))
var/mob/P = L.pulling
- if(P.restrained())
+ if(HAS_TRAIT(P, TRAIT_RESTRAINED))
if(!(world.time % 5))
to_chat(src, "[L] is restraining [P], you cannot push past.")
return TRUE
@@ -122,8 +122,8 @@
mob_swap = TRUE
else if(
!(HAS_TRAIT(M, TRAIT_NOMOBSWAP) || HAS_TRAIT(src, TRAIT_NOMOBSWAP))&&\
- ((M.restrained() && !too_strong) || M.a_intent == INTENT_HELP) &&\
- (restrained() || a_intent == INTENT_HELP)
+ ((HAS_TRAIT(M, TRAIT_RESTRAINED) && !too_strong) || M.a_intent == INTENT_HELP) &&\
+ (HAS_TRAIT(src, TRAIT_RESTRAINED) || a_intent == INTENT_HELP)
)
mob_swap = TRUE
if(mob_swap)
@@ -385,7 +385,7 @@
death()
/mob/living/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, ignore_stasis = FALSE)
- if(stat || HAS_TRAIT(src, TRAIT_INCAPACITATED) || (!ignore_restraints && restrained(ignore_grab)) || (!ignore_stasis && IS_IN_STASIS(src)))
+ if(stat || HAS_TRAIT(src, TRAIT_INCAPACITATED) || (!ignore_restraints && (HAS_TRAIT(src, TRAIT_RESTRAINED) || (!ignore_grab && pulledby && pulledby.grab_state >= GRAB_AGGRESSIVE))) || (!ignore_stasis && IS_IN_STASIS(src)))
return TRUE
/mob/living/canUseStorage()
@@ -770,7 +770,7 @@
SEND_SIGNAL(src, COMSIG_LIVING_RESIST, src)
//resisting grabs (as if it helps anyone...)
- if(!restrained(ignore_grab = 1) && pulledby)
+ if(!HAS_TRAIT(src, TRAIT_RESTRAINED) && pulledby)
log_combat(src, pulledby, "resisted grab")
resist_grab()
return
@@ -1177,19 +1177,9 @@
return ..() && !(buckled && buckled.buckle_prevents_pull)
-//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
+//Updates lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
//Robots, animals and brains have their own version so don't worry about them
/mob/living/proc/update_mobility()
- var/stat_softcrit = stat == SOFT_CRIT
- var/stat_conscious = (stat == CONSCIOUS) || stat_softcrit
- var/chokehold = pulledby && pulledby.grab_state >= GRAB_NECK
- var/restrained = restrained()
- var/paralyzed = IsParalyzed()
- var/canmove = !HAS_TRAIT(src, TRAIT_IMMOBILIZED)
- if(canmove)
- mobility_flags |= MOBILITY_MOVE
- else
- mobility_flags &= ~MOBILITY_MOVE
var/canstand_involuntary = !HAS_TRAIT(src, TRAIT_FLOORED)
var/canstand = canstand_involuntary && !resting
@@ -1209,18 +1199,11 @@
mobility_flags |= MOBILITY_STAND
set_lying_angle(0)
- if(lying_angle != 0 || restrained || incapacitated())
+ if(lying_angle != 0 || HAS_TRAIT(src, TRAIT_HANDS_BLOCKED) || incapacitated())
mobility_flags &= ~(MOBILITY_UI|MOBILITY_PULL)
else
mobility_flags |= MOBILITY_UI|MOBILITY_PULL
- var/canitem = !paralyzed && !IsStun() && stat_conscious && !chokehold && !restrained && usable_hands
- if(canitem)
- mobility_flags |= (MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_STORAGE)
- else
- mobility_flags &= ~(MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_STORAGE)
- if(!(mobility_flags & MOBILITY_USE))
- drop_all_held_items()
if(!(mobility_flags & MOBILITY_PULL))
if(pulling)
stop_pulling()
@@ -1619,10 +1602,12 @@
if(CONSCIOUS)
if(stat >= UNCONSCIOUS)
ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT)
+ ADD_TRAIT(src, TRAIT_HANDS_BLOCKED, TRAIT_KNOCKEDOUT)
ADD_TRAIT(src, TRAIT_FLOORED, UNCONSCIOUS_TRAIT)
if(SOFT_CRIT)
if(stat >= UNCONSCIOUS)
ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT) //adding trait sources should come before removing to avoid unnecessary updates
+ ADD_TRAIT(src, TRAIT_HANDS_BLOCKED, TRAIT_KNOCKEDOUT)
if(pulledby)
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, PULLED_WHILE_SOFTCRIT_TRAIT)
if(UNCONSCIOUS)
@@ -1635,6 +1620,7 @@
if(CONSCIOUS)
if(. >= UNCONSCIOUS)
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT)
+ REMOVE_TRAIT(src, TRAIT_HANDS_BLOCKED, TRAIT_KNOCKEDOUT)
REMOVE_TRAIT(src, TRAIT_FLOORED, UNCONSCIOUS_TRAIT)
REMOVE_TRAIT(src, TRAIT_CRITICAL_CONDITION, STAT_TRAIT)
if(SOFT_CRIT)
@@ -1642,6 +1628,7 @@
ADD_TRAIT(src, TRAIT_IMMOBILIZED, PULLED_WHILE_SOFTCRIT_TRAIT) //adding trait sources should come before removing to avoid unnecessary updates
if(. >= UNCONSCIOUS)
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT)
+ REMOVE_TRAIT(src, TRAIT_HANDS_BLOCKED, TRAIT_KNOCKEDOUT)
ADD_TRAIT(src, TRAIT_CRITICAL_CONDITION, STAT_TRAIT)
if(UNCONSCIOUS)
if(. != HARD_CRIT)
@@ -1686,6 +1673,20 @@
REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, PULLED_WHILE_SOFTCRIT_TRAIT)
+/// Updates the grab state of the mob and updates movespeed
+/mob/living/setGrabState(newstate)
+ . = ..()
+ switch(grab_state)
+ if(GRAB_PASSIVE)
+ remove_movespeed_modifier(MOVESPEED_ID_MOB_GRAB_STATE)
+ if(GRAB_AGGRESSIVE)
+ add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/aggressive)
+ if(GRAB_NECK)
+ add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/neck)
+ if(GRAB_KILL)
+ add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/kill)
+
+
/// Only defined for carbons who can wear masks and helmets, we just assume other mobs have visible faces
/mob/living/proc/is_face_visible()
return TRUE
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 415a8b4fd6f..5bb745c4704 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -372,8 +372,6 @@
else
mobility_flags = ALL
-/mob/living/silicon/ai/restrained(ignore_grab)
- . = 0
/mob/living/silicon/ai/Topic(href, href_list)
..()
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index 0f20e8455e7..d7b8b0bc1b7 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -200,8 +200,6 @@
else
. += text("Systems nonfunctional")
-/mob/living/silicon/pai/restrained(ignore_grab)
- . = FALSE
// See software.dm for Topic()
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index c34a42a35ef..b240f6a65d7 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -336,8 +336,6 @@
if(connected_ai)
. += "Master AI: [connected_ai.name]"
-/mob/living/silicon/robot/restrained(ignore_grab)
- return
/mob/living/silicon/robot/triggerAlarm(class, area/A, O, obj/alarmsource)
if(alarmsource.z != z)
diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm
index 215721d6e2e..eb8b06ca6f5 100644
--- a/code/modules/mob/living/simple_animal/bot/secbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/secbot.dm
@@ -265,7 +265,7 @@ Auto Patrol: []"},
if( !on || !Adjacent(C) || !isturf(C.loc) ) //if he's in a closet or not adjacent, we cancel cuffing.
return
if(!C.handcuffed)
- C.handcuffed = new /obj/item/restraints/handcuffs/cable/zipties/used(C)
+ C.set_handcuffed(new /obj/item/restraints/handcuffs/cable/zipties/used(C))
C.update_handcuffed()
playsound(src, "law", 50, FALSE)
back_to_idle()
diff --git a/code/modules/mob/living/simple_animal/hostile/ooze.dm b/code/modules/mob/living/simple_animal/hostile/ooze.dm
index a20fb00aae3..cd05aa9917f 100644
--- a/code/modules/mob/living/simple_animal/hostile/ooze.dm
+++ b/code/modules/mob/living/simple_animal/hostile/ooze.dm
@@ -151,7 +151,7 @@
background_icon_state = "bg_hive"
icon_icon = 'icons/mob/actions/actions_slime.dmi'
button_icon_state = "metabolic_boost"
- check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_STUN
+ check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_IMMOBILE
cooldown_time = 24 SECONDS
var/nutrition_cost = 10
var/active = FALSE
@@ -200,7 +200,7 @@
background_icon_state = "bg_hive"
icon_icon = 'icons/mob/actions/actions_slime.dmi'
button_icon_state = "consume"
- check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_STUN
+ check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_IMMOBILE
///The mob thats being consumed by this creature
var/mob/living/vored_mob
@@ -426,7 +426,7 @@
background_icon_state = "bg_hive"
icon_icon = 'icons/mob/actions/actions_slime.dmi'
button_icon_state = "gel_cocoon"
- check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_STUN
+ check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_IMMOBILE
cooldown_time = 10 SECONDS
///Try to put the pulled mob in a cocoon
diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm
index 722ebf0e5ff..70f520ca9b3 100644
--- a/code/modules/mob/living/simple_animal/hostile/statue.dm
+++ b/code/modules/mob/living/simple_animal/hostile/statue.dm
@@ -232,8 +232,3 @@
/mob/living/simple_animal/hostile/statue/sentience_act()
faction -= "neutral"
-
-/mob/living/simple_animal/hostile/statue/restrained(ignore_grab)
- . = ..()
- if(can_be_seen(loc))
- return 1
diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm
index bd861ad9131..2456ce6fe54 100644
--- a/code/modules/mob/living/ventcrawling.dm
+++ b/code/modules/mob/living/ventcrawling.dm
@@ -11,11 +11,11 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list(
if(stat)
to_chat(src, "You must be conscious to do this!")
return
- if(IsStun() || IsParalyzed())
- to_chat(src, "You can't vent crawl while you're stunned!")
+ if(HAS_TRAIT(src, TRAIT_IMMOBILIZED))
+ to_chat(src, "You can't move into the vent!")
return
- if(restrained())
- to_chat(src, "You can't vent crawl while you're restrained!")
+ if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
+ to_chat(src, "You need to be able to use your hands to ventcrawl!")
return
if(has_buckled_mobs())
to_chat(src, "You can't vent crawl with other creatures on you!")
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 0c75bf620ec..c89e25a80b0 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -283,9 +283,6 @@
/mob/proc/get_item_by_slot(slot_id)
return null
-///Is the mob restrained
-/mob/proc/restrained(ignore_grab)
- return
///Is the mob incapacitated
/mob/proc/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, ignore_stasis = FALSE)
@@ -868,7 +865,7 @@
return FALSE
if(notransform)
return FALSE
- if(restrained())
+ if(HAS_TRAIT(src, TRAIT_RESTRAINED))
return FALSE
return TRUE
@@ -1307,19 +1304,6 @@
update_movespeed(FALSE)
-/// Updates the grab state of the mob and updates movespeed
-/mob/setGrabState(newstate)
- . = ..()
- switch(grab_state)
- if(GRAB_PASSIVE)
- remove_movespeed_modifier(MOVESPEED_ID_MOB_GRAB_STATE)
- if(GRAB_AGGRESSIVE)
- add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/aggressive)
- if(GRAB_NECK)
- add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/neck)
- if(GRAB_KILL)
- add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/kill)
-
/mob/proc/update_equipment_speed_mods()
var/speedies = equipped_speed_mods()
if(!speedies)
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 8b66e1ab943..908c253484e 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -163,7 +163,7 @@
if(mob.incapacitated(ignore_restraints = 1))
move_delay = world.time + 10
return TRUE
- else if(mob.restrained(ignore_grab = 1))
+ else if(HAS_TRAIT(mob, TRAIT_RESTRAINED))
move_delay = world.time + 10
to_chat(src, "You're restrained! You can't move!")
return TRUE
diff --git a/code/modules/modular_computers/computers/item/laptop.dm b/code/modules/modular_computers/computers/item/laptop.dm
index a5d2a7ed170..9bf0cd5a3ec 100644
--- a/code/modules/modular_computers/computers/item/laptop.dm
+++ b/code/modules/modular_computers/computers/item/laptop.dm
@@ -64,14 +64,16 @@
. = ..()
if(over_object == usr || over_object == src)
try_toggle_open(usr)
- else if(istype(over_object, /obj/screen/inventory/hand))
+ return
+ if(istype(over_object, /obj/screen/inventory/hand))
var/obj/screen/inventory/hand/H = over_object
var/mob/M = usr
- if(!M.restrained() && !M.stat)
- if(!isturf(loc) || !Adjacent(M))
- return
- M.put_in_hand(src, H.held_index)
+ if(M.stat != CONSCIOUS || HAS_TRAIT(M, TRAIT_HANDS_BLOCKED))
+ return
+ if(!isturf(loc) || !Adjacent(M))
+ return
+ M.put_in_hand(src, H.held_index)
/obj/item/modular_computer/laptop/attack_hand(mob/user)
. = ..()
diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm
index 437d8f676bb..98a92217bbc 100644
--- a/code/modules/paperwork/clipboard.dm
+++ b/code/modules/paperwork/clipboard.dm
@@ -70,7 +70,7 @@
/obj/item/clipboard/Topic(href, href_list)
..()
- if(usr.stat || usr.restrained())
+ if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(usr.contents.Find(src))
diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm
index 305099d1159..633ede44af3 100644
--- a/code/modules/paperwork/folders.dm
+++ b/code/modules/paperwork/folders.dm
@@ -76,7 +76,7 @@
/obj/item/folder/Topic(href, href_list)
..()
- if(usr.stat || usr.restrained())
+ if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED))
return
if(usr.contents.Find(src))
diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm
index 01442f1bf9e..6f8c212ce8c 100644
--- a/code/modules/power/singularity/emitter.dm
+++ b/code/modules/power/singularity/emitter.dm
@@ -413,7 +413,7 @@
auto.Grant(M, src)
/datum/action/innate/protoemitter
- check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUN | AB_CHECK_CONSCIOUS
+ check_flags = AB_CHECK_HANDS_BLOCKED | AB_CHECK_IMMOBILE | AB_CHECK_CONSCIOUS
var/obj/machinery/power/emitter/prototype/PE
var/mob/living/carbon/U
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 46bcbdcd6e2..9757477f9ff 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -655,7 +655,7 @@
/datum/action/toggle_scope_zoom
name = "Toggle Scope"
- check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_LYING
+ check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_HANDS_BLOCKED|AB_CHECK_IMMOBILE|AB_CHECK_LYING
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "sniper_zoom"
var/obj/item/gun/gun = null
diff --git a/code/modules/research/nanites/nanite_programs/utility.dm b/code/modules/research/nanites/nanite_programs/utility.dm
index 48641cc2437..72ca34e6350 100644
--- a/code/modules/research/nanites/nanite_programs/utility.dm
+++ b/code/modules/research/nanites/nanite_programs/utility.dm
@@ -346,7 +346,7 @@
/datum/action/innate/nanite_button
name = "Button"
icon_icon = 'icons/mob/actions/actions_items.dmi'
- check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_CONSCIOUS
+ check_flags = AB_CHECK_HANDS_BLOCKED|AB_CHECK_IMMOBILE|AB_CHECK_CONSCIOUS
button_icon_state = "power_green"
var/datum/nanite_program/dermal_button/program
diff --git a/code/modules/research/xenobiology/crossbreeding/prismatic.dm b/code/modules/research/xenobiology/crossbreeding/prismatic.dm
index 6b4e058c866..9cfc4542d52 100644
--- a/code/modules/research/xenobiology/crossbreeding/prismatic.dm
+++ b/code/modules/research/xenobiology/crossbreeding/prismatic.dm
@@ -116,7 +116,7 @@ Prismatic extracts:
/obj/item/slimecross/prismatic/rainbow/attack_self(mob/user)
var/newcolor = input(user, "Choose the slime color:", "Color change",paintcolor) as color|null
- if ((user.get_active_held_item() != src || user.stat || user.restrained()))
+ if(user.get_active_held_item() != src || user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(!newcolor)
return
diff --git a/code/modules/research/xenobiology/crossbreeding/selfsustaining.dm b/code/modules/research/xenobiology/crossbreeding/selfsustaining.dm
index cdb14b68b6c..3088ddd0fee 100644
--- a/code/modules/research/xenobiology/crossbreeding/selfsustaining.dm
+++ b/code/modules/research/xenobiology/crossbreeding/selfsustaining.dm
@@ -36,7 +36,7 @@ Self-sustaining extracts:
var/amount = 5
var/secondary
- if ((user.get_active_held_item() != src || user.stat || user.restrained()))
+ if (user.get_active_held_item() != src || user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
return
if(!reagentselect)
return
diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm
index adffa8a0ddb..f0172688379 100644
--- a/code/modules/surgery/bodyparts/dismemberment.dm
+++ b/code/modules/surgery/bodyparts/dismemberment.dm
@@ -233,7 +233,7 @@
if(C.handcuffed)
C.handcuffed.forceMove(drop_location())
C.handcuffed.dropped(C)
- C.handcuffed = null
+ C.set_handcuffed(null)
C.update_handcuffed()
if(C.hud_used)
var/obj/screen/inventory/hand/R = C.hud_used.hand_slots["[held_index]"]
@@ -251,7 +251,7 @@
if(C.handcuffed)
C.handcuffed.forceMove(drop_location())
C.handcuffed.dropped(C)
- C.handcuffed = null
+ C.set_handcuffed(null)
C.update_handcuffed()
if(C.hud_used)
var/obj/screen/inventory/hand/L = C.hud_used.hand_slots["[held_index]"]
diff --git a/code/modules/swarmers/swarmer.dm b/code/modules/swarmers/swarmer.dm
index 05d92defe56..133e05968e3 100644
--- a/code/modules/swarmers/swarmer.dm
+++ b/code/modules/swarmers/swarmer.dm
@@ -243,7 +243,7 @@
if(ishuman(target))
var/mob/living/carbon/human/victim = target
if(!victim.handcuffed)
- victim.handcuffed = new /obj/item/restraints/handcuffs/energy/used(victim)
+ victim.set_handcuffed(new /obj/item/restraints/handcuffs/energy/used(victim))
victim.update_handcuffed()
log_combat(src, victim, "handcuffed")
diff --git a/code/modules/vehicles/cars/car.dm b/code/modules/vehicles/cars/car.dm
index d222d1d3e33..860d526a78f 100644
--- a/code/modules/vehicles/cars/car.dm
+++ b/code/modules/vehicles/cars/car.dm
@@ -33,7 +33,7 @@
return TRUE
/obj/vehicle/sealed/car/MouseDrop_T(atom/dropping, mob/M)
- if(M.stat || M.restrained())
+ if(M.stat != CONSCIOUS || HAS_TRAIT(M, TRAIT_HANDS_BLOCKED))
return FALSE
if((car_traits & CAN_KIDNAP) && isliving(dropping) && M != dropping)
var/mob/living/L = dropping
diff --git a/code/modules/vehicles/vehicle_actions.dm b/code/modules/vehicles/vehicle_actions.dm
index 4b3157ac24f..af66d0927b8 100644
--- a/code/modules/vehicles/vehicle_actions.dm
+++ b/code/modules/vehicles/vehicle_actions.dm
@@ -92,7 +92,7 @@
/***************** ACTION DATUMS *****************/
/datum/action/vehicle
- check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUN | AB_CHECK_CONSCIOUS
+ check_flags = AB_CHECK_HANDS_BLOCKED | AB_CHECK_IMMOBILE | AB_CHECK_CONSCIOUS
icon_icon = 'icons/mob/actions/actions_vehicle.dmi'
button_icon_state = "vehicle_eject"
var/obj/vehicle/vehicle_target
From bbf273bd6dc8b6e789f1434a1c88a3e94b33087d Mon Sep 17 00:00:00 2001
From: tgstation-server
Date: Tue, 29 Sep 2020 03:26:00 -0700
Subject: [PATCH 13/13] Automatic changelog generation for PR #53889 [ci skip]
---
html/changelogs/AutoChangeLog-pr-53889.yml | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 html/changelogs/AutoChangeLog-pr-53889.yml
diff --git a/html/changelogs/AutoChangeLog-pr-53889.yml b/html/changelogs/AutoChangeLog-pr-53889.yml
new file mode 100644
index 00000000000..89cd11fab8c
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-53889.yml
@@ -0,0 +1,4 @@
+author: "ATHATH"
+delete-after: True
+changes:
+ - balance: "Morphs no longer have to wait 5 seconds between disguising themselves and undisguising themselves (or vice versa)."