diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 5a641a81689..932c1e021b2 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -517,57 +517,39 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
/mob/living/carbon/throw_item(atom/target)
throw_mode_off()
- if(stat || !target)
+ if(!target || !isturf(loc))
return
- if(target.type == /obj/screen)
+ if(istype(target, /obj/screen))
return
- var/atom/movable/item = get_active_hand()
+ var/atom/movable/thrown_thing
+ var/obj/item/I = src.get_active_hand()
- if(!item || (item.flags & NODROP))
+ if(!I || (I.flags & NODROP))
return
- if (istype(item, /obj/item/weapon/grab))
- var/obj/item/weapon/grab/G = item
- item = G.get_mob_if_throwable() //throw the person instead of the grab
- if(ismob(item))
+ if(istype(I, /obj/item/weapon/grab))
+ var/obj/item/weapon/grab/G = I
+ var/mob/throwable_mob = G.get_mob_if_throwable() //throw the person instead of the grab
+ qdel(G) //We delete the grab.
+ if(throwable_mob)
+ thrown_thing = throwable_mob
var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors
var/turf/end_T = get_turf(target)
if(start_T && end_T)
- var/mob/M = item
var/start_T_descriptor = "tile at [start_T.x], [start_T.y], [start_T.z] in area [get_area(start_T)]"
var/end_T_descriptor = "tile at [end_T.x], [end_T.y], [end_T.z] in area [get_area(end_T)]"
- M.attack_log += text("\[[time_stamp()]\] Has been thrown by [key_name(src)] from [start_T_descriptor] with the target [end_T_descriptor]")
- attack_log += text("\[[time_stamp()]\] Has thrown [key_name(M)] from [start_T_descriptor] with the target [end_T_descriptor]")
- msg_admin_attack("[key_name_admin(src)] has thrown [key_name_admin(M)] from [start_T_descriptor] with the target [end_T_descriptor]")
+ add_logs(throwable_mob, src, "thrown", addition="from [start_T_descriptor] with the target [end_T_descriptor]")
- if(!iscarbon(src))
- M.LAssailant = null
- else
- M.LAssailant = src
-
- if(!item)
- return //Grab processing has a chance of returning null
- if(!ismob(item)) //Honk mobs don't have a dropped() proc honk
- unEquip(item)
- update_icons()
-
- if (istype(src, /mob/living/carbon)) //Check if a carbon mob is throwing. Modify/remove this line as required.
- item.loc = loc
- if(client)
- client.screen -= item
- if(istype(item, /obj/item))
- item:dropped(src) // let it know it's been dropped
-
- //actually throw it!
- if (item)
- item.layer = initial(item.layer)
- visible_message("\red [src] has thrown [item].")
+ else if(!(I.flags & ABSTRACT)) //can't throw abstract items
+ thrown_thing = I
+ unEquip(I)
+ if(thrown_thing)
+ visible_message("[src] has thrown [thrown_thing].")
newtonian_move(get_dir(target, src))
-
- item.throw_at(target, item.throw_range, item.throw_speed, src)
+ thrown_thing.throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed, src)
/*
/mob/living/carbon/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
..()
diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm
index 98437a53ffd..fee4897f375 100644
--- a/code/modules/mob/mob_grab.dm
+++ b/code/modules/mob/mob_grab.dm
@@ -93,13 +93,15 @@
hud.screen_loc = ui_rhand
else
hud.screen_loc = ui_lhand
-
+ assailant.client.screen += hud
/obj/item/weapon/grab/process()
- if(!confirm()) return //If the confirm fails, the grab is about to be deleted. That means it shouldn't continue processing.
+ 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
+ if(!hud)
+ return //this somehow can runtime under the right circumstances
assailant.client.screen -= hud
assailant.client.screen += hud
@@ -136,12 +138,8 @@
hud.icon_state = "!reinforce"
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_r_hand()
+ affecting.drop_l_hand()
//var/announce = 0
@@ -440,7 +438,13 @@
affecting.pixel_y = 0 //used to be an animate, not quick enough for del'ing
affecting.layer = initial(affecting.layer)
affecting.grabbed_by -= src
+ affecting = null
+ if(assailant)
+ if(assailant.client)
+ assailant.client.screen -= hud
+ assailant = null
qdel(hud)
+ hud = null
return ..()
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index f9023a97dd3..8d57d115ebe 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -304,26 +304,38 @@
///Called by client/Move()
///Checks to see if you are being grabbed and if so attemps to break it
/client/proc/Process_Grab()
- if(locate(/obj/item/weapon/grab, locate(/obj/item/weapon/grab, mob.grabbed_by.len)))
+ if(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))) qdel(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!")
- qdel(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!")
- qdel(G)
+
+ for(var/X in mob.grabbed_by)
+ var/obj/item/weapon/grab/G = X
+ switch(G.state)
+
+ if(GRAB_PASSIVE)
+ if(!grabbing.Find(G.assailant)) //moving always breaks a passive grab unless we are also grabbing our grabber.
+ qdel(G)
+
+ if(GRAB_AGGRESSIVE)
+ move_delay = world.time + 10
+ if(!prob(25))
+ return 1
+ mob.visible_message("[mob] has broken free of [G.assailant]'s grip!")
+ qdel(G)
+
+ if(GRAB_NECK)
+ move_delay = world.time + 10
+ if(!prob(5))
+ return 1
+ mob.visible_message("[mob] has broken free of [G.assailant]'s headlock!")
+ qdel(G)
return 0
diff --git a/icons/mob/screen_gen.dmi b/icons/mob/screen_gen.dmi
index 4936936afde..c3843c0c967 100644
Binary files a/icons/mob/screen_gen.dmi and b/icons/mob/screen_gen.dmi differ