From 394c7972e158185136910a989077dbcb6bc752b5 Mon Sep 17 00:00:00 2001 From: MrMelbert Date: Sun, 8 Feb 2026 18:31:25 -0600 Subject: [PATCH 1/2] Grab hand gets redder the harder you are grabbing --- code/__DEFINES/living.dm | 9 +++ code/datums/status_effects/debuffs/grabbed.dm | 55 ++++++++++++++++++- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/code/__DEFINES/living.dm b/code/__DEFINES/living.dm index a8e6b86f8de2..0bdc155f3364 100644 --- a/code/__DEFINES/living.dm +++ b/code/__DEFINES/living.dm @@ -42,6 +42,15 @@ #define COMSIG_LIVING_CAN_ALLOW_THROUGH "living_can_allow_through" #define COMPONENT_LIVING_PASSABLE (1<<0) +/// Movable is pinning a mob (source = the mob doing the pinning, mob/living/pinned_mob) +#define COMSIG_MOVABLE_PINNING_MOB "movable_pinning_mob" +/// Movable is unpinning a mob (source = the mob doing the unpinning, mob/living/unpinned_mob) +#define COMSIG_MOVABLE_UNPINNING_MOB "movable_unpinning_mob" +/// Living mob is being pinned by some movable (source = the movable doing the pinning, atom/movable/pinning) +#define COMSIG_LIVING_PINNED_BY "living_pinned_by" +/// Living mob is being unpinned by some movable (source = the movable doing the unpinning, atom/movable/unpinning) +#define COMSIG_LIVING_UNPINNED_BY "living_unpinned_by" + /// Various lists of body zones affected by pain. #define BODY_ZONES_ALL list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) diff --git a/code/datums/status_effects/debuffs/grabbed.dm b/code/datums/status_effects/debuffs/grabbed.dm index 068a5fec1fc2..8208a056bbb3 100644 --- a/code/datums/status_effects/debuffs/grabbed.dm +++ b/code/datums/status_effects/debuffs/grabbed.dm @@ -16,12 +16,55 @@ . = ..() ADD_TRAIT(src, TRAIT_EXAMINE_SKIP, INNATE_TRAIT) +/obj/item/grabbing_hand/equipped(mob/user, slot, initial) + . = ..() + RegisterSignal(user, COMSIG_MOVABLE_SET_GRAB_STATE, PROC_REF(update_state_color), TRUE) + RegisterSignal(user, COMSIG_MOVABLE_PINNING_MOB, PROC_REF(rotate_grab), TRUE) + RegisterSignal(user, COMSIG_MOVABLE_UNPINNING_MOB, PROC_REF(unrotate_grab), TRUE) + +/obj/item/grabbing_hand/dropped(mob/user, silent) + . = ..() + UnregisterSignal(user, list( + COMSIG_MOVABLE_SET_GRAB_STATE, + COMSIG_MOVABLE_PINNING_MOB, + COMSIG_MOVABLE_UNPINNING_MOB, + )) + +/obj/item/grabbing_hand/proc/update_state_color(datum/source, new_state) + SIGNAL_HANDLER + switch(new_state) + if(GRAB_PASSIVE) + color = COLOR_WHITE + if(GRAB_AGGRESSIVE) + color = COLOR_SOFT_RED + if(GRAB_NECK) + color = COLOR_RED + if(GRAB_KILL) + color = COLOR_DARK_RED + +/obj/item/grabbing_hand/proc/rotate_grab(datum/source, mob/living/being_pinned) + SIGNAL_HANDLER + transform = transform.Turn(90) + +/obj/item/grabbing_hand/proc/unrotate_grab(datum/source, mob/living/being_unpinned) + SIGNAL_HANDLER + transform = transform.Turn(-90) + /obj/item/grabbing_hand/on_thrown(mob/living/carbon/user, atom/target) return user.pulling /obj/item/grabbing_hand/attack_self(mob/user, modifiers) return user.start_pulling(user.pulling) +/// Returns what direction we look when we're lying down. +/// If we're not lying down, returns own dir +/mob/living/proc/get_lying_dir() + if(lying_angle == LYING_ANGLE_WEST) + return WEST + if(lying_angle == LYING_ANGLE_EAST) + return EAST + return dir + /// Status effect applied to someone grabbing something /datum/status_effect/grabbing id = "grabbing" @@ -389,6 +432,11 @@ if(owner.buckled || HAS_TRAIT_NOT_FROM(owner, TRAIT_FORCED_STANDING, LINK_SOURCE(id))) to_chat(grabbing_us, span_warning("You fail to pin [owner] to the ground!")) return + if(grabbing_us.loc != owner.loc) + grabbing_us.Move(owner.loc) + if(grabbing_us.loc != owner.loc) + to_chat(grabbing_us, span_warning("You fail to pin [owner] to the ground!")) + return owner.visible_message( span_danger("[grabbing_us] pins [owner] to the ground!"), @@ -408,9 +456,10 @@ ADD_TRAIT(owner, TRAIT_FLOORED, PIN_SOURCE(id)) owner.Paralyze(2 SECONDS) owner.setDir(SOUTH) - grabbing_us.Move(owner.loc) - grabbing_us.setDir(UNLINT(owner.lying_angle) == 270 ? WEST : EAST) // melbert todo + grabbing_us.setDir(owner.get_lying_dir()) // face the same way the person is lying RegisterSignal(grabbing_us, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(start_dragging)) + SEND_SIGNAL(owner, COMSIG_LIVING_PINNED_BY, grabbing_us) + SEND_SIGNAL(grabbing_us, COMSIG_MOVABLE_PINNING_MOB, owner) /datum/status_effect/grabbed/proc/pin_check() return !QDELETED(src) && !QDELETED(grabbing_us) && !pin && grabbing_us.grab_state >= GRAB_AGGRESSIVE @@ -456,6 +505,8 @@ REMOVE_TRAIT(owner, TRAIT_FLOORED, PIN_SOURCE(id)) REMOVE_TRAIT(owner, TRAIT_NO_MOVE_PULL, PIN_SOURCE(id)) UnregisterSignal(grabbing_us, COMSIG_MOVABLE_PRE_MOVE) + SEND_SIGNAL(owner, COMSIG_LIVING_UNPINNED_BY, grabbing_us) + SEND_SIGNAL(grabbing_us, COMSIG_MOVABLE_UNPINNING_MOB, owner) /datum/status_effect/grabbed/proc/update_state(datum/source, new_state) SIGNAL_HANDLER From b84bd0df8876ebe75a633020520aa50e9cfaa867 Mon Sep 17 00:00:00 2001 From: MrMelbert Date: Sun, 8 Feb 2026 18:45:11 -0600 Subject: [PATCH 2/2] Tweaks --- code/datums/status_effects/debuffs/grabbed.dm | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/code/datums/status_effects/debuffs/grabbed.dm b/code/datums/status_effects/debuffs/grabbed.dm index 8208a056bbb3..e52ca414ffe3 100644 --- a/code/datums/status_effects/debuffs/grabbed.dm +++ b/code/datums/status_effects/debuffs/grabbed.dm @@ -18,6 +18,9 @@ /obj/item/grabbing_hand/equipped(mob/user, slot, initial) . = ..() + var/hand = user.get_held_index_of_item(src) + if(IS_RIGHT_INDEX(hand)) + transform = transform.Scale(-1, 1) RegisterSignal(user, COMSIG_MOVABLE_SET_GRAB_STATE, PROC_REF(update_state_color), TRUE) RegisterSignal(user, COMSIG_MOVABLE_PINNING_MOB, PROC_REF(rotate_grab), TRUE) RegisterSignal(user, COMSIG_MOVABLE_UNPINNING_MOB, PROC_REF(unrotate_grab), TRUE) @@ -30,7 +33,7 @@ COMSIG_MOVABLE_UNPINNING_MOB, )) -/obj/item/grabbing_hand/proc/update_state_color(datum/source, new_state) +/obj/item/grabbing_hand/proc/update_state_color(mob/source, new_state) SIGNAL_HANDLER switch(new_state) if(GRAB_PASSIVE) @@ -42,13 +45,15 @@ if(GRAB_KILL) color = COLOR_DARK_RED -/obj/item/grabbing_hand/proc/rotate_grab(datum/source, mob/living/being_pinned) +/obj/item/grabbing_hand/proc/rotate_grab(mob/source, mob/living/being_pinned) SIGNAL_HANDLER - transform = transform.Turn(90) + var/hand = source.get_held_index_of_item(src) + transform = transform.Turn(IS_RIGHT_INDEX(hand) ? -90 : 90) -/obj/item/grabbing_hand/proc/unrotate_grab(datum/source, mob/living/being_unpinned) +/obj/item/grabbing_hand/proc/unrotate_grab(mob/source, mob/living/being_unpinned) SIGNAL_HANDLER - transform = transform.Turn(-90) + var/hand = source.get_held_index_of_item(src) + transform = transform.Turn(IS_RIGHT_INDEX(hand) ? 90 : -90) /obj/item/grabbing_hand/on_thrown(mob/living/carbon/user, atom/target) return user.pulling @@ -432,6 +437,7 @@ if(owner.buckled || HAS_TRAIT_NOT_FROM(owner, TRAIT_FORCED_STANDING, LINK_SOURCE(id))) to_chat(grabbing_us, span_warning("You fail to pin [owner] to the ground!")) return + owner.Knockdown(3 SECONDS) if(grabbing_us.loc != owner.loc) grabbing_us.Move(owner.loc) if(grabbing_us.loc != owner.loc)