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
   bbcc19c764 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.
This commit is contained in:
Tigercat2000
2015-07-22 05:30:48 -07:00
parent bbcc19c764
commit e9ba7cbca1
2 changed files with 25 additions and 16 deletions

View File

@@ -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)

View File

@@ -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