diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm
index b7cecf3d7e1..fd5f90460b4 100644
--- a/code/modules/mob/living/carbon/human/human_attackhand.dm
+++ b/code/modules/mob/living/carbon/human/human_attackhand.dm
@@ -72,6 +72,10 @@
if(I_GRAB)
if(M == src || anchored)
return 0
+ for(var/obj/item/weapon/grab/G in src.grabbed_by)
+ if(G.assailant == M)
+ M << "You already grabbed [src]."
+ return
if(w_uniform)
w_uniform.add_fingerprint(M)
diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm
index 39895f22b24..3e020bde232 100644
--- a/code/modules/mob/mob_grab.dm
+++ b/code/modules/mob/mob_grab.dm
@@ -3,6 +3,8 @@
/obj/item/weapon/grab
name = "grab"
+ icon = 'icons/mob/screen1.dmi'
+ icon_state = "reinforce"
flags = NOBLUDGEON
var/obj/screen/grab/hud = null
var/mob/affecting = null
@@ -32,6 +34,7 @@
hud = new /obj/screen/grab(src)
hud.icon_state = "reinforce"
+ icon_state = "grabbed"
hud.name = "reinforce grab"
hud.master = src
@@ -89,11 +92,12 @@
if(G.state >= GRAB_AGGRESSIVE)
allow_upgrade = 0
if(allow_upgrade)
- hud.icon_state = "reinforce"
+ if(state < GRAB_AGGRESSIVE)
+ hud.icon_state = "reinforce"
+ else
+ hud.icon_state = "reinforce1"
else
hud.icon_state = "!reinforce"
- else if(!affecting.buckled)
- affecting.loc = assailant.loc
if(state >= GRAB_NECK)
affecting.Stun(1)
@@ -105,7 +109,51 @@
//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)
+ affecting.losebreath = max(affecting.losebreath + 2, 3)
+
+ adjust_position()
+
+
+/obj/item/weapon/grab/attack_self()
+ return s_click(hud)
+
+
+//Updating pixelshift, position and direction
+//Gets called on process, when the grab gets upgraded or the assailant moves
+/obj/item/weapon/grab/proc/adjust_position()
+ if(affecting.buckled)
+ return
+ var/shift = 0
+ var/adir = get_dir(assailant, affecting)
+ affecting.layer = 4
+ switch(state)
+ if(GRAB_PASSIVE)
+ shift = 6
+ if(GRAB_AGGRESSIVE)
+ shift = 12
+ if(GRAB_NECK, GRAB_UPGRADING)
+ shift = -10
+ adir = assailant.dir
+ affecting.set_dir(assailant.dir)
+ affecting.loc = assailant.loc
+ if(GRAB_KILL)
+ shift = 0
+ adir = 1
+ affecting.set_dir(reverse_dir[assailant.dir])
+ affecting.loc = assailant.loc
+ affecting.lying = 1
+
+ switch(adir)
+ if(NORTH)
+ animate(affecting, pixel_x = 0, pixel_y =-shift, 5, 1, LINEAR_EASING)
+ affecting.layer = 3.9
+ if(SOUTH)
+ animate(affecting, pixel_x = 0, pixel_y = shift, 5, 1, LINEAR_EASING)
+ if(WEST)
+ animate(affecting, pixel_x = shift, pixel_y = 0, 5, 1, LINEAR_EASING)
+ if(EAST)
+ animate(affecting, pixel_x =-shift, pixel_y = 0, 5, 1, LINEAR_EASING)
+
/obj/item/weapon/grab/proc/s_click(obj/screen/S)
@@ -129,6 +177,7 @@
assailant.visible_message("[assailant] has grabbed [affecting] aggressively (now hands)!")
state = GRAB_AGGRESSIVE
icon_state = "grabbed1"
+ hud.icon_state = "reinforce1"
else if(state < GRAB_NECK)
if(isslime(affecting))
assailant << "You squeeze [affecting], but nothing interesting happens."
@@ -137,38 +186,25 @@
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
+ assailant.set_dir(get_dir(assailant, affecting))
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"
+ hud.icon_state = "kill"
+ hud.name = "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)]")
+ hud.icon_state = "kill1"
- 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
+ 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
+ adjust_position()
//This is used to make sure the victim hasn't managed to yackety sax away before using the grab.
@@ -223,5 +259,7 @@
del(src)
/obj/item/weapon/grab/Del()
+ animate(affecting, pixel_x = 0, pixel_y = 0, 4, 1)
+ affecting.layer = 4
del(hud)
..()
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index cc50cfbde1e..c1f0aa5897c 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -343,6 +343,11 @@
else
. = mob.SelfMove(n, direct)
+ for (var/obj/item/weapon/grab/G in mob)
+ if (G.state == GRAB_NECK)
+ mob.set_dir(reverse_dir[direct])
+ G.adjust_position()
+
moving = 0
return .
diff --git a/icons/mob/screen1.dmi b/icons/mob/screen1.dmi
index 4dae20e2e6f..8cf6599edd3 100644
Binary files a/icons/mob/screen1.dmi and b/icons/mob/screen1.dmi differ