diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm
index bb02aee5e0..8dd2e06067 100644
--- a/code/modules/mob/living/carbon/human/human_attackhand.dm
+++ b/code/modules/mob/living/carbon/human/human_attackhand.dm
@@ -209,7 +209,7 @@
w_uniform.add_fingerprint(M)
var/datum/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
- if (istype(r_hand,/obj/item/weapon/gun) || istype(l_hand,/obj/item/weapon/gun))
+ if(istype(r_hand,/obj/item/weapon/gun) || istype(l_hand,/obj/item/weapon/gun))
var/obj/item/weapon/gun/W = null
var/chance = 0
@@ -231,9 +231,13 @@
var/randn = rand(1, 100)
if(!(species.flags & NO_SLIP) && randn <= 25)
- apply_effect(3, WEAKEN, run_armor_check(affecting, "melee"))
+ var/armor_check = run_armor_check(affecting, "melee")
+ apply_effect(3, WEAKEN, armor_check)
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
- visible_message("\red [M] has pushed [src]!")
+ if(armor_check < 2)
+ visible_message("[M] has pushed [src]!")
+ else
+ visible_message("[M] attempted to push [src]!")
return
var/talked = 0 // BubbleWrap
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 68e9b0f0e8..5d2e1aa504 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -514,7 +514,7 @@
return
//resisting grabs (as if it helps anyone...)
- if ((!( L.stat ) && L.canmove && !( L.restrained() )))
+ if ((!( L.stat ) && !( L.restrained() )))
var/resisting = 0
for(var/obj/O in L.requests)
L.requests.Remove(O)
@@ -522,23 +522,20 @@
resisting++
for(var/obj/item/weapon/grab/G in usr.grabbed_by)
resisting++
- if (G.state == 1)
- del(G)
- else
- if (G.state == 2)
- if (prob(25))
- for(var/mob/O in viewers(L, null))
- O.show_message(text("\red [] has broken free of []'s grip!", L, G.assailant), 1)
+ switch(G.state)
+ if(GRAB_PASSIVE)
+ del(G)
+ if(GRAB_AGGRESSIVE)
+ if(prob(60)) //same chance of breaking the grab as disarm
+ L.visible_message("[L] has broken free of [G.assailant]'s grip!")
+ del(G)
+ if(GRAB_NECK)
+ //If the you move when grabbing someone then it's easier for them to break free. Same if the affected mob is immune to stun.
+ if (((world.time - G.assailant.l_move_time < 20 || !L.stunned) && prob(15)) || prob(3))
+ L.visible_message("[L] has broken free of [G.assailant]'s headlock!")
del(G)
- else
- if (G.state == 3)
- if (prob(5))
- for(var/mob/O in viewers(usr, null))
- O.show_message(text("\red [] has broken free of []'s headlock!", L, G.assailant), 1)
- del(G)
if(resisting)
- for(var/mob/O in viewers(usr, null))
- O.show_message(text("\red [] resists!", L), 1)
+ L.visible_message("[L] resists!")
//unbuckling yourself
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 5a86291dd5..73623ac043 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -868,7 +868,7 @@ note dizziness decrements automatically in the mob's Life() proc.
else if( stat || weakened || paralysis || resting || sleeping || (status_flags & FAKEDEATH))
lying = 1
canmove = 0
- else if( stunned )
+ else if(stunned)
canmove = 0
else if(captured)
anchored = 1
@@ -885,6 +885,11 @@ note dizziness decrements automatically in the mob's Life() proc.
else
density = 1
+ for(var/obj/item/weapon/grab/G in grabbed_by)
+ if(G.state >= GRAB_AGGRESSIVE)
+ canmove = 0
+ break
+
//Temporarily moved here from the various life() procs
//I'm fixing stuff incrementally so this will likely find a better home.
//It just makes sense for now. ~Carn
diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm
index ed11358838..2b47227dfe 100644
--- a/code/modules/mob/mob_grab.dm
+++ b/code/modules/mob/mob_grab.dm
@@ -35,6 +35,10 @@
hud.name = "reinforce grab"
hud.master = src
+/obj/item/weapon/grab/Del()
+ //make sure the grabbed_by list doesn't fill up with nulls
+ if(affecting) affecting.grabbed_by -= src
+ ..()
//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/throw()
@@ -67,6 +71,7 @@
if(state <= GRAB_AGGRESSIVE)
allow_upgrade = 1
+ //disallow upgrading if we're grabbing more than one person
if((assailant.l_hand && assailant.l_hand != src && istype(assailant.l_hand, /obj/item/weapon/grab)))
var/obj/item/weapon/grab/G = assailant.l_hand
if(G.affecting != affecting)
@@ -76,31 +81,29 @@
if(G.affecting != affecting)
allow_upgrade = 0
if(state == GRAB_AGGRESSIVE)
- var/h = affecting.hand
- affecting.hand = 0
- affecting.drop_item()
- affecting.hand = 1
- affecting.drop_item()
- affecting.hand = h
+ affecting.drop_l_hand()
+ affecting.drop_r_hand()
+ //disallow upgrading past aggressive if we're being grabbed aggressively
for(var/obj/item/weapon/grab/G in affecting.grabbed_by)
if(G == src) continue
- if(G.state == GRAB_AGGRESSIVE)
+ if(G.state >= GRAB_AGGRESSIVE)
allow_upgrade = 0
if(allow_upgrade)
hud.icon_state = "reinforce"
else
hud.icon_state = "!reinforce"
- else
- if(!affecting.buckled)
- affecting.loc = assailant.loc
+ else if(!affecting.buckled)
+ affecting.loc = assailant.loc
if(state >= GRAB_NECK)
- affecting.Stun(5) //It will hamper your voice, being choked and all.
+ affecting.Stun(1)
if(isliving(affecting))
var/mob/living/L = affecting
L.adjustOxyLoss(1)
if(state >= GRAB_KILL)
+ //affecting.apply_effect(STUTTER, 5) //would do this, but affecting isn't declared as mob/living for some stupid reason.
+ affecting.stuttering = max(affecting.stuttering, 5) //It will hamper your voice, being choked and all.
affecting.Weaken(5) //Should keep you down unless you get help.
affecting.losebreath = min(affecting.losebreath + 2, 3)
@@ -126,48 +129,46 @@
assailant.visible_message("[assailant] has grabbed [affecting] aggressively (now hands)!")
state = GRAB_AGGRESSIVE
icon_state = "grabbed1"
- else
- if(state < GRAB_NECK)
- if(isslime(affecting))
- assailant << "You squeeze [affecting], but nothing interesting happens."
+ else if(state < GRAB_NECK)
+ if(isslime(affecting))
+ assailant << "You squeeze [affecting], but nothing interesting happens."
+ return
+
+ assailant.visible_message("[assailant] has reinforced \his grip on [affecting] (now neck)!")
+ state = GRAB_NECK
+ icon_state = "grabbed+1"
+ if(!affecting.buckled)
+ affecting.loc = assailant.loc
+ affecting.attack_log += "\[[time_stamp()]\] Has had their neck grabbed by [assailant.name] ([assailant.ckey])"
+ assailant.attack_log += "\[[time_stamp()]\] Grabbed the neck of [affecting.name] ([affecting.ckey])"
+ msg_admin_attack("[key_name(assailant)] grabbed the neck of [key_name(affecting)]")
+ hud.icon_state = "disarm/kill"
+ hud.name = "disarm/kill"
+ else if(state < GRAB_UPGRADING)
+ assailant.visible_message("[assailant] starts to tighten \his grip on [affecting]'s neck!")
+ hud.icon_state = "disarm/kill1"
+ state = GRAB_UPGRADING
+ if(do_after(assailant, UPGRADE_KILL_TIMER))
+ if(state == GRAB_KILL)
return
+ if(!affecting)
+ del(src)
+ return
+ if(!assailant.canmove || assailant.lying)
+ del(src)
+ return
+ state = GRAB_KILL
+ assailant.visible_message("[assailant] has tightened \his grip on [affecting]'s neck!")
+ affecting.attack_log += "\[[time_stamp()]\] Has been strangled (kill intent) by [assailant.name] ([assailant.ckey])"
+ assailant.attack_log += "\[[time_stamp()]\] Strangled (kill intent) [affecting.name] ([affecting.ckey])"
+ msg_admin_attack("[key_name(assailant)] strangled (kill intent) [key_name(affecting)]")
- assailant.visible_message("[assailant] has reinforced \his grip on [affecting] (now neck)!")
- state = GRAB_NECK
- icon_state = "grabbed+1"
- if(!affecting.buckled)
- affecting.loc = assailant.loc
- affecting.attack_log += "\[[time_stamp()]\] Has had their neck grabbed by [assailant.name] ([assailant.ckey])"
- assailant.attack_log += "\[[time_stamp()]\] Grabbed the neck of [affecting.name] ([affecting.ckey])"
- msg_admin_attack("[key_name(assailant)] grabbed the neck of [key_name(affecting)]")
- hud.icon_state = "disarm/kill"
- hud.name = "disarm/kill"
+ assailant.next_move = world.time + 10
+ affecting.losebreath += 1
else
- if(state < GRAB_UPGRADING)
- assailant.visible_message("[assailant] starts to tighten \his grip on [affecting]'s neck!")
- hud.icon_state = "disarm/kill1"
- state = GRAB_UPGRADING
- if(do_after(assailant, UPGRADE_KILL_TIMER))
- if(state == GRAB_KILL)
- return
- if(!affecting)
- del(src)
- return
- if(!assailant.canmove || assailant.lying)
- del(src)
- return
- state = GRAB_KILL
- assailant.visible_message("[assailant] has tightened \his grip on [affecting]'s neck!")
- affecting.attack_log += "\[[time_stamp()]\] Has been strangled (kill intent) by [assailant.name] ([assailant.ckey])"
- assailant.attack_log += "\[[time_stamp()]\] Strangled (kill intent) [affecting.name] ([affecting.ckey])"
- msg_admin_attack("[key_name(assailant)] strangled (kill intent) [key_name(affecting)]")
-
- assailant.next_move = world.time + 10
- affecting.losebreath += 1
- else
- assailant.visible_message("[assailant] was unable to tighten \his grip on [affecting]'s neck!")
- hud.icon_state = "disarm/kill"
- state = GRAB_NECK
+ assailant.visible_message("[assailant] was unable to tighten \his grip on [affecting]'s neck!")
+ hud.icon_state = "disarm/kill"
+ state = GRAB_NECK
//This is used to make sure the victim hasn't managed to yackety sax away before using the grab.
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 84f74cacae..ad499e51e5 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -351,30 +351,13 @@
///Process_Grab()
///Called by client/Move()
-///Checks to see if you are being grabbed and if so attemps to break it
+///Checks to see if you are grabbing anything and if moving will affect your grab.
/client/proc/Process_Grab()
- if(locate(/obj/item/weapon/grab, locate(/obj/item/weapon/grab, mob.grabbed_by.len)))
- var/list/grabbing = list()
- if(istype(mob.l_hand, /obj/item/weapon/grab))
- var/obj/item/weapon/grab/G = mob.l_hand
- grabbing += G.affecting
- if(istype(mob.r_hand, /obj/item/weapon/grab))
- var/obj/item/weapon/grab/G = mob.r_hand
- grabbing += G.affecting
- for(var/obj/item/weapon/grab/G in mob.grabbed_by)
- if((G.state == 1)&&(!grabbing.Find(G.assailant))) del(G)
- if(G.state == 2)
- move_delay = world.time + 10
- if(!prob(25)) return 1
- mob.visible_message("\red [mob] has broken free of [G.assailant]'s grip!")
- del(G)
- if(G.state == 3)
- move_delay = world.time + 10
- if(!prob(5)) return 1
- mob.visible_message("\red [mob] has broken free of [G.assailant]'s headlock!")
- del(G)
- return 0
-
+ for(var/obj/item/weapon/grab/G in list(mob.l_hand, mob.r_hand))
+ if(G.state == GRAB_KILL) //no wandering across the station/asteroid while choking someone
+ mob.visible_message("[mob] lost \his tight grip on [G.affecting]'s neck!")
+ G.hud.icon_state = "disarm/kill"
+ G.state = GRAB_NECK
///Process_Incorpmove
///Called by client/Move()