Updates grabs

Replaces broken client/Process_Grab(), makes resisting neck grabs
actually work. Fixes the grabbed_by list filling up with null entries
when a grab is broken. Aggressive grabs now prevent movement, can still
be quickly broken using resist or disarm. Neck grabs are easier to
resist if the grabber has moved recently. Some minor cleanup.
This commit is contained in:
mwerezak
2015-02-17 23:40:51 -05:00
parent bee187d5bc
commit 6479c909cd
5 changed files with 83 additions and 93 deletions
@@ -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 <B>[M] has pushed [src]!</B>")
if(armor_check < 2)
visible_message("<span class='danger'>[M] has pushed [src]!</span>")
else
visible_message("<span class='warning'>[M] attempted to push [src]!</span>")
return
var/talked = 0 // BubbleWrap
+13 -16
View File
@@ -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("<span class='warning'>[L] has broken free of [G.assailant]'s grip!</span>")
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("<span class='warning'>[L] has broken free of [G.assailant]'s headlock!</span>")
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 <B>[] resists!</B>", L), 1)
L.visible_message("<span class='danger'>[L] resists!</span>")
//unbuckling yourself
+6 -1
View File
@@ -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
+51 -50
View File
@@ -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("<span class='warning'>[assailant] has grabbed [affecting] aggressively (now hands)!</span>")
state = GRAB_AGGRESSIVE
icon_state = "grabbed1"
else
if(state < GRAB_NECK)
if(isslime(affecting))
assailant << "<span class='notice'>You squeeze [affecting], but nothing interesting happens.</span>"
else if(state < GRAB_NECK)
if(isslime(affecting))
assailant << "<span class='notice'>You squeeze [affecting], but nothing interesting happens.</span>"
return
assailant.visible_message("<span class='warning'>[assailant] has reinforced \his grip on [affecting] (now neck)!</span>")
state = GRAB_NECK
icon_state = "grabbed+1"
if(!affecting.buckled)
affecting.loc = assailant.loc
affecting.attack_log += "\[[time_stamp()]\] <font color='orange'>Has had their neck grabbed by [assailant.name] ([assailant.ckey])</font>"
assailant.attack_log += "\[[time_stamp()]\] <font color='red'>Grabbed the neck of [affecting.name] ([affecting.ckey])</font>"
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("<span class='danger'>[assailant] starts to tighten \his grip on [affecting]'s neck!</span>")
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("<span class='danger'>[assailant] has tightened \his grip on [affecting]'s neck!</span>")
affecting.attack_log += "\[[time_stamp()]\] <font color='orange'>Has been strangled (kill intent) by [assailant.name] ([assailant.ckey])</font>"
assailant.attack_log += "\[[time_stamp()]\] <font color='red'>Strangled (kill intent) [affecting.name] ([affecting.ckey])</font>"
msg_admin_attack("[key_name(assailant)] strangled (kill intent) [key_name(affecting)]")
assailant.visible_message("<span class='warning'>[assailant] has reinforced \his grip on [affecting] (now neck)!</span>")
state = GRAB_NECK
icon_state = "grabbed+1"
if(!affecting.buckled)
affecting.loc = assailant.loc
affecting.attack_log += "\[[time_stamp()]\] <font color='orange'>Has had their neck grabbed by [assailant.name] ([assailant.ckey])</font>"
assailant.attack_log += "\[[time_stamp()]\] <font color='red'>Grabbed the neck of [affecting.name] ([affecting.ckey])</font>"
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("<span class='danger'>[assailant] starts to tighten \his grip on [affecting]'s neck!</span>")
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("<span class='danger'>[assailant] has tightened \his grip on [affecting]'s neck!</span>")
affecting.attack_log += "\[[time_stamp()]\] <font color='orange'>Has been strangled (kill intent) by [assailant.name] ([assailant.ckey])</font>"
assailant.attack_log += "\[[time_stamp()]\] <font color='red'>Strangled (kill intent) [affecting.name] ([affecting.ckey])</font>"
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("<span class='warning'>[assailant] was unable to tighten \his grip on [affecting]'s neck!</span>")
hud.icon_state = "disarm/kill"
state = GRAB_NECK
assailant.visible_message("<span class='warning'>[assailant] was unable to tighten \his grip on [affecting]'s neck!</span>")
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.
+6 -23
View File
@@ -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("<span class='warning'>[mob] lost \his tight grip on [G.affecting]'s neck!</span>")
G.hud.icon_state = "disarm/kill"
G.state = GRAB_NECK
///Process_Incorpmove
///Called by client/Move()