From e9ba7cbca1bc79bb4d2bf6b273b20fde71d75f4b Mon Sep 17 00:00:00 2001 From: Tigercat2000 Date: Wed, 22 Jul 2015 05:30:48 -0700 Subject: [PATCH] Fix a number of grab bugs and odd behaviour still around. This commit fixes a number of bugs with mob grabbing code. Primary things fixed: - Aliens grabbing people will no longer break horribly, they call grabbedby like everything else now. - Any nulls that do manage to find their way into a grab list will be cleaned up by the next grab on that person. - Fixed a number of odd behaviours when grabbing xenomorphs, see bbcc19c764cd for more details. - Fixed grabs having a tendency to shift someone's pixel_xy and not reset it when being deleted. This was simply because it previously relied on del() to stop all procs instantly. --- .../living/carbon/human/human_attackalien.dm | 15 +---------- code/modules/mob/mob_grab.dm | 26 +++++++++++++++++-- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/code/modules/mob/living/carbon/human/human_attackalien.dm b/code/modules/mob/living/carbon/human/human_attackalien.dm index b28daa3683a..c09901e8dcb 100644 --- a/code/modules/mob/living/carbon/human/human_attackalien.dm +++ b/code/modules/mob/living/carbon/human/human_attackalien.dm @@ -7,20 +7,7 @@ if ("help") visible_message(text("\blue [M] caresses [src] with its scythe like arm.")) if ("grab") - if(M == src || anchored) - return - if (w_uniform) - w_uniform.add_fingerprint(M) - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src) - - M.put_in_active_hand(G) - - grabbed_by += G - G.synch() - LAssailant = M - - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - visible_message(text("\red [] has grabbed [] passively!", M, src)) + grabbedby(M) if("harm") M.do_attack_animation(src) diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index a49656dbe59..4257d29b1fb 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -27,8 +27,13 @@ w_class = 5.0 -/obj/item/weapon/grab/New(mob/user, mob/victim) +/obj/item/weapon/grab/New(var/mob/user, var/mob/victim) ..() + + //Okay, first off, some fucking sanity checking. No user, or no victim, or they are not mobs, no grab. + if(!istype(user) || !istype(victim)) + return + loc = user assailant = user affecting = victim @@ -52,8 +57,25 @@ G.dancing = 1 G.adjust_position() dancing = 1 + + clean_grabbed_by(assailant, affecting) adjust_position() +/obj/item/weapon/grab/proc/clean_grabbed_by(var/mob/user, var/mob/victim) //Cleans up any nulls in the grabbed_by list. + if(istype(user)) + + for(var/entry in user.grabbed_by) + if(isnull(entry) || !istype(entry, /obj/item/weapon/grab)) //the isnull() here is probably redundant- but it might outperform istype, who knows. Better safe than sorry. + user.grabbed_by -= entry + + if(istype(victim)) + + for(var/entry in victim.grabbed_by) + if(isnull(entry) || !istype(entry, /obj/item/weapon/grab)) + victim.grabbed_by -= entry + + return 1 + //Used by throw code to hand over the mob, instead of throwing the grab. The grab is then deleted by the throw code. /obj/item/weapon/grab/proc/get_mob_if_throwable() if(affecting && assailant.Adjacent(affecting)) @@ -73,7 +95,7 @@ /obj/item/weapon/grab/process() - confirm() + if(!confirm()) return //If the confirm fails, the grab is about to be deleted. That means it shouldn't continue processing. if(assailant.client) if(!hud) return //this somehow can runtime under the right circumstances