diff --git a/code/__defines/dcs/signals.dm b/code/__defines/dcs/signals.dm index 920139b9ab8..bdcf31f7b48 100644 --- a/code/__defines/dcs/signals.dm +++ b/code/__defines/dcs/signals.dm @@ -55,6 +55,7 @@ #define COMSIG_MOB_EXAMINATE "mob_examinate" #define COMSIG_MOB_FACEDIR "mob_facedir" #define COMSIG_MOB_POINT "mob_point" +#define COMSIG_MOB_ZONE_SEL_CHANGE "mob_zone_sel_change" ///from base of /mob/Login(): () #define COMSIG_MOB_LOGIN "mob_login" ///from base of /mob/Logout(): () diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index f3469748a8b..593cff50d8b 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -262,6 +262,7 @@ if(choice != selecting) selecting = choice update_icon() + SEND_SIGNAL(user, COMSIG_MOB_ZONE_SEL_CHANGE, user) /obj/screen/zone_sel/update_icon() cut_overlays() diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 65306588bc8..4e8ee1fc016 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -318,6 +318,9 @@ var/const/enterloopsanity = 100 return can_have_cabling() /turf/attackby(obj/item/C, mob/user) + if(istype(C, /obj/item/grab)) + var/obj/item/grab/grab = C + step(grab.affecting, get_dir(grab.affecting, src)) if (can_lay_cable() && C.iscoil()) var/obj/item/stack/cable_coil/coil = C coil.turf_place(src, user) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index b801debc110..420a7273d52 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -768,10 +768,11 @@ default behaviour is: if(prob(resist_chance)) visible_message(resist_msg) qdel(G) + break if(resisting) visible_message(SPAN_WARNING("[src] resists!")) - setClickCooldown(25) + setClickCooldown(2.5 SECONDS) /mob/living/verb/lay_down() set name = "Rest" diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index f68e05824f5..15d0625acbd 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -864,7 +864,7 @@ else lying = MOB_IS_INCAPACITATED(INCAPACITATION_KNOCKDOWN) lying_is_intentional = FALSE - canmove = !MOB_IS_INCAPACITATED(INCAPACITATION_KNOCKOUT) + canmove = !MOB_IS_INCAPACITATED(INCAPACITATION_KNOCKOUT) && !weakened if(lying) density = 0 diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 00bb1a63051..09875754b61 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -57,7 +57,6 @@ var/computer_id = null var/character_id = 0 var/obj/machinery/machine = null - var/other_mobs = null var/height = HEIGHT_NOT_USED var/sdisabilities = 0 //Carbon var/disabilities = 0 //Carbon diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index bca31281ccf..40411ab6059 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -10,17 +10,6 @@ return 1 -///Process_Grab() -///Called by client/Move() -///Checks to see if you are grabbing or being grabbed by anything and if moving will affect your grab. -/client/proc/Process_Grab() - if(isliving(mob)) //if we are being grabbed - var/mob/living/L = mob - if(!L.canmove && L.grabbed_by.len) - L.resist() //shortcut for resisting grabs - for(var/obj/item/grab/G in list(mob.l_hand, mob.r_hand)) - G.reset_kill_state() //no wandering across the station/asteroid while choking someone - /obj/item/grab name = "grab" icon = 'icons/mob/screen/generic.dmi' @@ -177,6 +166,11 @@ adjust_position() +/obj/item/grab/proc/handle_eye_mouth_covering_wrapper() + SIGNAL_HANDLER + + INVOKE_ASYNC(src, PROC_REF(handle_eye_mouth_covering), affecting, assailant, assailant.zone_sel.selecting) + /obj/item/grab/proc/handle_eye_mouth_covering(mob/living/carbon/target, mob/user, var/target_zone) var/announce = (target_zone != last_hit_zone) //only display messages when switching between different target zones last_hit_zone = target_zone @@ -288,6 +282,8 @@ state = GRAB_AGGRESSIVE icon_state = "grabbed1" hud.icon_state = "reinforce1" + RegisterSignal(assailant, COMSIG_MOB_ZONE_SEL_CHANGE, PROC_REF(handle_eye_mouth_covering_wrapper)) + handle_eye_mouth_covering(affecting, assailant, assailant.zone_sel.selecting) else if(state < GRAB_NECK) if(isslime(affecting)) assailant.visible_message(SPAN_WARNING("[assailant] tries to squeeze [affecting], but [assailant.get_pronoun("his")] hands sink right through!"), SPAN_WARNING("You try to squeeze [affecting], but your hands sink right through!")) @@ -354,8 +350,7 @@ last_action = world.time reset_kill_state() //using special grab moves will interrupt choking them - //clicking on the victim while grabbing them - if(M == affecting) + if(M == affecting) //clicking on the victim while grabbing them if(ishuman(affecting)) var/hit_zone = target_zone flick(hud.icon_state, hud) @@ -385,7 +380,7 @@ hair_pull(affecting, assailant) //clicking on yourself while grabbing them - if(M == assailant && assailant.a_intent == I_GRAB && state >= GRAB_AGGRESSIVE) + else if(M == assailant && assailant.a_intent == I_GRAB && state >= GRAB_AGGRESSIVE) devour(affecting, assailant) /obj/item/grab/dropped() @@ -407,6 +402,8 @@ if(!QDELETED(linked_grab)) qdel(linked_grab) + UnregisterSignal(assailant, COMSIG_MOB_ZONE_SEL_CHANGE) + if(wielded) if(affecting.buckled_to == assailant) affecting.buckled_to = null diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 17d99a8d202..b3d94647f0e 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -3,8 +3,12 @@ if(ismob(mover)) var/mob/moving_mob = mover - if ((other_mobs && moving_mob.other_mobs)) - return 1 + if(moving_mob.pulledby == src) + return TRUE + if(length(moving_mob.grabbed_by)) + for(var/obj/item/grab/G in moving_mob.grabbed_by) + if(G.assailant == src) + return TRUE return (!mover.density || !density || lying) else return (!mover.density || !density || lying) @@ -238,9 +242,16 @@ console.jump_on_click(mob,T) return - // Only meaningful for living mobs. - if(Process_Grab()) - return + if(length(mob.grabbed_by)) + var/turf/target_turf = get_step(mob, direct) + for(var/obj/item/grab/G in mob.grabbed_by) + // can't move, try resisting and stop movement + if(G.state > GRAB_PASSIVE || get_dist(G.assailant, target_turf) > 1) + L.resist() + return + + for(var/obj/item/grab/G in list(mob.l_hand, mob.r_hand)) + G.reset_kill_state() //no wandering across the station/asteroid while choking someone if(!mob.canmove || mob.paralysis) return diff --git a/html/changelogs/geeves-grab_stuff.yml b/html/changelogs/geeves-grab_stuff.yml new file mode 100644 index 00000000000..149fe33d715 --- /dev/null +++ b/html/changelogs/geeves-grab_stuff.yml @@ -0,0 +1,11 @@ +author: Geeves + +delete-after: True + +changes: + - tweak: "Tweaked movement code's interaction with grabs. You can no longer walk out of grabs." + - tweak: "You can now only break out of one grab at a time." + - rscadd: "When you have someone grabbed, clicking on a tile will now move them there." + - rscadd: "You can now pass through people that are pulling or grabbing you." + - rscadd: "You will now instantly cover someone's eyes or mouth upon going to an aggressive grab, or changing your selected attack zone." + - tweak: "You can no longer crawl around if you get weakened, such as by a disarm shove or certain other stunning effects." \ No newline at end of file